You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today's metrics for dispatch include counters (actor_messages_delivered_total) and per-handler latency histogram (actor_message_handler_seconds). What's missing:
Mailbox depth distribution: most actors have mailbox depth 0-1; some have spikes to 1000+. A histogram reveals the tail.
Dispatcher saturation: ratio of "time the dispatcher was processing" vs "time available". 100% = no idle headroom; OOM/latency risk imminent.
Both are critical production-debugging signals. Without them, "the system is slow" diagnosis goes through pinning mailbox-by-mailbox.
Design sketch
// src/metrics/Metrics.ts — new metric families// Per-actor mailbox depth (sampled per dispatch)'actor_mailbox_depth'(histogram,label: 'actor.path')// Dispatcher saturation (per-node, per-dispatcher)'dispatcher_saturation_ratio'(gauge,label: 'dispatcher')// Time spent waiting in mailbox before handler started'actor_mailbox_wait_seconds'(histogram)
Hooks in ActorCell._dispatchOne:
// At dispatch start:constqueueEntryTs=env.enqueuedAt;metrics.histogram('actor_mailbox_wait_seconds',{},{...}).observe((performance.now()-queueEntryTs)/1000);metrics.histogram('actor_mailbox_depth',{'actor.path': bucketize(this.path)},{...}).observe(this.mailbox.size);// Dispatcher saturation: track in the per-dispatcher event loop wrapper:// busyTime / (busyTime + idleTime) sampled every N seconds.
Integration
Envelope: extend with enqueuedAt: number (filled at tell time).
Sampling frequency: every dispatch (sketch) vs every Nth. Recommend every dispatch — cheap with the existing histogram.
Saturation measurement: requires event-loop instrumentation. Node has perf_hooks.monitorEventLoopDelay; Bun has similar; Deno different. Cross-runtime adapter.
Cardinality: actor.path can explode (every entity has its own path). Bucketize to actor-class-name + parent-path; document.
Test plan
Stress test → mailbox-depth histogram p99 reflects build-up.
Size / Priority
Rationale
Today's metrics for dispatch include counters (
actor_messages_delivered_total) and per-handler latency histogram (actor_message_handler_seconds). What's missing:Both are critical production-debugging signals. Without them, "the system is slow" diagnosis goes through pinning mailbox-by-mailbox.
Design sketch
Hooks in
ActorCell._dispatchOne:Integration
Envelope: extend withenqueuedAt: number(filled attelltime).ActorCell: existing instrumentation extended.Metrics.registry: respect [Security] Prometheus cardinality attack via user-controlled label values #131's cardinality cap (actor.path label → bucketize).Out of scope / non-goals
Open design questions
perf_hooks.monitorEventLoopDelay; Bun has similar; Deno different. Cross-runtime adapter.Test plan
Acceptance criteria
actor_mailbox_depth+actor_mailbox_wait_secondshistograms.dispatcher_saturation_ratiogauge.