Skip to content

Polling and triggers

Last updated View as MarkdownAgent index

This reference describes the schedules configured in the repository. It does not establish that a deployed schedule is healthy. Source observations, completed assets, published revisions, and delivered alerts are separate checkpoints.

Trigger ownership

Work Owner and trigger Persistent checkpoint
Live MRMS discovery data, cron */2 * * * * (every two minutes, UTC) D1 source cursors and source assets
Configured historical benchmarks data, the same cron; incomplete registry entries are reconsidered D1 backfill state and event-scoped assets
MRMS processing Ingestion queue consumer D1 asset outcome, R2 raw object and rendered frame, revision products
Revision notification Revision queue consumer; outbox dispatch follows ingestion and scheduled discovery D1 outbox, then the event room's last notice
Operational artifact cleanup data, the scheduled invocation at 04:00 UTC R2 object deletion; no archive-completeness checkpoint
NWS warning evaluation hail-alerts, cron */2 * * * * Application-local Durable Object state and delivery ledger
Place search A client request, with response caching No scheduled source ingestion

Wrangler owns these triggers and queue consumer settings. Terraform owns the backing resources. The application owners are Data and Hail Alerts. Their source contracts are listed in Datasets and source contracts.

Storm Forecast ingestion, county/work-area ingestion, Storm Report generation, and customer archive maintenance do not yet have configured schedules. Their product requirements must not be interpreted as running jobs.

Live MRMS discovery

The current poller reads MESH_00.50 and MergedReflectivityAtLowestAltitude_00.50 from https://noaa-mrms-pds.s3.amazonaws.com. These are the configured products; adding a source requires an explicit contract and implementation change.

Bound Implemented behavior
Date scope Current UTC date; also the previous date during the first ten minutes after midnight
Listing One S3 listing per product/date, at most 1,000 keys and 768 KiB of listing data; no continuation-page loop
Selection At most the newest 12 eligible objects in each product/date listing
Cursor Per-product last_source_key, supplied as start-after when it belongs to that date prefix
Input .grib2.gz objects, with compressed input bounded to 16 MiB
Identity Source, object key, and source version derived from last-modified time, size, and ETag

The cursor advances after enqueueing the selected objects. A large backlog can therefore leave older objects unprocessed. An overwrite or late object behind the cursor is not automatically rediscovered. Source-version identity prevents some duplicate processing; it does not provide a complete correction scan.

A discovery failure prevents that invocation's subsequent outbox dispatch and cleanup. Benchmark discovery runs alongside live discovery; a benchmark failure is logged separately and does not by itself stop live discovery. The MRMS fetch paths bound response sizes but do not configure an explicit request-abort timer.

Queue and publication contract

Queue Concurrency Maximum batch / wait Retries / delay Dead-letter queue
stormtrust-data-ingestion 1 4 messages / 5 seconds 5 / 30 seconds stormtrust-data-ingestion-dlq
stormtrust-data-revisions 4 20 messages / 2 seconds 5 / 10 seconds stormtrust-data-revisions-dlq

Ingestion messages use schema version 2. Processing failures record the asset failure and request queue retry. Already completed assets are skipped. Invalid message shapes are logged and acknowledged, so they do not reach a dead-letter queue through repeated failure.

A completed asset is not yet a complete revision. Publication requires both configured products for the two-minute observation window. The revision and manifest identify the evidence; the notification only tells a consumer that a revision is available. See Live revisions and historical evaluation.

Revision messages use schema version 1. The outbox dispatches up to 50 pending entries per invocation, ordered by creation time. An ingestion-side dispatch failure leaves pending work for a later dispatch. The event room retains its last notice and suppresses older sequences. Consumers reconcile through the read API after reconnecting; the WebSocket is not a complete history log.

Neither queue has a repository-configured automatic dead-letter drain. Invalid messages and exhausted retries require an operator to inspect the failed stage, identity, and persisted output before authorizing recovery.

Historical acquisition and recovery bounds

The benchmark registry is checked on each data cron. A registry entry marked complete is skipped. The internal backfill interface supports windows of at most 12 hours whose end is at least five minutes in the past; it is an internal acquisition interface, not a customer replay operation. Use Inspect a local benchmark for the supported local procedure.

Historical discovery inspects one listing page per product/date and filters by observation time. It does not paginate the complete bucket history. A backfill marked complete means its registered assets completed; it does not prove the expected upstream object count was discovered. Completed backfills do not continuously check for upstream corrections.

