use crate::feed::Post; pub async fn spawn(redis_url: &str, mut post_rx: tokio::sync::mpsc::UnboundedReceiver) { let client = redis::Client::open(redis_url) .expect("redis::Client"); let mut man = redis::aio::ConnectionManager::new(client).await .expect("redis::aio::ConnectionManager"); tokio::spawn(async move { while let Some(post) = post_rx.recv().await { if post.tags.is_empty() { continue; } if let Some(timestamp) = post.timestamp() { let post_key = format!("p:{}", post.url); let cmd = redis::Cmd::getset(&post_key, "1"); if cmd.query_async::<_, Option>>(&mut man).await.unwrap().is_some() { continue; } let hour = timestamp.naive_utc().timestamp() / 3600; let mut cmd = redis::pipe(); for tag in post.tags { let tag_key = format!("t:{}", tag.name.to_lowercase()); // by hour cmd.hincr( &tag_key, format!("h:{}", hour), 1 ).ignore(); // by spelling cmd.hincr( tag_key, format!("s:{}", tag.name), 1 ).ignore(); } match cmd.query_async(&mut man).await { Ok(()) => {} Err(e) => { eprintln!("redis error: {:?}", e); } } } } }); }