mirror of
https://github.com/chatmail/core.git
synced 2026-05-07 08:56:30 +03:00
Fix: Don't update quota in an endless loop (#2726)
The problem was: When opening the connectivity view while there is no network, get_connectivity_html() calls schedule_quota_update(), which schedules a UpdateRecentQuota job. But in update_recent_quota(), connecting fails and a ConnectivityChanged event is emitted (connectivity changes from Error to Connecting and back). Therefore the UI calls get_connectivity_html() again, and the loop is complete. This made the UI completely unresponsible. To reproduce, just turn wi-fi off and open the connectivity view. The fix is: schedule_quota_update() now only schedules a new job if there is no old job. To prevent the possible (though probably unlikely) problem that an old quota update job has a backoff of, like, a day and therefore quota is not updated, I reduced the backoff time for quota jobs to 10s. Fixes possibly https://github.com/deltachat/deltachat-android/issues/2043, but we should "re-try" this
This commit is contained in:
27
src/job.rs
27
src/job.rs
@@ -1084,7 +1084,7 @@ pub(crate) async fn perform_job(context: &Context, mut connection: Connection<'_
|
|||||||
"{} thread increases job {} tries to {}", &connection, job, tries
|
"{} thread increases job {} tries to {}", &connection, job, tries
|
||||||
);
|
);
|
||||||
job.tries = tries;
|
job.tries = tries;
|
||||||
let time_offset = get_backoff_time_offset(tries);
|
let time_offset = get_backoff_time_offset(tries, job.action);
|
||||||
job.desired_timestamp = time() + time_offset;
|
job.desired_timestamp = time() + time_offset;
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
@@ -1170,15 +1170,24 @@ async fn perform_job_action(
|
|||||||
try_res
|
try_res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_backoff_time_offset(tries: u32) -> i64 {
|
fn get_backoff_time_offset(tries: u32, action: Action) -> i64 {
|
||||||
let n = 2_i32.pow(tries - 1) * 60;
|
match action {
|
||||||
let mut rng = thread_rng();
|
// Just try every 10s to update the quota
|
||||||
let r: i32 = rng.gen();
|
// If all retries are exhausted, a new job will be created when the quota information is needed
|
||||||
let mut seconds = r % (n + 1);
|
Action::UpdateRecentQuota => 10,
|
||||||
if seconds < 1 {
|
|
||||||
seconds = 1;
|
_ => {
|
||||||
|
// Exponential backoff
|
||||||
|
let n = 2_i32.pow(tries - 1) * 60;
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
let r: i32 = rng.gen();
|
||||||
|
let mut seconds = r % (n + 1);
|
||||||
|
if seconds < 1 {
|
||||||
|
seconds = 1;
|
||||||
|
}
|
||||||
|
seconds as i64
|
||||||
|
}
|
||||||
}
|
}
|
||||||
seconds as i64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_mdn(context: &Context, msg: &Message) -> Result<()> {
|
async fn send_mdn(context: &Context, msg: &Message) -> Result<()> {
|
||||||
|
|||||||
13
src/quota.rs
13
src/quota.rs
@@ -110,12 +110,13 @@ pub fn needs_quota_warning(curr_percentage: u64, warned_at_percentage: u64) -> b
|
|||||||
impl Context {
|
impl Context {
|
||||||
// Adds a job to update `quota.recent`
|
// Adds a job to update `quota.recent`
|
||||||
pub(crate) async fn schedule_quota_update(&self) -> Result<()> {
|
pub(crate) async fn schedule_quota_update(&self) -> Result<()> {
|
||||||
job::kill_action(self, Action::UpdateRecentQuota).await?;
|
if !job::action_exists(self, Action::UpdateRecentQuota).await? {
|
||||||
job::add(
|
job::add(
|
||||||
self,
|
self,
|
||||||
job::Job::new(Action::UpdateRecentQuota, 0, Params::new(), 0),
|
job::Job::new(Action::UpdateRecentQuota, 0, Params::new(), 0),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user