The EventLinker Registry¶
🏗️ Work in Progress
This section is currently being rebuilt.
Events are essential for building reactive applications with Pyventus. However, we need a way to connect
events to the code that should run in response. This is where the EventLinker
comes in.
What is the EventLinker?¶
The EventLinker
is a central class that acts as a registry for linking events to their associated
event handlers. It keeps track of which events have event handlers assigned to them, so when an event occurs it knows
which code needs to run.
The EventLinker
can also be subclassed to create separate linking registries, allowing you to define
different namespaces or contexts for events and event handlers.
Benefits of Using The EventLinker¶
Using the EventLinker
class offers several advantages:
- Clear separation of concerns - The emitter class focuses only on emitting events, while the linker handles all the subscription logic. This makes both classes cleaner and easier to understand, as well as allowing them to be modified independently as needed.
- Centralized logic - Having global registries means there is only one place to go to see which events have event handlers. This simplifies management of the overall event system.
- Flexibility - You can change the event emitter instance at runtime without the need to reconfigure all connections.
Event Handlers¶
Before proceeding, we should first understand the concept behind event handlers and what they do. An event handler is a callable object designed to respond to a specific event. When an event occurs, such as a button click, mouse movement, or a timer expiration, these objects are executed concurrently in response.
The EventHandler
class encapsulates the event callbacks and provides a standardized mechanism for
executing them when the event occurs. It handles the asynchronous and synchronous execution of event callbacks,
as well as the completion workflow for success and error handling.
Subscribing Event Handlers¶
The EventLinker
makes it easy to subscribe event handlers to respond to events. Let's explore the
different approaches to subscribing event handlers.
Subscription Basics¶
Pyventus supports two types of subscriptions to handle callback registration: regular subscriptions and
one-time subscriptions. Each subscription, regardless of type, will create a separate EventHandler
instance
independently. So subscribing the same callback multiple times to an event will cause it to be invoked
multiple times.
Regular Subscriptions¶
Regular subscriptions trigger the event handler each time the subscribed event(s) occur, and the handler remains subscribed until explicitly unsubscribed. Below we will explore how to subscribe regular event handlers.
Using decorators¶
Decorators provide a clean Python syntax for subscribing handlers.
Using the subscribe() method¶
You can also subscribe event handlers by calling the subscribe()
method.
One-time Subscriptions¶
One-time subscriptions trigger the event handler only once, then automatically unsubscribe it. One-time handlers are useful for tasks that should only run once.
Behavior with Multiple Events
When subscribing a one-time handler to multiple events, if one event fires it will automatically unsubscribe the event handler from all other events.
Using decorators¶
In order to perform a one-time subscription using decorators we use the once()
method:
Using the subscribe() method¶
Alternatively, you can also use the subscribe()
method to do a one-time subscription too:
Success and Error Handling¶
In the previous sections, we discussed the process of subscribing callback functions to handle events using Pyventus' event linker. However, there may be times when we need more control over the exact workflow.
In this section, we'll show you how to define custom logic to process events upon completion using success and failure handlers. It's important to have reliable control over the asynchronous flow to build robust apps.
Response Logic For Regular Subscriptions¶
- When the
EventLinker.on
method is used as a context manager via thewith
statement, it allows multiple callbacks to be associated with events within thelinkage context block
, defining the event workflow.
Response Logic For One-time Subscriptions¶
- When the
EventLinker.once
method is used as a context manager via thewith
statement, it allows multiple callbacks to be associated with events within thelinkage context block
, defining the event workflow.
Optimizing Callbacks Execution¶
By default, event handlers in Pyventus are executed concurrently during an event emission, running their
sync
and async
callbacks as defined. However, if you have a sync
callback
that involves I/O or non-CPU bound operations, you can enable the force_async
parameter to offload it
to a thread pool, ensuring optimal performance and responsiveness. The force_async
parameter utilizes
the asyncio.to_thread()
function to execute sync
callbacks asynchronously.
Unsubscribing Event Handlers¶
Removing event handlers is an important part of working with events. Let's look at different approaches to properly teardown event subscriptions:
Removing an Event Handler from an Event¶
To remove a single event handler from a specific event:
- Removes the
event_handler
from just theStringEvent
Removing Event Handlers from All Events¶
To remove an event handler from all subscribed events:
- Removes the
event_handler
from theStringEvent
andAnotherEvent
Removing an Event and its Event Handlers¶
To delete an event and all associated handlers:
- Removes all event handlers associated with the
StringEvent
Clearing All Events¶
To remove all events and their handlers:
Custom Event Linkers¶
The EventLinker
class in Pyventus was designed to support subclassing to allow you to define separate
linking registries or namespaces for your events and handlers, as well as configure the EventLinker
behavior.
This approach provides a powerful way to customize how events are linked within your applications. Some key reasons
for using custom linkers include:
- Organizing events into logical domains/contexts.
- Isolating events to only be accessible within certain scopes.
- Configuring linker-specific options like max handlers per event.
To define a custom linker, subclass the EventLinker
, as shown below:
Debug Mode¶
The EventLinker
also offers a debug mode feature which helps you understand how event subscriptions
and unsubscriptions are happening during runtime.
Global Debug Mode¶
By default, Pyventus leverages the Python's global debug tracing feature. Simply run your code in an IDE's debugger mode to activate the global debug mode tracing.
Namespace Debug Flag¶
Alternatively, if you want to enable or disable the debug mode specifically for a certain EventLinker
namespace, you can use the debug
flag that is available in the subclass configurations. Setting the
debug
flag to True
enables debug mode for that namespace, while setting it to False
disables
debug mode. Here's an example:
Recap¶
In this tutorial we covered:
- The standardized mechanism for executing event callbacks (Event Handlers).
-
Subscribing regular and one-time handlers with decorators and the
subscribe()
method. - Unsubscribing a single event handler, all handlers, an event, or clearing all.
- Success and error handling by defining custom logic for event completion.
- Techniques for optimizing synchronous callback execution.
- Custom Event Linkers to separate event namespaces.
- Debug mode to trace subscriptions
We learned the core EventLinker
concepts of:
- Use the EventLinker to link events to code responses.
- Subscribe/unsubscribe as needed using various approaches.