Fix process shutdown (#3673)

I noticed that stopping the Lemmy process with ctrl+c wasnt working
because the activity channel isnt properly closed. This is now fixed.

Later we should also move the channel from static into LemmyContext,
Im not doing that now to avoid conflicts with #3670.
This commit is contained in:
Nutomic 2023-07-20 17:36:48 +02:00 committed by GitHub
parent 1a164a649e
commit ccc122100e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 11 deletions

View file

@ -4,10 +4,13 @@ use futures::future::BoxFuture;
use lemmy_db_schema::source::post::Post; use lemmy_db_schema::source::post::Post;
use lemmy_utils::{error::LemmyResult, SYNCHRONOUS_FEDERATION}; use lemmy_utils::{error::LemmyResult, SYNCHRONOUS_FEDERATION};
use once_cell::sync::{Lazy, OnceCell}; use once_cell::sync::{Lazy, OnceCell};
use tokio::sync::{ use tokio::{
sync::{
mpsc, mpsc,
mpsc::{UnboundedReceiver, UnboundedSender}, mpsc::{UnboundedReceiver, UnboundedSender, WeakUnboundedSender},
Mutex, Mutex,
},
task::JoinHandle,
}; };
type MatchOutgoingActivitiesBoxed = type MatchOutgoingActivitiesBoxed =
@ -21,17 +24,22 @@ pub enum SendActivityData {
CreatePost(Post), CreatePost(Post),
} }
// TODO: instead of static, move this into LemmyContext. make sure that stopping the process with
// ctrl+c still works.
static ACTIVITY_CHANNEL: Lazy<ActivityChannel> = Lazy::new(|| { static ACTIVITY_CHANNEL: Lazy<ActivityChannel> = Lazy::new(|| {
let (sender, receiver) = mpsc::unbounded_channel(); let (sender, receiver) = mpsc::unbounded_channel();
let weak_sender = sender.downgrade();
ActivityChannel { ActivityChannel {
sender, weak_sender,
receiver: Mutex::new(receiver), receiver: Mutex::new(receiver),
keepalive_sender: Mutex::new(Some(sender)),
} }
}); });
pub struct ActivityChannel { pub struct ActivityChannel {
sender: UnboundedSender<SendActivityData>, weak_sender: WeakUnboundedSender<SendActivityData>,
receiver: Mutex<UnboundedReceiver<SendActivityData>>, receiver: Mutex<UnboundedReceiver<SendActivityData>>,
keepalive_sender: Mutex<Option<UnboundedSender<SendActivityData>>>,
} }
impl ActivityChannel { impl ActivityChannel {
@ -49,10 +57,18 @@ impl ActivityChannel {
.get() .get()
.expect("retrieve function pointer")(data, context) .expect("retrieve function pointer")(data, context)
.await?; .await?;
} else { }
let lock = &ACTIVITY_CHANNEL.sender; // could do `ACTIVITY_CHANNEL.keepalive_sender.lock()` instead and get rid of weak_sender,
lock.send(data)?; // not sure which way is more efficient
else if let Some(sender) = ACTIVITY_CHANNEL.weak_sender.upgrade() {
sender.send(data)?;
} }
Ok(()) Ok(())
} }
pub async fn close(outgoing_activities_task: JoinHandle<LemmyResult<()>>) -> LemmyResult<()> {
ACTIVITY_CHANNEL.keepalive_sender.lock().await.take();
outgoing_activities_task.await??;
Ok(())
}
} }

View file

@ -21,7 +21,7 @@ use lemmy_api_common::{
context::LemmyContext, context::LemmyContext,
lemmy_db_views::structs::SiteView, lemmy_db_views::structs::SiteView,
request::build_user_agent, request::build_user_agent,
send_activity::MATCH_OUTGOING_ACTIVITIES, send_activity::{ActivityChannel, MATCH_OUTGOING_ACTIVITIES},
utils::{ utils::{
check_private_instance_and_federation_enabled, check_private_instance_and_federation_enabled,
local_site_rate_limit_to_rate_limit_config, local_site_rate_limit_to_rate_limit_config,
@ -227,7 +227,7 @@ pub async fn start_lemmy_server() -> Result<(), LemmyError> {
.await?; .await?;
// Wait for outgoing apub sends to complete // Wait for outgoing apub sends to complete
outgoing_activities_task.await??; ActivityChannel::close(outgoing_activities_task).await?;
Ok(()) Ok(())
} }