Arifa
Arifa is a lightweight, Redis-based realtime pub/sub engine for Rust applications.
It provides a simple abstraction over Redis Pub/Sub and WebSocket sessions, making it easy to build scalable realtime systems that work across multiple application nodes.
Features
- Redis Pub/Sub
- Shared Redis Pub/Sub connection per node
- Automatic reconnect with exponential backoff
- Automatic channel resubscription
- Tokio async runtime
- WebSocket session abstraction
- Channel-based subscriptions
- Multi-node message routing
- Online user tracking
- Lock-free metrics
- Framework agnostic (
WsSessiontrait)
Installation
Creating an Arifa Instance
use *;
async
Defining a WebSocket Session
Arifa is transport agnostic. Implement the WsSession trait for your WebSocket framework.
use *;
use async_trait;
;
Subscribing
subscribe() registers the session, marks it online, and returns a generated session id.
let session = MySession;
let channels = vec!;
let session_id = arifa.subscribe.await?;
The returned session id is used when removing the connection from the online users set and unsubscribing.
Publishing Messages
use *;
use json;
let message = WsMessage ;
arifa
.publish
.await?;
Unsubscribing
When a WebSocket disconnects, remove the session from the online users set before unsubscribing.
let _ = arifa.remove_online_user.await;
arifa.unsubscribe;
Message Model
MessageScope
MessageKind
Online Users
A connection is automatically marked online inside subscribe().
Query the current number of active sessions:
let users = arifa.online_users.await?;
println!;
Remove a session when its WebSocket closes:
let _ = arifa.remove_online_user.await;
Check whether a user currently has any active sessions:
let online = arifa.is_user_online.await?;
Note: The online count reflects active sessions, not unique users. Multiple browser tabs or devices for the same user count as multiple sessions.
Multi-node Routing
To target only a specific application node, set the node_id field.
let message = WsMessage ;
arifa.publish.await?;
If node_id is None, every subscribed node receives the message.
Metrics
Arifa exposes lightweight runtime metrics.
let metrics = arifa.metrics.snapshot;
println!;
println!;
println!;
println!;
Graceful Shutdown
Before shutting down your application, stop Arifa's background router and forwarding tasks.
arifa.shutdown;
Example: Actix Web
pub async
Architecture
WebSocket Client
│
▼
WsSession
│
▼
Per-session forwarder
▲
│
Routing Table
│
▼
Shared Redis Pub/Sub Router
(one per application node)
│
▼
Redis Pub/Sub
│
▼
Other Nodes
Each Arifa instance maintains a single Redis Pub/Sub connection that is shared by all subscriptions on that node. Incoming messages are routed to subscribed sessions through an in-memory routing table. If the Redis connection drops, Arifa automatically reconnects and resubscribes to all active channels.
Use Cases
- Chat applications
- Notifications
- Live location updates
- Multiplayer games
- Live dashboards
- Social feeds
- Collaborative applications
Notes
- One shared Redis Pub/Sub connection is used per application node.
- Each subscribed session runs in its own forwarding task.
- Session message queues are bounded to prevent slow clients from consuming unbounded memory.
- Redis reconnects and channel resubscriptions happen automatically.
- Call
remove_online_user()beforeunsubscribe()when a client disconnects.
License
Apache-2.0