Skip to content

Fix #319: record event runtime for events acked via stream.take()#701

Open
wbarnha wants to merge 1 commit into
masterfrom
claude/fix-319-take-runtime-metric
Open

Fix #319: record event runtime for events acked via stream.take()#701
wbarnha wants to merge 1 commit into
masterfrom
claude/fix-319-take-runtime-metric

Conversation

@wbarnha

@wbarnha wbarnha commented Jul 19, 2026

Copy link
Copy Markdown
Member

What

When an agent consumes a stream with stream.take(max_, within=...), the event runtime metric (events_runtime, surfaced e.g. as Prometheus events_runtime_ms_sum) stayed at zero.

Fixes #319.

Why

take() disables acking (enable_acks = False) and acks its buffered events manually in its finally, long after the main iteration loop yielded them. The main loop only calls on_stream_event_out when do_ack is set, so for the take() path the out-event is delivered by Stream.ack() instead.

But Stream.ack() called on_stream_event_out(tp, offset, self, event) without the sensor state. Monitor.on_stream_event_out needs that state (which carries time_in) to compute time_total; with state=None it does nothing, so no runtime was ever recorded for taken events.

How

  • SensorDelegate.on_stream_event_in now stashes the per-sensor state dict on the event itself (event.sensor_state). Both the Python (_py_aiter) and Cython (_cython/streams) iterators call this same delegate method, so the state is captured regardless of which iterator runs — no .pyx recompile needed.
  • Stream.ack() reads event.sensor_state, forwards it to on_stream_event_out, then clears it so a second ack can't double-count.
  • Event / EventT gain a sensor_state attribute (initialised to None, added to EventT.__slots__).

The normal (acks-enabled) path is unchanged: the main loop still fires on_stream_event_out with its local state and never routes through Stream.ack().

Test

Added test_take__records_event_runtime in tests/functional/test_streams.py: attaches a Monitor, sends a value, consumes one buffered batch via take(), and asserts monitor.events_runtime is non-empty. Verified it fails on master (assert deque([])) and passes with the fix, under both the Cython and NO_CYTHON stream iterators. Updated the Stream.ack unit test for the new forwarded/cleared sensor_state argument.

🤖 Generated with Claude Code


Generated by Claude Code

Stream.take() disables acks and acks its buffered events manually after
the main iteration loop has already yielded.  The main loop only calls
on_stream_event_out when do_ack is set, so for take() the out-event was
delivered by Stream.ack() -- but without the sensor state returned by
on_stream_event_in.  on_stream_event_out needs that state to compute the
runtime, so events_runtime was never populated and metrics such as
events_runtime_ms_sum stayed at zero.

Capture the per-sensor state on the event in SensorDelegate.on_stream_event_in
(covers both the Python and Cython stream iterators, which share that
delegate) and forward it from Stream.ack(), clearing it afterwards so a
second ack cannot double-count.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HHPL4VFWQRQPpjR1gXSKyL
@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.15%. Comparing base (3073eb9) to head (8224172).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #701      +/-   ##
==========================================
+ Coverage   94.14%   94.15%   +0.01%     
==========================================
  Files         104      104              
  Lines       11136    11141       +5     
  Branches     1201     1201              
==========================================
+ Hits        10484    10490       +6     
+ Misses        551      550       -1     
  Partials      101      101              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Event runtime metric is zero when using stream.take(...)

1 participant