Domain Events and Messaging
Relevant source files
The following files were used as context for generating this wiki page:
Domain events and messaging in Athena form the backbone of its decoupled communication architecture. The system distinguishes between fire-and-forget notifications (EventBus) and guaranteed delivery background processing (JobQueue). This allows the application to remain responsive by offloading heavy processing tasks—such as PP calculation and leaderboard updates—to a separate worker process while maintaining loose coupling between different domain contexts.
The architecture emphasizes strict boundaries where domain events are transport-independent and represent business-meaningful state changes. These events are used for internal synchronization and triggering side effects without making services depend on concrete infrastructure implementations.
Sources: README.md:12-16, AGENTS.md:204-206, tests/unit/test_event_boundaries.py
Messaging Architecture
Athena employs two primary messaging patterns to manage state changes and background tasks: the EventBus and the JobQueue. The EventBus is utilized for immediate, fire-and-forget notifications within the system, while the JobQueue ensures delivery for critical tasks that require guaranteed execution.
The diagram above illustrates the separation of concerns between immediate application responses and heavy background processing.
Sources: README.md:120-123, AGENTS.md:204-206, AGENTS.md:329-332
Event Classification and Boundaries
Events in Athena are strictly classified to prevent architectural leakage. A critical rule is that Distributed Events are not used as the source of truth for persistence. For instance, chat persistence is handled directly by command services rather than relying on event subscriptions.
| Feature | Description |
|---|---|
| Local Events | Internal synchronization within a single process or context. |
| Distributed Events | Cross-process communication, typically backed by Valkey. |
| Job Payloads | Primitive types used to trigger background tasks via Taskiq. |
Sources: tests/unit/test_event_boundaries.py:44-53, AGENTS.md:267-274
Domain Event Structure
Domain events are defined as standard Python @dataclass(slots=True) objects. They reside in the domain/events/ context and must remain pure, meaning they cannot import infrastructure, repositories, or services.
Core Implementation
While specific event field implementation details are abstracted in the base classes, the system enforces that events remain transport-independent business language.
# Example of the structural expectation for Domain Events
@dataclass(slots=True, frozen=True)
class DomainEvent:
"""Base class for all domain events in the system."""
pass
Sources: AGENTS.md:167-184, src/osu_server/domain/events/base.py
Distributed and Volatile State
The messaging system relies on Valkey (using the valkey-glide driver) for managing volatile state, including packet queues and pub/sub concerns. This infrastructure choice enables horizontal scaling, as process restarts do not result in the loss of session state or pending notifications.
The diagram shows how Valkey serves as the central hub for shared runtime state and messaging infrastructure.
Sources: README.md:115-117, AGENTS.md:334-336, src/osu_server/config.py:34-40
Configuration Parameters
The messaging system behavior is tuned via application configuration settings:
| Config Option | Type | Default | Description |
|---|---|---|---|
packet_queue_max_size | int | 4096 | Maximum number of packets held in the queue. |
valkey_url | RedisDsn | (Required) | URL for the Valkey/Redis instance. |
message_max_length | int | 450 | Maximum length for chat messages. |
rate_limit_messages | int | 10 | Max messages per window for rate limiting. |
Sources: src/osu_server/config.py:42-53
Integration with Background Jobs
Athena utilizes a two-process model where the App process (uvicorn) handles immediate responses like authentication and chat delivery, while the Worker process (taskiq) handles heavy-duty processing.
- Triggering: Use-cases invoke the
JobQueueor fire events that lead to job scheduling. - Adaptation: The
jobs/layer contains Taskiq adapters that validate task payload primitives. - Execution: The worker resolves the necessary command/query use-cases via Dishka DI to perform the work.
Sources: AGENTS.md:329-332, AGENTS.md:267-274
Summary
The Domain Events and Messaging system in Athena ensures that the server remains highly responsive and scalable. By decoupling immediate business logic from heavy side effects and utilizing Valkey for distributed state, the project achieves a modular architecture where transport concerns do not leak into the core domain. The strict enforcement of import boundaries and the use of explicit Job and Event interfaces maintain the integrity of the hexagonal architecture.
Sources: README.md:52-64, AGENTS.md:124-135