Skip to content

Add rx.event arg to cancel previous background tasks#6793

Open
tim-haselhoff wants to merge 11 commits into
reflex-dev:mainfrom
tim-haselhoff:cancel-previous-background-tasks
Open

Add rx.event arg to cancel previous background tasks#6793
tim-haselhoff wants to merge 11 commits into
reflex-dev:mainfrom
tim-haselhoff:cancel-previous-background-tasks

Conversation

@tim-haselhoff

@tim-haselhoff tim-haselhoff commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

New Feature Submission:

  • Does your submission pass the tests?
  • Have you linted your code locally prior to submission?

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

After these steps, you're ready to open a pull request.

a. Give a descriptive title to your PR.
Add rx.event arg to cancel previous background tasks

b. Describe your changes.
Add rx.event arg to cancels runs of previous background tasks when a new one is scheduled.

c. Put `closes #XXXX` in your comment to auto-close the issue that your PR fixes (if such).

@benedikt-bartscher benedikt-bartscher left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks Tim!

@codspeed-hq

codspeed-hq Bot commented Jul 17, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing tim-haselhoff:cancel-previous-background-tasks (95fd0ce) 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 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a cancel_previous_task=True option to rx.event that automatically cancels a still-running background task for the same client whenever a new dispatch of the same handler arrives. The implementation is clean and correct.

  • O(1) lookup via _cancel_keys: A secondary dict[(token, event_name) → txid] is introduced, populated in _create_event_task and cleaned up in _finish_task (with a guard that avoids deleting a newer task's entry) and in stop().
  • Validation at decoration time: cancel_previous_task=True is rejected with a clear ValueError unless background=True is also set; the is_cancel_previous_task property on EventHandler propagates the marker to the processor.
  • Tests: A new async integration test exercises the cancellation path end-to-end and inspects _cancel_keys directly, verifying both start, cancel, and completion ordering.

Confidence Score: 5/5

Safe to merge; the cancellation bookkeeping is correct, cleanup is properly guarded, and the new behavior is well-tested.

The cancellation bookkeeping handles all edge cases correctly — task already done when superseded, task replaced before its _finish_task fires, and shutdown ordering. No runtime defects were found in the changed code.

No files require special attention.

Important Files Changed

Filename Overview
packages/reflex-base/src/reflex_base/event/processor/event_processor.py Adds _cancel_keys dict for O(1) cancel-key lookup; cancellation logic in _create_event_task is correct; _finish_task cleanup correctly guards against stomping a newer task's entry; shutdown clears the dict after tasks are stopped.
packages/reflex-base/src/reflex_base/event/init.py Adds cancel_previous_task parameter and CANCEL_PREVIOUS_TASK_MARKER constant; validation correctly requires background=True to be co-set; is_cancel_previous_task property is a clean addition to EventHandler.
tests/units/test_state.py Adds CancelPreviousTaskState and test_background_task_cancel_previous; module-level mutable lists accessed inside the background handler are safe for sequential runs but would conflict under parallel test execution.
packages/reflex-base/news/6793.feature.md Changelog entry with minor wording inaccuracy ("scheduled events" vs "running background tasks").

Reviews (6): Last reviewed commit: "Merge branch 'main' into cancel-previous..." | Re-trigger Greptile

Comment thread packages/reflex-base/src/reflex_base/event/processor/event_processor.py Outdated
Comment thread packages/reflex-base/src/reflex_base/event/processor/event_processor.py Outdated
Comment thread packages/reflex-base/src/reflex_base/event/__init__.py
@tim-haselhoff

tim-haselhoff commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

TODO: also check behaviour when running this within another event.

@tim-haselhoff
tim-haselhoff marked this pull request as ready for review July 18, 2026 14:09
@tim-haselhoff
tim-haselhoff requested a review from a team as a code owner July 18, 2026 14:10

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 95fd0ceda4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +593 to +595
existing = self._tasks.get(existing_txid)
if existing is not None and not existing.done():
existing.cancel()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve task context before cancelling queued background runs

On Python 3.12+, when two matching cancel_previous_task background events are enqueued back-to-back, _process_queue can reach this existing.cancel() before the first task has ever run _process_event_queue_entry and set EventContext to entry.ctx. _finish_task then reads the task's original queue-processor context via task.get_context(), so it does not pop the first txid from _tasks or settle that EventFuture; callers waiting on the first future can hang and the task entry leaks. Store the event context on every task before it can be cancelled, as the pre-3.12 path already does.

Useful? React with 👍 / 👎.

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.

2 participants