Freshness¶
Freshness helps show whether a view has updated recently enough.
This is useful when plotsrv is observing a process that should publish on a schedule, such as:
- an hourly import
- a daily report
- a repeated validation job
- a long-running monitor
- a batch process with expected checkpoints
Freshness is not about whether a view exists. It is about whether the view is recent.
Enable freshness¶
Freshness is configured in plotsrv.yaml.
This means:
| Setting | Meaning |
|---|---|
expected_every |
how often the view is expected to update |
warn_after |
when the view should be considered stale |
overdue_after |
when the view should be considered overdue |
Source-aware freshness¶
Freshness is source-aware.
Global freshness settings apply to normal Python publishes, such as publish_view() and @view outputs.
Watched-file views are different. A watched file may be static for a long time and still be valid, so global freshness does not mark watched-file views stale by default.
To apply freshness to a watched file, add an explicit per-view freshness entry:
freshness-settings:
enabled: true
expected_every: 1h
warn_after: 90m
overdue_after: 2h
views:
"files:job log":
enabled: true
expected_every: 5m
warn_after: 10m
overdue_after: 30m
With this pattern:
- normal Python views use the global freshness settings
- watched-file views ignore global freshness unless they have a matching entry in
freshness-settings.views - a per-view entry can also set
enabled: falseto opt a normal view out
What appears in the UI¶
When freshness is enabled, plotsrv can show whether a view is:
| State | Meaning |
|---|---|
| Fresh | the view has updated recently |
| Stale | the view has not updated within the warning threshold |
| Overdue | the view has not updated within the overdue threshold |
| Unknown | plotsrv does not yet have enough information |
| Disabled | freshness is not enabled for the view |
This makes plotsrv useful as a lightweight status surface for repeated jobs.
A simple example¶
Given a script like this:
import plotsrv as ps
ps.publish_view(
{
"job": "daily-import",
"status": "ok",
"rows_processed": 123,
},
label="daily import",
section="pipelines",
host="127.0.0.1",
port=8000,
)
Create a config:
Enable freshness:
Start plotsrv:
Run the script:
The view now has freshness information in the UI.
Populate freshness config¶
For projects with several views, use the populate command:
This scans for:
@ps.view(...)decorators- simple
publish_view(...)calls
and adds per-view freshness entries where possible.
For example:
import plotsrv as ps
@ps.view(label="daily import", section="pipelines")
def daily_import_status():
return {"status": "ok"}
@ps.view(label="validation summary", section="pipelines")
def validation_summary():
return {"warnings": 2}
Run:
plotsrv can discover the views and create config entries for them.
Merge generated entries¶
To merge generated freshness entries into an existing config:
To replace generated freshness entries:
To skip prompts:
A common pattern is:
Then edit the generated timings.
Per-view freshness¶
Different views may update on different schedules.
For example:
| View | Expected update pattern |
|---|---|
pipelines:daily import |
every hour |
pipelines:nightly report |
once per night |
models:latest metrics |
after each training run |
logs:etl log |
frequently while the job is running |
Per-view freshness settings allow these expectations to differ.
For example, an hourly view might use:
A nightly view might use:
Freshness with restored views¶
When storage is enabled, plotsrv can restore the latest live view after restart.
Freshness still uses the original update time.
That means a restored view from yesterday does not look fresh just because the server restarted today.
This is important for scheduled jobs, because restart recovery should not hide stale data.