rifts 0.3.10

Rift Realtime Protocol / 1.0 — server + client implementation
Documentation
//! Redis-backed monotonic offset allocation.
//!
//! Uses a Redis Hash with `HINCRBY` for atomic, distributed offset
//! allocation. Each topic maps to a field in a shared Redis hash.
//! All methods are async to avoid blocking the Tokio runtime.

use async_trait::async_trait;

use crate::redis::connection::RedisPool;
use crate::storage::OffsetStore;

#[derive(Clone)]
pub struct RedisOffsetStore {
    pool: RedisPool,
}

impl RedisOffsetStore {
    pub fn new(pool: RedisPool) -> Self {
        Self { pool }
    }

    fn hash_key(&self) -> String {
        self.pool.key("offsets")
    }
}

#[async_trait]
impl OffsetStore for RedisOffsetStore {
    async fn alloc(&self, topic: &str) -> i64 {
        let key = self.hash_key();
        let mut conn = self.pool.conn().clone();
        redis::cmd("HINCRBY")
            .arg(&key)
            .arg(topic)
            .arg(1)
            .query_async(&mut conn)
            .await
            .unwrap_or(1)
    }

    async fn head(&self, topic: &str) -> i64 {
        let key = self.hash_key();
        let mut conn = self.pool.conn().clone();
        redis::cmd("HGET")
            .arg(&key)
            .arg(topic)
            .query_async(&mut conn)
            .await
            .unwrap_or(None)
            .unwrap_or(0)
    }

    async fn remove(&self, topic: &str) {
        let key = self.hash_key();
        let mut conn = self.pool.conn().clone();
        let _: Result<(), _> = redis::cmd("HDEL")
            .arg(&key)
            .arg(topic)
            .query_async(&mut conn)
            .await;
    }
}