mirror of
https://github.com/chatmail/core.git
synced 2026-04-28 02:46:29 +03:00
fix: get_connectivity(): Get rid of locking SchedulerState::inner (#7124)
`get_connectivity()` is expected to return immediately, not when the scheduler finishes updating its state in `start_io()/stop_io()/pause_io()`, otherwise it causes app non-responsiveness. Instead of read-locking `SchedulerState::inner`, store the `ConnectivityStore` collection in `Context` and fetch it from there in `get_connectivity()`. Update it every time we release a write lock on `SchedulerState::inner`.
This commit is contained in:
@@ -272,16 +272,7 @@ impl Context {
|
||||
///
|
||||
/// If the connectivity changes, a DC_EVENT_CONNECTIVITY_CHANGED will be emitted.
|
||||
pub async fn get_connectivity(&self) -> Connectivity {
|
||||
let lock = self.scheduler.inner.read().await;
|
||||
let stores: Vec<_> = match *lock {
|
||||
InnerSchedulerState::Started(ref sched) => sched
|
||||
.boxes()
|
||||
.map(|b| b.conn_state.state.connectivity.clone())
|
||||
.collect(),
|
||||
_ => return Connectivity::NotConnected,
|
||||
};
|
||||
drop(lock);
|
||||
|
||||
let stores = self.connectivities.lock().clone();
|
||||
let mut connectivities = Vec::new();
|
||||
for s in stores {
|
||||
if let Some(connectivity) = s.get_basic().await {
|
||||
@@ -291,7 +282,18 @@ impl Context {
|
||||
connectivities
|
||||
.into_iter()
|
||||
.min()
|
||||
.unwrap_or(Connectivity::Connected)
|
||||
.unwrap_or(Connectivity::NotConnected)
|
||||
}
|
||||
|
||||
pub(crate) fn update_connectivities(&self, sched: &InnerSchedulerState) {
|
||||
let stores: Vec<_> = match sched {
|
||||
InnerSchedulerState::Started(sched) => sched
|
||||
.boxes()
|
||||
.map(|b| b.conn_state.state.connectivity.clone())
|
||||
.collect(),
|
||||
_ => Vec::new(),
|
||||
};
|
||||
*self.connectivities.lock() = stores;
|
||||
}
|
||||
|
||||
/// Get an overview of the current connectivity, and possibly more statistics.
|
||||
|
||||
Reference in New Issue
Block a user