feat: session garbage collection

This commit is contained in:
DJMrTV 2025-05-29 10:46:27 +02:00
commit 77e3f1ef08

View file

@ -52,17 +52,29 @@ impl MatchmakeManager{
let mut idx = 0; let mut idx = 0;
let mut to_be_deleted_gids = Vec::new();
// i am very well aware of how inefficient doing it like this is but this is the only // i am very well aware of how inefficient doing it like this is but this is the only
// way which i could think of to do this without potentially causing a deadlock of // way which i could think of to do this without potentially causing a deadlock of
// the entire server // the entire server
while let Some((gid, sessions)) = { while let Some((gid, session)) = {
let sessions = self.sessions.write().await; let sessions = self.sessions.read().await;
let session_pair = sessions.iter().nth(idx).map(|s| (*s.0, s.1.clone())); let session_pair = sessions.iter().nth(idx).map(|s| (*s.0, s.1.clone()));
drop(sessions); drop(sessions);
session_pair session_pair
}{ }{
let mut session = session.lock().await;
if !session.is_reachable(){
to_be_deleted_gids.push(gid);
}
}
let mut sessions = self.sessions.write().await;
for gid in to_be_deleted_gids{
sessions.remove(&gid);
} }
} }
@ -70,6 +82,8 @@ impl MatchmakeManager{
tokio::spawn(async move { tokio::spawn(async move {
while let Some(this) = this.upgrade(){ while let Some(this) = this.upgrade(){
this.garbage_collect().await; this.garbage_collect().await;
// every 30 minutes
sleep(Duration::from_secs(60 * 30)).await; sleep(Duration::from_secs(60 * 30)).await;
} }
}); });
@ -103,10 +117,12 @@ pub async fn broadcast_notification<T: AsRef<User>>(players: &[T], notification_
} }
impl ExtendedMatchmakeSession{ impl ExtendedMatchmakeSession{
#[inline(always)]
pub fn get_active_players(&self) -> Vec<Arc<User>>{ pub fn get_active_players(&self) -> Vec<Arc<User>>{
self.connected_players.iter().filter_map(|u| u.upgrade()).collect() self.connected_players.iter().filter_map(|u| u.upgrade()).collect()
} }
#[inline(always)]
pub async fn broadcast_notification(&self, notification_event: &NotificationEvent){ pub async fn broadcast_notification(&self, notification_event: &NotificationEvent){
broadcast_notification(&self.get_active_players(), notification_event).await; broadcast_notification(&self.get_active_players(), notification_event).await;
} }
@ -224,7 +240,7 @@ impl ExtendedMatchmakeSession{
} }
#[inline] #[inline]
pub fn is_reachable(&self) -> bool{ pub fn is_reachable(&self) -> bool{
if self.session.gathering.flags & PERSISTENT_GATHERING != 0{ (if self.session.gathering.flags & PERSISTENT_GATHERING != 0{
if !self.connected_players.is_empty(){ if !self.connected_players.is_empty(){
true true
} else { } else {
@ -232,7 +248,7 @@ impl ExtendedMatchmakeSession{
} }
} else { } else {
!self.connected_players.is_empty() !self.connected_players.is_empty()
} }) & !self.connected_players.is_empty()
} }
#[inline] #[inline]
pub fn is_joinable(&self) -> bool{ pub fn is_joinable(&self) -> bool{