Skip to main content

Keyed timers — detect the silence

Intermediate ⏱ 15 min streaming · process · timers

You will build: a watchdog that fires when a device goes quiet — per-key timeout timers that turn absence of events into an event.

heartbeats → streaming:watchdog (process + timer) → (silence alerts out)

Prerequisites

  • Comfortable with Windows & aggregations. Windows aggregate what arrives — this tutorial is about what doesn't.

1 · Scaffold

pulse new fleetwatch --source webhook --stage streaming:watchdog

2 · Declare the keyed timer

stages:
- name: watchdog
engine: streaming
operators:
- type: process
key: device_id
timeout: "10m"
timer: processing # processing · event
onTimeout: emit # emit · drop
passThrough: true

Each device_id gets its own timer. Every event from that device resets it; if timeout elapses with no event, the operator emits a timeout event for that key. passThrough: true keeps normal heartbeats flowing downstream too.

3 · Deploy and heartbeat two devices

pulse secret set PULSE_WEBHOOK_SECRET dev-secret # the scaffolded webhook source requires it
pulse deploy .
pulse events publish --topic fleetwatch.in --value '{"device_id":"d-1","battery":88}'
pulse events publish --topic fleetwatch.in --value '{"device_id":"d-2","battery":91}'

4 · Watch one go silent

pulse events tail --topic fleetwatch.watchdog.out

Keep d-1 heartbeating; stop sending for d-2. When d-2's timer expires, a timeout event for that key only appears — d-1's timer, still being reset, never fires.

tip

For a quick demo, drop the timeout to "30s" — the semantics are identical.

5 · Chain the alert

Add a rule-based stage after the watchdog to route timeout events to your on-call flow — or an mcp stage to open the ticket directly (see Acting with MCP tools).

What just happened

You used the process operator — a keyed process function with per-key state and timeout timers. Windows answer "what happened per key in this period"; process answers "what should have happened and didn't". Together they cover both halves of monitoring: activity and silence.

Troubleshooting

The timeout never fires

With timer: processing the clock is wall-time from the last event for that key — confirm you actually stopped sending for it. timeout must be positive, and onTimeout: emit (not drop) is what makes the silence visible downstream.

Next