mirror of
https://github.com/chatmail/core.git
synced 2026-04-28 10:56:29 +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
|
||||
);
|
||||
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;
|
||||
info!(
|
||||
context,
|
||||
@@ -1170,15 +1170,24 @@ async fn perform_job_action(
|
||||
try_res
|
||||
}
|
||||
|
||||
fn get_backoff_time_offset(tries: u32) -> i64 {
|
||||
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;
|
||||
fn get_backoff_time_offset(tries: u32, action: Action) -> i64 {
|
||||
match action {
|
||||
// Just try every 10s to update the quota
|
||||
// If all retries are exhausted, a new job will be created when the quota information is needed
|
||||
Action::UpdateRecentQuota => 10,
|
||||
|
||||
_ => {
|
||||
// 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<()> {
|
||||
|
||||
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 {
|
||||
// Adds a job to update `quota.recent`
|
||||
pub(crate) async fn schedule_quota_update(&self) -> Result<()> {
|
||||
job::kill_action(self, Action::UpdateRecentQuota).await?;
|
||||
job::add(
|
||||
self,
|
||||
job::Job::new(Action::UpdateRecentQuota, 0, Params::new(), 0),
|
||||
)
|
||||
.await?;
|
||||
if !job::action_exists(self, Action::UpdateRecentQuota).await? {
|
||||
job::add(
|
||||
self,
|
||||
job::Job::new(Action::UpdateRecentQuota, 0, Params::new(), 0),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user