Skip to content

Create new EventDispatcher to move user-provided callback execution out of the main thread - #403

Open
ppicom wants to merge 7 commits into
mainfrom
fix/eg-4649-move-event-callback-execution-out-of-the-hot-path-of
Open

Create new EventDispatcher to move user-provided callback execution out of the main thread#403
ppicom wants to merge 7 commits into
mainfrom
fix/eg-4649-move-event-callback-execution-out-of-the-hot-path-of

Conversation

@ppicom

@ppicom ppicom commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

The pull request introduces the implementation of EventDispatcher. Its goal is to move all event-and-callback-related code to the same file. At the same time, the EventDispatcher is based on threads: the "callers" of the dispatcher will use emit_event to queue an event, and a worker thread managed by the dispatcher will drain the queue.

In this pull request, the Dispatcher is not yet wired to anyone.

Reason for these changes

This is the initial step towards solving two problems:

  1. the user-provided event callback currently runs in the hot path, making it possible for users to stall is_enabled indefinitely; and
  2. the async counterpart to the current UnleashClient (i.e. AsyncUnleashClient) will also support sending events to a callback

By introducing a single class that deals with event-sending as a whole, code will be shared and we ensure we don't run it in the hot path anymore (as long as we publish events through the EventDispatcher).

Tricky parts when reviewing

Threads and locks

EventDispatcher deals with locks and threads, which is always fun. Variables like _closed, as well as the two centinels ( _SHUTDOWN and _FlushMarker) help manage the synchronization of operations:

  • To avoid race conditions
  • To avoid leaving the Dispatcher in an inconsistent state (e.g. allowing to send after having invoked close()

Backpressure

I discarded the option of adding a timeout or a number of retries to a user's callback. I'm happy to revisit the decision.

@ppicom
ppicom force-pushed the fix/eg-4649-move-event-callback-execution-out-of-the-hot-path-of branch from 54c3b78 to fa3f132 Compare August 4, 2026 15:14
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 30923141826

Coverage increased (+0.3%) to 93.678%

Details

  • Coverage increased (+0.3%) from the base build.
  • Patch coverage: 4 uncovered changes across 1 file (91 of 95 lines covered, 95.79%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
UnleashClient/events.py 95 91 95.79%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 870
Covered Lines: 815
Line Coverage: 93.68%
Coverage Strength: 0.94 hits per line

馃挍 - Coveralls

@gastonfournier gastonfournier moved this from New to In Progress in Issues and PRs Aug 5, 2026
@ppicom ppicom changed the title wip fix(events): move callback invocation outside of hot path Create new EventDispatcher to move user-provided callback execution out of the main thread Aug 5, 2026
Comment thread UnleashClient/events.py Outdated
return self._parsed_payload


_SHUTDOWN = object()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

On second thought, this sentinel is not super very idiomatic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Replaced by a class-based one.

Using an instance of object was a bit awkward
@ppicom
ppicom marked this pull request as ready for review August 5, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

4 participants