Rediscovered assets in discovered or failed state can be enqueued. Assets left in queued or processing do not have a separate automatic recovery scan. A benchmark backfill uses its own event identity; it does not repair the live feed's cursor or guarantee that missing live frames become available.

Persistence and cleanup

D1 stores discovery, processing, revision, and outbox metadata. R2 stores source objects, images, and manifests. Event rooms retain notification state. These stores have different lifecycles.

At 04:00 UTC, cleanup removes operational raw objects older than 72 hours and operational frames older than 30 days, measured from R2 upload time. Frames referenced by the current manifest are retained. Cleanup requires the current manifest; without it, the routine deletes nothing. Benchmark event prefixes are outside this operational cleanup scope.

A missed or failed cleanup has no separate catch-up timer. The next matching scheduled invocation is the next configured cleanup opportunity. Cleanup deletes R2 objects without pruning all D1 revision records or historical manifests, so an old revision listing can reference an expired image. Report retention pins and a complete customer archive are future requirements in the History and Replay contract.

NWS evaluation and delivery

Hail Alerts evaluates the configured Missouri severe-thunderstorm-warning feed for its Kansas City market. It persists application-local state in the kc-mo-hail-alerts-v1 coordinator. This is not a shared warning archive for all Storm Intelligence capabilities.

Condition Implemented behavior
Active feed Conditional request with ETag; HTTP 304 updates fetch metadata without replacing warnings
Request bounds 12-second timeout, 8 MiB response limit, at most 1,000 features
Missing warning geometry At most 20 allowed NWS zone URLs may supply fallback geometry
HTTP 429 or 5xx Error retains Retry-After text when supplied; no dedicated retry timer honors that value
Poll failure Error is persisted; a later scheduled or manual poll retries. The scheduled promise can resolve after an error was recorded
UI state read Reads stored state without polling NWS
Manual poll Evaluates the source without automatically sending email
Acceptance replay Fetches a rolling recent window with a 500-result limit and no pagination; uses a labeled fixture when needed

Scheduled live evaluation may deliver pending alerts only when delivery mode, allow-list, and cap checks permit it. The default shadow mode does not establish real delivery. Replay never automatically sends email. The application's acceptance replay can reset its local replay state; it is separate from the proposed customer Storm Replay capability, which reads retained evidence without rerunning acquisition or delivery.

Operational evidence and next action

GET /v1/data/status returns the latest discovered asset per product, including benchmark assets. Its statuses describe processing, not freshness or complete live coverage. An empty product list means no matching asset was found. A successful HTTP response or cron invocation does not establish healthy data.

Observation Evidence needed before recovery
No recent source discovery Scheduled invocation outcome, queried prefix, cursor, source response, and last discovery time
Queued, processing, or failed asset Exact source/version and event identity, queue attempts or dead-letter record, D1 state, and any existing R2 output
Missing revision Required product outcomes for the observation window and revision publication state
Missed live notice Published revision, outbox state, event-room sequence, and a fresh API reconciliation
Missing historical image R2 object availability and applicable retention scope; do not assume a listed revision guarantees retained bytes
NWS or delivery failure Coordinator error, last successful fetch, qualifying warning revision, delivery mode, and delivery ledger

An operator records the affected identity, timestamps, diagnostic evidence, and intended recovery scope before a retry or backfill. Recovery is complete only when new evidence establishes the expected output. Repeating a poll must not be presented as proof that skipped history or expired artifacts were restored.

Source-specific freshness thresholds, escalation recipients, and automated stale-data alerts are not configured by this reference. Before relying on a capability operationally, its owner must define the accepted data age, expected scope, observation/check frequency, failure action, and retained recovery evidence.

Implementation references

Repository paths are the authority for the configured behavior:

  • org/apps/data/wrangler.json: cron and queue configuration.
  • org/apps/data/worker/index.ts: scheduled work, status response, and cleanup gate.
  • org/apps/data/worker/discovery.ts and backfill.ts: listing, cursors, acquisition bounds, and benchmark selection.
  • org/apps/data/worker/ingestion.ts, revisions.ts, and event-room.ts: retries, publication, outbox, and notifications.
  • org/apps/data/worker/mrms.ts: artifact persistence and cleanup.
  • org/apps/hail-alerts/wrangler.jsonc and worker/index.ts: NWS schedule and entry points.
  • org/apps/hail-alerts/worker/nws.ts and coordinator.ts: fetch bounds, stored state, replay, and delivery decisions.