sneedstr/src/bussy/mod.rs
Tony Klink 0bbce25d39
Add pubkey ban support
Temporary use nostr-db as a db backend due to breaking API change
    in the library
2024-01-23 10:30:47 -06:00

158 lines
4.7 KiB
Rust

use crate::{
noose::user::{User, UserRow},
noose::sled::BanInfo,
utils::{error::Error, structs::Subscription},
};
use nostr::secp256k1::XOnlyPublicKey;
use std::{collections::HashMap, fmt::Debug};
use tokio::sync::{broadcast, Mutex};
pub mod channels {
pub static MSG_NOOSE: &str = "MSG_NOOSE";
pub static MSG_NIP05: &str = "MSG_NIP05";
pub static MSG_RELAY: &str = "MSG_RELAY";
pub static MSG_PIPELINE: &str = "MSG_PIPELINE";
pub static MSG_SLED: &str = "MSG_SLED";
}
#[derive(Debug, Clone, PartialEq)]
pub enum Command {
// DbRequest
DbReqWriteEvent(/* client_id */ uuid::Uuid, Box<nostr::Event>),
DbReqFindEvent(/* client_id*/ uuid::Uuid, Subscription),
DbReqDeleteEvents(/* client_id*/ uuid::Uuid, Box<nostr::Event>),
DbReqEventCounts(/* client_id*/ uuid::Uuid, Subscription),
// Old messages
DbReqInsertUser(UserRow),
DbReqGetUser(User),
DbReqCreateAccount(XOnlyPublicKey, String, String),
DbReqGetAccount(String),
DbReqClear,
// DbResponse
DbResRelayMessages(
/* client_id*/ uuid::Uuid,
/* Vec<RelayMessage::Event> */ Vec<nostr::RelayMessage>,
),
DbResInfo,
DbResOk,
DbResOkWithStatus(/* client_id */ uuid::Uuid, nostr::RelayMessage),
DbResAccount, // TODO: Add Account DTO as a param
DbResUser(UserRow),
DbResEventCounts(/* client_id */ uuid::Uuid, nostr::RelayMessage),
// Event Pipeline
PipelineReqEvent(/* client_id */ uuid::Uuid, Box<nostr::Event>),
PipelineResRelayMessageOk(/* client_id */ uuid::Uuid, nostr::RelayMessage),
PipelineResStreamOutEvent(Box<nostr::Event>),
PipelineResOk,
// Subscription Errors
ClientSubscriptionError(/* error message */ String),
// Sled
SledReqBanUser(Box<BanInfo>),
SledReqBanInfo(/* pubkey */ String),
SledReqUnbanUser(/* pubkey */ String),
SledReqGetBans,
SledResBan(Option<BanInfo>),
SledResBans(Vec<BanInfo>),
SledResSuccess(bool),
// Other
Str(String),
ServiceError(Error),
Noop,
}
#[derive(Debug, Clone)]
pub struct Message {
pub source: &'static str,
pub content: Command,
}
#[derive(Debug)]
pub struct PubSub {
subscribers: Mutex<HashMap<String, Vec<broadcast::Sender<Message>>>>,
}
impl Default for PubSub {
fn default() -> Self {
panic!("Use PubSub::new() to initialize PubSub");
}
}
impl PubSub {
pub fn new() -> Self {
PubSub {
subscribers: Mutex::new(HashMap::new()),
}
}
pub async fn subscribe(&self, topic: &str) -> broadcast::Receiver<Message> {
let (tx, _rx) = broadcast::channel(32); // 32 is the channel capacity
let mut subscribers = self.subscribers.lock().await;
subscribers
.entry(topic.to_string())
.or_insert_with(Vec::new)
.push(tx.clone());
tx.subscribe()
}
pub async fn publish(&self, topic: &str, message: Message) {
let mut subscribers = self.subscribers.lock().await;
if let Some(queue) = subscribers.get_mut(topic) {
for sender in queue.iter() {
sender.send(message.clone()).ok();
}
}
}
}
// #[cfg(test)]
// mod tests {
// use super::channels;
// use crate::bussy::{Command, Message, PubSub};
// use std::sync::Arc;
// #[tokio::test]
// async fn create_bus() {
// let pubsub = Arc::new(PubSub::new());
// let mut subscriber1 = pubsub.subscribe(channels::MSG_NIP05).await;
// let mut subscriber2 = pubsub.subscribe(channels::MSG_NOOSE).await;
// tokio::spawn(async move {
// while let Ok(message) = subscriber1.recv().await {
// println!("Subscriber1 received: {:?}", message);
// }
// });
// tokio::spawn(async move {
// while let Ok(message) = subscriber2.recv().await {
// println!("Subscriber2 received: {:?}", message);
// }
// });
// pubsub
// .publish(
// channels::MSG_NIP05,
// Message {
// source: "test",
// content: Command::Str("Hello S1".to_string()),
// },
// )
// .await;
// pubsub
// .publish(
// channels::MSG_NOOSE,
// Message {
// source: "test",
// content: Command::Str("Hello S2".to_string()),
// },
// )
// .await;
// dbg!(pubsub);
// // Sleep to keep the main thread alive while messages are processed in the background.
// tokio::time::sleep(std::time::Duration::from_secs(1)).await;
// }
// }