From 149318e533e73c7c7a95b441f5c18770cfa88a61 Mon Sep 17 00:00:00 2001 From: Daniel Cadenas Date: Sat, 27 Apr 2024 20:47:39 -0300 Subject: [PATCH] Event dispatcher should know nothing about GiftWrappedReportRequest --- src/actors/gift_unwrapper.rs | 26 +++++++++++++++++++++++--- src/actors/messages.rs | 22 +++++++++++++++++----- src/actors/relay_event_dispatcher.rs | 23 ++++------------------- src/domain_objects/as_gift_wrap.rs | 7 +++---- 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/actors/gift_unwrapper.rs b/src/actors/gift_unwrapper.rs index 11610de..d2a0911 100644 --- a/src/actors/gift_unwrapper.rs +++ b/src/actors/gift_unwrapper.rs @@ -40,8 +40,22 @@ impl Actor for GiftUnwrapper { state: &mut Self::State, ) -> Result<(), ActorProcessingErr> { match message { - // Decrypts and forwards private messages to the output port. - GiftUnwrapperMessage::UnwrapEvent(gift_wrap) => { + // Decrypts and forwards private messages so they can be sent to + // google pubsub or whatever is hooked to the output port. + // + // Note that this is a good example of what we are trying to achieve + // in terms of separation of concerns, keeping the actor logic just + // as an orchestrator for our domain code. The brains of the + // operation are in the domain model. + GiftUnwrapperMessage::UnwrapEvent(maybe_gift_wrap) => { + // 1) The actor's message handling, which includes the message From + // implementation, deal with massaging the message to gather the + // input for... + let Some(gift_wrap) = maybe_gift_wrap else { + return Ok(()); + }; + + // 2) The domain model, which does the real work. let report_request = match gift_wrap.extract_report_request(&state.keys) { Ok(report_request) => report_request, Err(e) => { @@ -50,6 +64,9 @@ impl Actor for GiftUnwrapper { } }; + // 3) Resulting model output is used to create events + // that are sent to the output port for the next actor or any other + // IO needed info!( "Request from {} to moderate event {}", report_request.reporter_pubkey(), @@ -128,10 +145,13 @@ mod tests { cast!( parser_actor_ref, - GiftUnwrapperMessage::UnwrapEvent(gift_wrapped_event) + GiftUnwrapperMessage::UnwrapEvent(Some(gift_wrapped_event)) ) .unwrap(); + // This happens when during the From conversion, the event + cast!(parser_actor_ref, GiftUnwrapperMessage::UnwrapEvent(None)).unwrap(); + tokio::spawn(async move { sleep(Duration::from_secs(1)).await; parser_actor_ref.stop(None); diff --git a/src/actors/messages.rs b/src/actors/messages.rs index effbf5a..297397c 100644 --- a/src/actors/messages.rs +++ b/src/actors/messages.rs @@ -1,7 +1,9 @@ use crate::domain_objects::*; +use metrics::counter; use nostr_sdk::prelude::*; use ractor::{port::OutputPortSubscriber, RpcReplyPort}; use std::fmt::Debug; +use tracing::error; pub enum SupervisorMessage { Publish(ModeratedReport), @@ -11,21 +13,31 @@ pub enum SupervisorMessage { pub enum RelayEventDispatcherMessage { Connect, Reconnect, - SubscribeToEventReceived(OutputPortSubscriber), + SubscribeToEventReceived(OutputPortSubscriber), EventReceived(Event), Publish(ModeratedReport), GetNip05(PublicKey, RpcReplyPort>), } pub enum GiftUnwrapperMessage { - UnwrapEvent(GiftWrappedReportRequest), + // If an event couldn't be mapped to a GiftWrappedReportRequest, it will be None + UnwrapEvent(Option), SubscribeToEventUnwrapped(OutputPortSubscriber), } // How to subscribe to actors that publish DM messages like RelayEventDispatcher -impl From for GiftUnwrapperMessage { - fn from(gift_wrap: GiftWrappedReportRequest) -> Self { - GiftUnwrapperMessage::UnwrapEvent(gift_wrap) +impl From for GiftUnwrapperMessage { + fn from(event: Event) -> Self { + let gift_wrapped_report_request = match GiftWrappedReportRequest::try_from(event) { + Ok(gift) => Some(gift), + Err(e) => { + counter!("event_received_error").increment(1); + error!("Failed to get gift wrap event: {}", e); + None + } + }; + + GiftUnwrapperMessage::UnwrapEvent(gift_wrapped_report_request) } } diff --git a/src/actors/relay_event_dispatcher.rs b/src/actors/relay_event_dispatcher.rs index e24cfa2..ce612a3 100644 --- a/src/actors/relay_event_dispatcher.rs +++ b/src/actors/relay_event_dispatcher.rs @@ -1,5 +1,4 @@ use crate::actors::messages::RelayEventDispatcherMessage; -use crate::domain_objects::GiftWrappedReportRequest; use crate::service_manager::ServiceManager; use anyhow::Result; use metrics::counter; @@ -20,7 +19,7 @@ impl Default for RelayEventDispatcher { } } pub struct State { - event_received_output_port: OutputPort, + event_received_output_port: OutputPort, subscription_task_manager: Option, nostr_client: T, } @@ -153,18 +152,7 @@ impl Actor for RelayEventDispatcher { subscriber.subscribe_to_port(&state.event_received_output_port); } RelayEventDispatcherMessage::EventReceived(event) => { - let gift_wrapped_report_request = match GiftWrappedReportRequest::try_from(event) { - Ok(gift) => gift, - Err(e) => { - counter!("event_received_error").increment(1); - error!("Failed to get gift wrap event: {}", e); - return Ok(()); - } - }; - - state - .event_received_output_port - .send(gift_wrapped_report_request); + state.event_received_output_port.send(event); counter!("event_received").increment(1); } RelayEventDispatcherMessage::Publish(moderated_report) => { @@ -314,7 +302,7 @@ mod tests { .await .unwrap(); - let received_messages = Arc::new(Mutex::new(Vec::::new())); + let received_messages = Arc::new(Mutex::new(Vec::::new())); let (receiver_ref, receiver_handle) = Actor::spawn(None, TestActor::default(), Some(received_messages.clone())) @@ -343,10 +331,7 @@ mod tests { assert_eq!( received_messages.lock().await.as_ref(), - [ - GiftWrappedReportRequest::try_from(first_event).unwrap(), - GiftWrappedReportRequest::try_from(second_event).unwrap() - ] + [first_event, second_event] ); } } diff --git a/src/domain_objects/as_gift_wrap.rs b/src/domain_objects/as_gift_wrap.rs index e16e423..f9981c8 100644 --- a/src/domain_objects/as_gift_wrap.rs +++ b/src/domain_objects/as_gift_wrap.rs @@ -14,8 +14,7 @@ pub trait AsGiftWrap { fn random_time_in_last_two_days(&self) -> Timestamp { let now = Timestamp::now(); let two_days = 2 * 24 * 60 * 60; - let random_time = now - (rand::random::() % two_days); - random_time + now - (rand::random::() % two_days) } } @@ -69,10 +68,10 @@ mod tests { async fn test_as_gift_wrap() { let reporter_keys = Keys::generate(); let receiver_keys = Keys::generate(); - let rumor = EventBuilder::text_note("Hello", []) + let event_to_report = EventBuilder::text_note("Hello", []) .to_event(&reporter_keys) .unwrap(); - let report_request = ReportRequest::new(rumor, reporter_keys.public_key(), None); + let report_request = ReportRequest::new(event_to_report, reporter_keys.public_key(), None); let gift_wrap = report_request .as_gift_wrap(&reporter_keys, &receiver_keys.public_key())