chore: shorten group lifetime (#726)

This commit is contained in:
Nathan.fooo 2024-08-13 16:20:06 +08:00 committed by GitHub
parent 71d292ebcd
commit 73127fb886
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 50 additions and 29 deletions

View File

@ -67,12 +67,7 @@ impl StreamGroup {
match result { match result {
Ok(_) => Ok(()), Ok(_) => Ok(()),
Err(redis_error) => { Err(redis_error) => {
warn!( let result = match redis_error.kind() {
"error when creating consumer group `{}` `{}`: {:?}",
self.stream_key, self.group_name, redis_error
);
return match redis_error.kind() {
ErrorKind::ExtensionError => match redis_error.code() { ErrorKind::ExtensionError => match redis_error.code() {
None => Err(StreamError::from(redis_error)), None => Err(StreamError::from(redis_error)),
Some(code) => { Some(code) => {
@ -85,6 +80,11 @@ impl StreamGroup {
}, },
_ => Err(StreamError::from(redis_error)), _ => Err(StreamError::from(redis_error)),
}; };
if result.is_err() {
error!("error when creating consumer group: {:?}", result);
}
result
}, },
} }
} }

View File

@ -27,7 +27,7 @@ use collab_stream::stream_group::StreamGroup;
use std::sync::atomic::{AtomicBool, AtomicI64, AtomicU32, Ordering}; use std::sync::atomic::{AtomicBool, AtomicI64, AtomicU32, Ordering};
use std::time::Duration; use std::time::Duration;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tracing::{debug, error, event, trace}; use tracing::{error, event, info, trace};
use yrs::updates::decoder::Decode; use yrs::updates::decoder::Decode;
use yrs::updates::encoder::Encode; use yrs::updates::encoder::Encode;
use yrs::Update; use yrs::Update;
@ -187,20 +187,35 @@ impl CollabGroup {
/// subscriber /// subscriber
pub async fn is_inactive(&self) -> bool { pub async fn is_inactive(&self) -> bool {
let modified_at = self.broadcast.modified_at.lock(); let modified_at = self.broadcast.modified_at.lock();
// In debug mode, we set the timeout to 60 seconds
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
modified_at.elapsed().as_secs() > 60 && self.subscribers.is_empty() trace!(
"Group:{} is inactive for {} seconds, subscribers: {}",
self.object_id,
modified_at.elapsed().as_secs(),
self.subscribers.len()
);
modified_at.elapsed().as_secs() > 120
} else { } else {
let elapsed_secs = modified_at.elapsed().as_secs(); let elapsed_secs = modified_at.elapsed().as_secs();
const MAXIMUM_SECS: u64 = 60 * 60 * 12; // 12 hours if elapsed_secs > self.timeout_secs() {
if elapsed_secs > MAXIMUM_SECS { // Mark the group as inactive if it has been inactive for more than 3 hours, even if there are subscribers.
debug!( // Otherwise, return true only if there are no subscribers.
"The group:{} is inactive for {} seconds", const MAXIMUM_SECS: u64 = 3 * 60 * 60;
self.object_id, elapsed_secs if elapsed_secs > MAXIMUM_SECS {
); info!(
// If the group is inactive for more than 12 hours, mark it as inactive "Group:{} is inactive for {} seconds, subscribers: {}",
true self.object_id,
modified_at.elapsed().as_secs(),
self.subscribers.len()
);
true
} else {
self.subscribers.is_empty()
}
} else { } else {
elapsed_secs > self.timeout_secs() && self.subscribers.is_empty() false
} }
} }
} }
@ -225,8 +240,8 @@ impl CollabGroup {
fn timeout_secs(&self) -> u64 { fn timeout_secs(&self) -> u64 {
match self.collab_type { match self.collab_type {
CollabType::Document => 10 * 60, // 10 minutes CollabType::Document => 10 * 60, // 10 minutes
CollabType::Database | CollabType::DatabaseRow => 60 * 60, // 1 hour CollabType::Database | CollabType::DatabaseRow => 30 * 60, // 30 minutes
CollabType::WorkspaceDatabase | CollabType::Folder | CollabType::UserAwareness => 2 * 60 * 60, // 2 hours, CollabType::WorkspaceDatabase | CollabType::Folder | CollabType::UserAwareness => 6 * 60 * 60, // 6 hours,
CollabType::Unknown => { CollabType::Unknown => {
10 * 60 // 10 minutes 10 * 60 // 10 minutes
}, },

View File

@ -76,7 +76,7 @@ where
}) })
} }
pub async fn inactive_groups(&self) -> Vec<String> { pub async fn get_inactive_groups(&self) -> Vec<String> {
self.state.get_inactive_group_ids().await self.state.get_inactive_group_ids().await
} }

