Event Loop
How OpenWalrus routes events through a single mpsc channel — zero bottlenecks, fully async.
The event loop is the core of the OpenWalrus daemon. All events from all sources flow through a single channel, and each is dispatched as its own async task.
How it works
[Sources] ──→ mpsc::unbounded ──→ [Event Loop] ──→ tokio::spawn- Sources (socket UDS/TCP, gateway service, tool calls) send
DaemonEventmessages into anmpsc::unboundedchannel - The event loop reads events one at a time
- Each event is dispatched via
tokio::spawn— non-blocking, fully parallel - The spawned task locks the target agent, runs it, and streams results back
Event types
The DaemonEvent enum covers all event sources:
| Variant | Source |
|---|---|
Message | Chat message from socket, Telegram, or Discord |
ToolCall | Tool invocation from an agent |
Heartbeat | Timer-fired per agent (see heartbeat) |
Shutdown | Graceful shutdown signal |
Why a single channel
A single mpsc::unbounded channel provides:
- Ordering — events arrive in the order they're sent
- Backpressure — unbounded means no sender blocks (the event loop is always fast enough to keep up)
- Simplicity — one place to observe all activity
The parallelism comes from tokio::spawn, not from multiple channels. Each event gets its own async task, so agents run concurrently even though events are dispatched sequentially.
Agent execution within the loop
When a message event arrives:
- Look up the target session in the runtime
- Lock the session's mutex
- Call
agent.run_stream()with the session's history and tool schemas - Forward
AgentEvents back to the transport (socket, bot, etc.) - Release the lock
Tool call events from the agent are sent back into the same channel, creating a natural feedback loop. Tool dispatch goes through DaemonHook::dispatch_tool, which handles permission checks, scope enforcement, and routing to the correct sub-hook.
When a heartbeat event fires, the daemon dispatches any pending work for that agent with the heartbeat prompt.
Starting the event loop
The daemon starts the event loop automatically when you run walrus daemon. See configuration for setup, and agents for how agents are configured.