40 lines
1.3 KiB
Rust
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)
|
|
}
|
|
}
|