Skip to content

Event processor fix#6801

Draft
benedikt-bartscher wants to merge 2 commits into
reflex-dev:mainfrom
benedikt-bartscher:event-processor-fix
Draft

Event processor fix#6801
benedikt-bartscher wants to merge 2 commits into
reflex-dev:mainfrom
benedikt-bartscher:event-processor-fix

Conversation

@benedikt-bartscher

Copy link
Copy Markdown
Contributor

No description provided.

@codspeed-hq

codspeed-hq Bot commented Jul 19, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing benedikt-bartscher:event-processor-fix (91feef3) with main (f79d011)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@greptile-apps

greptile-apps Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a crash in EventProcessor.enqueue where calling add_child on an already-completed parent EventFuture would raise a RuntimeError. The fix adds a not parent_future.done() guard so late-arriving chained events are silently orphaned from their parent rather than crashing.

  • event_processor.py: A single-line guard (and not parent_future.done()) is added before parent_future.add_child(tracked). Because asyncio is single-threaded, there is no race between the done() check and the add_child call. The orphaned child's parent reference is preserved, so _try_clean_future can still walk up the chain and remove the parent from _futures once the child completes.
  • test_event_processor.py: A regression test manually seeds a done parent future into the processor's _futures map, enqueues a child event with that parent's txid, and asserts the child runs successfully while done_parent.children remains empty.

Confidence Score: 5/5

Safe to merge — the change is a one-line targeted guard with a direct regression test, and the surrounding asyncio machinery is unaffected.

The guard is correct for asyncio's single-threaded cooperative model: no await exists between the done() check and add_child, so no interleaving is possible. The child's parent field is preserved despite skipping add_child, allowing _try_clean_future to walk the parent chain and remove the parent from _futures once the orphaned child completes. The test covers the exact crash scenario and verifies both the child's execution and the parent's empty children list.

No files require special attention.

Important Files Changed

Filename Overview
packages/reflex-base/src/reflex_base/event/processor/event_processor.py Adds a not parent_future.done() guard before add_child to avoid a RuntimeError when a late-chained event arrives after its parent future has already resolved.
tests/units/reflex_base/event/processor/test_event_processor.py Adds a regression test verifying that enqueueing against an already-done parent future doesn't crash and that the child event still executes successfully.

Reviews (1): Last reviewed commit: "typing" | Re-trigger Greptile

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.

1 participant