Distributed event bus with Redis pub/sub, source-instance dedup, and pre-rehydration buffering
Project description
nodus-events
Distributed event bus with Redis pub/sub, source-instance deduplication, and pre-rehydration buffering.
Local-first: events are recorded in the in-process AuditStore and optionally
broadcast over Redis pub/sub when [redis] is installed. No required
external dependencies — the bus works fully in local mode without Redis.
Status: v0.1.0 — prepared, not yet published.
Install
pip install nodus-events
# With Redis pub/sub support:
pip install "nodus-events[redis]"
What it provides
| Component | Purpose |
|---|---|
EventBus |
Publish events locally and optionally via Redis pub/sub |
EventBusConfig |
Connection settings, channel, instance ID, buffer config |
Event |
Typed event record with type, payload, correlation ID, timestamp |
AuditStore / InMemoryAuditStore |
Persistent event log (protocol + in-memory impl) |
get_event_bus() |
Process-level singleton factory |
publish_event() |
Convenience wrapper for one-line event emission |
Quick start
from nodus_events import publish_event, get_event_bus
# One-liner emission (uses process singleton)
publish_event("user.created", payload={"user_id": "u123"}, correlation_id="req-abc")
# Direct bus access
bus = get_event_bus()
bus.publish("flow.completed", payload={"flow_id": "f1"})
# Read audit log
events = bus.audit_store.list()
Redis pub/sub
from nodus_events import EventBusConfig, get_event_bus
config = EventBusConfig(
redis_url="redis://localhost:6379",
channel="nodus:events",
instance_id="worker-1", # dedup: ignores events from own instance
)
bus = get_event_bus(config)
bus.start_subscriber(callback=lambda event: print(event.event_type))
Events published by this instance are not re-delivered to its own
subscriber — source_instance_id deduplication prevents echo loops.
Stop the subscriber and flush buffered events:
bus.stop()
buffered = bus.drain_buffered_events() # events received before start_subscriber()
Pre-rehydration buffering
Events that arrive over Redis before start_subscriber() is called are
buffered in memory. drain_buffered_events() returns them in order after
the subscriber starts — no events are lost during startup.
EventBusConfig
from nodus_events import EventBusConfig
config = EventBusConfig(
redis_url=None, # None → local-only mode (no Redis)
channel="nodus:events", # Redis pub/sub channel name
enabled=True,
instance_id="worker-1", # unique per process/pod
reconnect_delay_secs=5,
max_buffer_size=1000,
)
Event record
from nodus_events import Event
# Event fields:
event.event_type # str
event.correlation_id # str | None
event.source_instance_id # str
event.payload # dict | None
event.timestamp # float (UTC epoch seconds)
AuditStore protocol
from nodus_events import AuditStore, InMemoryAuditStore
store = InMemoryAuditStore()
store.record(event)
events = store.list() # all events
events = store.list(event_type="user.created")
events = store.list(limit=50)
Implement AuditStore to back the log with a database.
Singleton management
from nodus_events import get_event_bus, reset_event_bus
bus = get_event_bus(config) # creates singleton on first call
bus2 = get_event_bus() # returns same instance (config ignored)
# In tests — reset between cases:
reset_event_bus()
Design
- No required dependencies. Local mode works with zero extras.
Redis is opt-in via
[redis]extra. - Source-instance dedup. Each bus has a unique
instance_id; events it published are not re-delivered to itself. - Pre-rehydration buffer. Events arriving before
start_subscriber()are buffered so no events are dropped during startup. - Thread-safe. Singleton creation and audit store use
threading.Lock.
Development
pip install -e ".[dev]"
pytest tests/ -q
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nodus_events-0.1.0.tar.gz.
File metadata
- Download URL: nodus_events-0.1.0.tar.gz
- Upload date:
- Size: 11.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50695d1c90bbe868729590b2b266c4192301e65b054deada31f478c86a369335
|
|
| MD5 |
44186711faebbc7a844945668f29f551
|
|
| BLAKE2b-256 |
c4752f1e0d49461ce71bc50709ef04aeb9d900d0549379e1c550bbef4425d2a5
|
File details
Details for the file nodus_events-0.1.0-py3-none-any.whl.
File metadata
- Download URL: nodus_events-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a79643c947cd5c75d1730470d970cd17665f68d8e3705611f8dbd1a6e411f524
|
|
| MD5 |
24edccd6fda2b21b21e2045ab5cfabba
|
|
| BLAKE2b-256 |
d771e6d6dec3e5c65c9b15ec84ef68d05078f572962d89a6dfeed8486ade61b7
|