1 use crate::context::LemmyContext;
2 use activitypub_federation::config::Data;
3 use futures::future::BoxFuture;
4 use lemmy_db_schema::source::post::Post;
5 use lemmy_utils::{error::LemmyResult, SYNCHRONOUS_FEDERATION};
6 use once_cell::sync::{Lazy, OnceCell};
9 mpsc::{UnboundedReceiver, UnboundedSender},
13 type MatchOutgoingActivitiesBoxed =
14 Box<for<'a> fn(SendActivityData, &'a Data<LemmyContext>) -> BoxFuture<'a, LemmyResult<()>>>;
16 /// This static is necessary so that activities can be sent out synchronously for tests.
17 pub static MATCH_OUTGOING_ACTIVITIES: OnceCell<MatchOutgoingActivitiesBoxed> = OnceCell::new();
20 pub enum SendActivityData {
24 static ACTIVITY_CHANNEL: Lazy<ActivityChannel> = Lazy::new(|| {
25 let (sender, receiver) = mpsc::unbounded_channel();
28 receiver: Mutex::new(receiver),
32 pub struct ActivityChannel {
33 sender: UnboundedSender<SendActivityData>,
34 receiver: Mutex<UnboundedReceiver<SendActivityData>>,
37 impl ActivityChannel {
38 pub async fn retrieve_activity() -> Option<SendActivityData> {
39 let mut lock = ACTIVITY_CHANNEL.receiver.lock().await;
43 pub async fn submit_activity(
44 data: SendActivityData,
45 context: &Data<LemmyContext>,
46 ) -> LemmyResult<()> {
47 if *SYNCHRONOUS_FEDERATION {
48 MATCH_OUTGOING_ACTIVITIES
50 .expect("retrieve function pointer")(data, context)
53 let lock = &ACTIVITY_CHANNEL.sender;