chore: shorten group lifetime (#726)
This commit is contained in:
parent
71d292ebcd
commit
73127fb886
|
|
@ -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
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue