Events¶
Pokie includes an event system for decoupled communication between modules. Events are dispatched by name and handled by registered handlers, with support for priority-based execution ordering.
Event Registration¶
Events are registered in a module's events dictionary. The structure maps event names to priority levels, and each
priority level contains a list of handler class paths:
from pokie.core import BaseModule
class Module(BaseModule):
name = "my_module"
description = "My module"
events = {
"afterLogin": {
10: ["my_module.event.LoginLogger"],
},
"afterOrderCreate": {
10: ["my_module.event.SendConfirmationEmail"],
20: ["my_module.event.UpdateInventory"],
},
}
Lower priority numbers execute first. Handlers within the same priority level are executed in list order.
Event Handlers¶
There are two types of event handlers: class-based and function-based.
Class-Based Handlers¶
Class-based handlers extend EventHandler from Rick and define a method with the same name as the event:
from rick.event import EventHandler
class LoginLogger(EventHandler):
def afterLogin(self, **kwargs):
user = kwargs.get("user")
print(f"User logged in: {user.get_id()}")
The handler class is instantiated with the DI container on each dispatch. The event method receives the keyword
arguments passed to dispatch().
Function-Based Handlers¶
Function-based handlers are simple callables that receive event_name as an additional keyword argument:
def on_login(event_name, **kwargs):
user = kwargs.get("user")
print(f"Event {event_name}: user {user.get_id()}")
Dispatching Events¶
Events are dispatched via the EventManager, accessible through the DI container:
from pokie.constants import DI_EVENTS
evt_mgr = di.get(DI_EVENTS)
evt_mgr.dispatch(di, "afterLogin", user=user)
dispatch(di, event_name, **kwargs) -> bool¶
Dispatches an event by name. Returns True if the event was dispatched (handlers exist), False if no handlers are
registered for the event.
Handlers are executed synchronously in priority order. If an event has no registered handlers, the dispatch is a no-op.
Circular dependency protection: If a handler dispatches the same event that is currently being processed, a
RuntimeError is raised.
EventManager API¶
| Method | Description |
|---|---|
add_handler(event_name, handler, priority=100) |
Register a handler (dotted class path string) |
remove_handler(event_name, handler) |
Remove a handler. Returns True if found. |
get_events() |
List all registered event names |
dispatch(di, event_name, **kwargs) |
Dispatch an event |
purge() |
Remove all events and handlers |
load_handlers(src) |
Load handlers from a config dict (used during module loading) |