[fractal] In sync: wait longer, if 429 (Too Many Requests)



commit b39293aa4362ea211313ae625f346559236b83a6
Author: Sonja Heinze <sonjaleaheinze gmail com>
Date:   Sun May 24 21:13:33 2020 +0200

    In sync: wait longer, if 429 (Too Many Requests)
    
    Before, Fractal would always wait for 10 seconds when the sync request
    failed. With this commit, the time Fractal waits before the next request
    increases exponentially, if the error is a 429 (Too Many Requests) error.

 fractal-gtk/src/app/backend_loop.rs     |  8 +++++---
 fractal-gtk/src/appop/login.rs          |  2 +-
 fractal-gtk/src/appop/message.rs        |  3 ++-
 fractal-gtk/src/appop/sync.rs           |  9 +++++----
 fractal-matrix-api/src/backend/mod.rs   | 12 ++++++++++--
 fractal-matrix-api/src/backend/sync.rs  | 26 +++++++++++++++++++++++---
 fractal-matrix-api/src/backend/types.rs |  4 ++--
 7 files changed, 48 insertions(+), 16 deletions(-)
---
diff --git a/fractal-gtk/src/app/backend_loop.rs b/fractal-gtk/src/app/backend_loop.rs
index 3e1c6e85..47b39c20 100644
--- a/fractal-gtk/src/app/backend_loop.rs
+++ b/fractal-gtk/src/app/backend_loop.rs
@@ -54,7 +54,8 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                 BKResponse::SentMsg(Ok((txid, evid))) => {
                     APPOP!(msg_sent, (txid, evid));
                     let initial = false;
-                    APPOP!(sync, (initial));
+                    let number_tries = 0;
+                    APPOP!(sync, (initial, number_tries));
                 }
                 BKResponse::DirectorySearch(Ok(rooms)) => {
                     APPOP!(append_directory_rooms, (rooms));
@@ -220,13 +221,14 @@ pub fn backend_loop(rx: Receiver<BKResponse>) {
                     APPOP!(reset_directory_state);
                     APPOP!(show_error, (error));
                 }
-                BKResponse::Sync(Err(err)) => {
+                BKResponse::Sync(Err((err, number_tries))) => {
                     let err_str = format!("{:?}", err);
                     error!(
                         "SYNC Error: {}",
                         remove_matrix_access_token_if_present(&err_str).unwrap_or(err_str)
                     );
-                    APPOP!(sync_error);
+                    let new_number_tries = number_tries + 1;
+                    APPOP!(sync_error, (new_number_tries));
                 }
                 err => {
                     let err_str = format!("{:?}", err);
diff --git a/fractal-gtk/src/appop/login.rs b/fractal-gtk/src/appop/login.rs
index 9e91c928..aab14d11 100644
--- a/fractal-gtk/src/appop/login.rs
+++ b/fractal-gtk/src/appop/login.rs
@@ -56,7 +56,7 @@ impl AppOp {
 
         // initial sync, we're shoing some feedback to the user
         self.initial_sync(true);
-        self.sync(true);
+        self.sync(true, 0);
         self.init_protocols();
     }
 
diff --git a/fractal-gtk/src/appop/message.rs b/fractal-gtk/src/appop/message.rs
index 876b317d..1ae5c23b 100644
--- a/fractal-gtk/src/appop/message.rs
+++ b/fractal-gtk/src/appop/message.rs
@@ -216,7 +216,8 @@ impl AppOp {
                             Ok((txid, evid)) => {
                                 APPOP!(msg_sent, (txid, evid));
                                 let initial = false;
-                                APPOP!(sync, (initial));
+                                let number_tries = 0;
+                                APPOP!(sync, (initial, number_tries));
                             }
                             Err(err) => {
                                 tx.send(BKCommand::SendBKResponse(BKResponse::SentMsg(Err(err))))
diff --git a/fractal-gtk/src/appop/sync.rs b/fractal-gtk/src/appop/sync.rs
index e508ddf0..ed6b0d56 100644
--- a/fractal-gtk/src/appop/sync.rs
+++ b/fractal-gtk/src/appop/sync.rs
@@ -13,7 +13,7 @@ impl AppOp {
         }
     }
 
-    pub fn sync(&mut self, initial: bool) {
+    pub fn sync(&mut self, initial: bool, number_tries: u64) {
         if let (Some(login_data), true) = (self.login_data.clone(), !self.syncing) {
             self.syncing = true;
             // for the initial sync we set the since to None to avoid long syncing
@@ -28,6 +28,7 @@ impl AppOp {
                     login_data.uid,
                     since,
                     initial,
+                    number_tries,
                 ))
                 .unwrap();
         }
@@ -36,12 +37,12 @@ impl AppOp {
     pub fn synced(&mut self, since: Option<String>) {
         self.syncing = false;
         self.since = since;
-        self.sync(false);
+        self.sync(false, 0);
         self.initial_sync(false);
     }
 
-    pub fn sync_error(&mut self) {
+    pub fn sync_error(&mut self, number_tries: u64) {
         self.syncing = false;
-        self.sync(false);
+        self.sync(false, number_tries);
     }
 }
diff --git a/fractal-matrix-api/src/backend/mod.rs b/fractal-matrix-api/src/backend/mod.rs
index 61979f15..4ca9df3f 100644
--- a/fractal-matrix-api/src/backend/mod.rs
+++ b/fractal-matrix-api/src/backend/mod.rs
@@ -75,8 +75,16 @@ impl Backend {
             }
 
             // Sync module
-            Ok(BKCommand::Sync(server, access_token, uid, since, initial)) => {
-                sync::sync(self, server, access_token, uid, since, initial)
+            Ok(BKCommand::Sync(server, access_token, uid, since, initial, number_tries)) => {
+                sync::sync(
+                    self,
+                    server,
+                    access_token,
+                    uid,
+                    since,
+                    initial,
+                    number_tries,
+                )
             }
 
             // Room module
diff --git a/fractal-matrix-api/src/backend/sync.rs b/fractal-matrix-api/src/backend/sync.rs
index b9e901f7..3077c226 100644
--- a/fractal-matrix-api/src/backend/sync.rs
+++ b/fractal-matrix-api/src/backend/sync.rs
@@ -1,6 +1,7 @@
 use crate::backend::types::BKResponse;
 use crate::backend::types::Backend;
 use crate::client::ProxySettings;
+use crate::error::Error;
 use crate::globals;
 use crate::r0::filter::EventFilter;
 use crate::r0::filter::Filter;
@@ -40,6 +41,7 @@ pub fn sync(
     user_id: UserId,
     since: Option<String>,
     initial: bool,
+    number_tries: u64,
 ) {
     let tx = bk.tx.clone();
     let data = bk.data.clone();
@@ -265,10 +267,28 @@ pub fn sync(
             }
             Err(err) => {
                 // we wait if there's an error to avoid 100% CPU
-                error!("Sync Error, waiting 10 seconds to respond for the next sync");
-                thread::sleep(time::Duration::from_secs(10));
+                // we wait even longer, if it's a 429 (Too Many Requests) error
+                let waiting_time =
+                // Once the Rust issue https://github.com/rust-lang/rust/issues/53667 is resolved, we can 
hopefully write 
+                // if let Error::NetworkError(status) = err && status.as_u16() == 429
+                    if let Error::NetworkError(status) = err {
+                        if status.as_u16() == 429 {
+                            10 * 2_u64.pow(number_tries.try_into().expect(
+                                "The number of sync tries couldn't be transformed into a u32.",
+                            ))
+                        } else {
+                            10
+                        }
+                    } else {
+                        10
+                    };
+                error!(
+                    "Sync Error, waiting {:?} seconds to respond for the next sync",
+                    waiting_time
+                );
+                thread::sleep(time::Duration::from_secs(waiting_time));
 
-                tx.send(BKResponse::Sync(Err(err)))
+                tx.send(BKResponse::Sync(Err((err, number_tries))))
                     .expect_log("Connection closed");
             }
         }
diff --git a/fractal-matrix-api/src/backend/types.rs b/fractal-matrix-api/src/backend/types.rs
index cc197500..f47ce1b4 100644
--- a/fractal-matrix-api/src/backend/types.rs
+++ b/fractal-matrix-api/src/backend/types.rs
@@ -20,7 +20,7 @@ pub enum BKCommand {
     Login(String, String, Url, Url),
     Register(String, String, Url, Url),
     Guest(Url, Url),
-    Sync(Url, AccessToken, UserId, Option<String>, bool),
+    Sync(Url, AccessToken, UserId, Option<String>, bool, u64),
     GetThumbAsync(Url, String, Sender<Result<String, Error>>),
     GetMediaAsync(Url, String, Sender<Result<String, Error>>),
     GetMediaListAsync(
@@ -47,7 +47,7 @@ pub enum BKCommand {
 pub enum BKResponse {
     ShutDown,
     Token(UserId, AccessToken, Option<String>, Url, Url),
-    Sync(Result<String, Error>),
+    Sync(Result<String, (Error, u64)>),
     Rooms(Result<(Vec<Room>, Option<Room>), Error>),
     UpdateRooms(Result<Vec<Room>, Error>),
     RoomDetail(Result<(RoomId, String, String), Error>),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]