View File

@ -45,10 +45,8 @@ impl GroupManagementState {
} }
} }
if !inactive_group_ids.is_empty() { for object_id in &inactive_group_ids {
for object_id in &inactive_group_ids { self.remove_group(object_id).await;
self.remove_group(object_id).await;
}
} }
inactive_group_ids inactive_group_ids
} }
@ -123,7 +121,6 @@ impl GroupManagementState {
// Log error if the group doesn't exist // Log error if the group doesn't exist
error!("Group for object_id:{} not found", object_id); error!("Group for object_id:{} not found", object_id);
} }
self.metrics_calculate.num_of_active_collab.store( self.metrics_calculate.num_of_active_collab.store(
self.group_by_object_id.len() as i64, self.group_by_object_id.len() as i64,
std::sync::atomic::Ordering::Relaxed, std::sync::atomic::Ordering::Relaxed,

View File

@ -1,10 +1,10 @@
use anyhow::anyhow;
use async_trait::async_trait; use async_trait::async_trait;
use std::sync::Arc;
use collab::core::collab::MutexCollab; use collab::core::collab::MutexCollab;
use collab_document::document::Document; use collab_document::document::Document;
use collab_document::error::DocumentError; use collab_document::error::DocumentError;
use collab_entity::CollabType; use collab_entity::CollabType;
use std::sync::Arc;
use app_error::AppError; use app_error::AppError;
use appflowy_ai_client::client::AppFlowyAIClient; use appflowy_ai_client::client::AppFlowyAIClient;
@ -27,7 +27,15 @@ impl DocumentIndexer {
fn get_document_contents( fn get_document_contents(
collab: Arc<MutexCollab>, collab: Arc<MutexCollab>,
) -> Result<(String, Vec<AFCollabEmbeddingParams>), DocumentError> { ) -> Result<(String, Vec<AFCollabEmbeddingParams>), DocumentError> {
let object_id = collab.try_lock().unwrap().object_id.clone(); let object_id = collab
.try_lock()
.ok_or_else(|| {
DocumentError::Internal(anyhow!(
"Failed to lock collab when trying to get document content".to_string()
))
})?
.object_id
.clone();
let document = Document::open(collab)?; let document = Document::open(collab)?;
let document_data = document.get_document_data()?; let document_data = document.get_document_data()?;
let content = document_data.to_plain_text(); let content = document_data.to_plain_text();

View File

@ -270,7 +270,8 @@ fn spawn_period_check_inactive_group<S, AC>(
loop { loop {
interval.tick().await; interval.tick().await;
if let Some(groups) = weak_groups.upgrade() { if let Some(groups) = weak_groups.upgrade() {
let inactive_group_ids = groups.inactive_groups().await; let inactive_group_ids = groups.get_inactive_groups().await;
trace!("Inactive group ids: {:?}", inactive_group_ids);
for id in inactive_group_ids { for id in inactive_group_ids {
cloned_group_sender_by_object_id.remove(&id); cloned_group_sender_by_object_id.remove(&id);
} }