caveman/cave/src/firehose.rs

40 lines
1.3 KiB
Rust

use futures::{Stream, StreamExt};
use redis::RedisError;
use url::Url;
#[derive(Clone)]
pub struct FirehoseFactory {
redis_url: Url,
}
impl FirehoseFactory {
#[must_use] pub fn new(redis_url: String, redis_password_file: String) -> Self {
let redis_password = std::fs::read_to_string(redis_password_file)
.expect("redis_password_file");
let mut redis_url = Url::parse(&redis_url)
.expect("redis_url");
redis_url.set_password(Some(&redis_password)).unwrap();
FirehoseFactory { redis_url }
}
pub async fn produce(&self) -> Result<impl Stream<Item = (Vec<u8>, Vec<u8>)>, RedisError> {
let client = redis::Client::open(self.redis_url.clone())?;
let mut pubsub_conn = client.get_async_connection()
.await?
.into_pubsub();
pubsub_conn.subscribe("firehose")
.await?;
let stream = pubsub_conn.into_on_message()
.filter_map(|msg| async move {
let data = msg.get_payload::<Vec<u8>>().ok()?;
let nul_pos = data.iter().position(|&b| b == 0)?;
let event_type = data[..nul_pos].to_owned();
let post_data: Vec<u8> = data[nul_pos + 1..].to_owned();
Some((event_type, post_data))
});
Ok(stream)
}
}