mirror of
https://github.com/chatmail/core.git
synced 2026-05-20 07:16:31 +03:00
Use sync RwLock for debug_logging
This avoids the need for potentially expensive block_in_place(), but is unlikely to actually block the thread as holding write lock is rare.
This commit is contained in:
@@ -243,7 +243,10 @@ pub struct InnerContext {
|
|||||||
pub(crate) last_error: std::sync::RwLock<String>,
|
pub(crate) last_error: std::sync::RwLock<String>,
|
||||||
|
|
||||||
/// If debug logging is enabled, this contains all necessary information
|
/// If debug logging is enabled, this contains all necessary information
|
||||||
pub(crate) debug_logging: RwLock<Option<DebugLogging>>,
|
///
|
||||||
|
/// Standard RwLock instead of [`tokio::sync::RwLock`] is used
|
||||||
|
/// because the lock is used from synchronous [`Context::emit_event`].
|
||||||
|
pub(crate) debug_logging: std::sync::RwLock<Option<DebugLogging>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The state of ongoing process.
|
/// The state of ongoing process.
|
||||||
@@ -382,7 +385,7 @@ impl Context {
|
|||||||
creation_time: std::time::SystemTime::now(),
|
creation_time: std::time::SystemTime::now(),
|
||||||
last_full_folder_scan: Mutex::new(None),
|
last_full_folder_scan: Mutex::new(None),
|
||||||
last_error: std::sync::RwLock::new("".to_string()),
|
last_error: std::sync::RwLock::new("".to_string()),
|
||||||
debug_logging: RwLock::new(None),
|
debug_logging: std::sync::RwLock::new(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ctx = Context {
|
let ctx = Context {
|
||||||
@@ -438,7 +441,7 @@ impl Context {
|
|||||||
/// Emits a single event.
|
/// Emits a single event.
|
||||||
pub fn emit_event(&self, event: EventType) {
|
pub fn emit_event(&self, event: EventType) {
|
||||||
{
|
{
|
||||||
let lock = tokio::task::block_in_place(|| self.debug_logging.blocking_read());
|
let lock = self.debug_logging.read().expect("RwLock is poisoned");
|
||||||
if let Some(debug_logging) = &*lock {
|
if let Some(debug_logging) = &*lock {
|
||||||
debug_logging.log_event(event.clone());
|
debug_logging.log_event(event.clone());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ pub(crate) async fn set_debug_logging_xdc(ctx: &Context, id: Option<MsgId>) -> a
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
{
|
{
|
||||||
let debug_logging = &mut *ctx.debug_logging.write().await;
|
let debug_logging = &mut *ctx.debug_logging.write().expect("RwLock is poisoned");
|
||||||
match debug_logging {
|
match debug_logging {
|
||||||
// Switch logging xdc
|
// Switch logging xdc
|
||||||
Some(debug_logging) => debug_logging.msg_id = msg_id,
|
Some(debug_logging) => debug_logging.msg_id = msg_id,
|
||||||
@@ -162,7 +162,7 @@ pub(crate) async fn set_debug_logging_xdc(ctx: &Context, id: Option<MsgId>) -> a
|
|||||||
ctx.sql
|
ctx.sql
|
||||||
.set_raw_config(Config::DebugLogging.as_ref(), None)
|
.set_raw_config(Config::DebugLogging.as_ref(), None)
|
||||||
.await?;
|
.await?;
|
||||||
*ctx.debug_logging.write().await = None;
|
*ctx.debug_logging.write().expect("RwLock is poisoned") = None;
|
||||||
info!(ctx, "removing logging webxdc");
|
info!(ctx, "removing logging webxdc");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1425,7 +1425,7 @@ pub async fn delete_msgs(context: &Context, msg_ids: &[MsgId]) -> Result<()> {
|
|||||||
let logging_xdc_id = context
|
let logging_xdc_id = context
|
||||||
.debug_logging
|
.debug_logging
|
||||||
.read()
|
.read()
|
||||||
.await
|
.expect("RwLock is poisoned")
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|dl| dl.msg_id);
|
.map(|dl| dl.msg_id);
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,12 @@ impl SchedulerState {
|
|||||||
// to allow for clean shutdown.
|
// to allow for clean shutdown.
|
||||||
context.new_msgs_notify.notify_one();
|
context.new_msgs_notify.notify_one();
|
||||||
|
|
||||||
if let Some(debug_logging) = context.debug_logging.read().await.as_ref() {
|
if let Some(debug_logging) = context
|
||||||
|
.debug_logging
|
||||||
|
.read()
|
||||||
|
.expect("RwLock is poisoned")
|
||||||
|
.as_ref()
|
||||||
|
{
|
||||||
debug_logging.loop_handle.abort();
|
debug_logging.loop_handle.abort();
|
||||||
}
|
}
|
||||||
let prev_state = std::mem::replace(&mut *inner, new_state);
|
let prev_state = std::mem::replace(&mut *inner, new_state);
|
||||||
|
|||||||
@@ -2466,9 +2466,9 @@ sth_for_the = "future""#
|
|||||||
include_bytes!("../test-data/webxdc/minimal.xdc"),
|
include_bytes!("../test-data/webxdc/minimal.xdc"),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
assert!(alice.debug_logging.read().await.is_none());
|
assert!(alice.debug_logging.read().unwrap().is_none());
|
||||||
send_msg(&alice, chat_id, &mut instance).await?;
|
send_msg(&alice, chat_id, &mut instance).await?;
|
||||||
assert!(alice.debug_logging.read().await.is_some());
|
assert!(alice.debug_logging.read().unwrap().is_some());
|
||||||
|
|
||||||
alice.emit_event(EventType::Info("hi".to_string()));
|
alice.emit_event(EventType::Info("hi".to_string()));
|
||||||
alice
|
alice
|
||||||
|
|||||||
Reference in New Issue
Block a user