[evolution-data-server/gnome-3-36] I#101 - DAV backends: Limit server requests after getting online



commit a1aca75596b1b1dd3b4adde9684b68f1e2816840
Author: Milan Crha <mcrha redhat com>
Date:   Thu May 14 15:27:42 2020 +0200

    I#101 - DAV backends: Limit server requests after getting online
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/101

 .../backends/carddav/e-book-backend-carddav.c      | 43 ++++++++++++++++++++--
 .../libedata-book/e-book-meta-backend.c            | 17 +++++++--
 .../backends/caldav/e-cal-backend-caldav.c         | 41 +++++++++++++++++++--
 src/calendar/libedata-cal/e-cal-meta-backend.c     | 17 +++++++--
 4 files changed, 104 insertions(+), 14 deletions(-)
---
diff --git a/src/addressbook/backends/carddav/e-book-backend-carddav.c 
b/src/addressbook/backends/carddav/e-book-backend-carddav.c
index f1cf3ccf7..eff4d0bde 100644
--- a/src/addressbook/backends/carddav/e-book-backend-carddav.c
+++ b/src/addressbook/backends/carddav/e-book-backend-carddav.c
@@ -41,6 +41,10 @@ struct _EBookBackendCardDAVPrivate {
        EWebDAVSession *webdav;
        GMutex webdav_lock;
 
+       /* If already been connected, then the connect_sync() will relax server checks,
+          to avoid unnecessary requests towards the server. */
+       gboolean been_connected;
+
        /* support for 'getctag' extension */
        gboolean ctag_supported;
 
@@ -106,13 +110,21 @@ ebb_carddav_connect_sync (EBookMetaBackend *meta_backend,
                webdav, "proxy-resolver",
                G_BINDING_SYNC_CREATE);
 
-       /* Thinks the 'getctag' extension is available the first time, but unset it when realizes it isn't. */
-       bbdav->priv->ctag_supported = TRUE;
-
        e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTING);
 
        e_soup_session_set_credentials (E_SOUP_SESSION (webdav), credentials);
 
+       if (bbdav->priv->been_connected) {
+               g_mutex_lock (&bbdav->priv->webdav_lock);
+               bbdav->priv->webdav = webdav;
+               g_mutex_unlock (&bbdav->priv->webdav_lock);
+
+               return TRUE;
+       }
+
+       /* Thinks the 'getctag' extension is available the first time, but unset it when realizes it isn't. */
+       bbdav->priv->ctag_supported = TRUE;
+
        success = e_webdav_session_options_sync (webdav, NULL,
                &capabilities, &allows, cancellable, &local_error);
 
@@ -233,7 +245,7 @@ ebb_carddav_connect_sync (EBookMetaBackend *meta_backend,
                   authorized (aka without credentials), thus try something
                   more aggressive, just in case.
 
-                  The 'getctag' extension is not required, thuch check
+                  The 'getctag' extension is not required, thus check
                   for unauthorized error only. */
                if (!e_webdav_session_getctag_sync (webdav, NULL, &ctag, cancellable, &local_error) &&
                    g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
@@ -302,6 +314,7 @@ ebb_carddav_connect_sync (EBookMetaBackend *meta_backend,
                g_mutex_lock (&bbdav->priv->webdav_lock);
                bbdav->priv->webdav = webdav;
                g_mutex_unlock (&bbdav->priv->webdav_lock);
+               bbdav->priv->been_connected = TRUE;
        } else {
                if (success) {
                        e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
@@ -642,6 +655,8 @@ ebb_carddav_check_credentials_error (EBookBackendCardDAV *bbdav,
                op_error->domain = E_CLIENT_ERROR;
                op_error->code = E_CLIENT_ERROR_AUTHENTICATION_REQUIRED;
 
+               bbdav->priv->been_connected = FALSE;
+
                if (webdav) {
                        ENamedParameters *credentials;
                        gboolean empty_credentials;
@@ -1344,6 +1359,22 @@ ebb_carddav_get_backend_property (EBookBackend *book_backend,
        return E_BOOK_BACKEND_CLASS (e_book_backend_carddav_parent_class)->impl_get_backend_property 
(book_backend, prop_name);
 }
 
+static gboolean
+ebb_carddav_refresh_sync (EBookBackendSync *sync_backend,
+                         GCancellable *cancellable,
+                         GError **error)
+{
+       EBookBackendCardDAV *bbdav;
+
+       g_return_val_if_fail (E_IS_BOOK_BACKEND_CARDDAV (sync_backend), FALSE);
+
+       bbdav = E_BOOK_BACKEND_CARDDAV (sync_backend);
+       bbdav->priv->been_connected = FALSE;
+
+       /* Chain up to parent's method. */
+       return E_BOOK_BACKEND_SYNC_CLASS (e_book_backend_carddav_parent_class)->refresh_sync (sync_backend, 
cancellable, error);
+}
+
 static gchar *
 ebb_carddav_dup_contact_revision_cb (EBookCache *book_cache,
                                     EContact *contact)
@@ -1407,6 +1438,7 @@ e_book_backend_carddav_class_init (EBookBackendCardDAVClass *klass)
 {
        GObjectClass *object_class;
        EBookBackendClass *book_backend_class;
+       EBookBackendSyncClass *book_backend_sync_class;
        EBookMetaBackendClass *book_meta_backend_class;
 
        book_meta_backend_class = E_BOOK_META_BACKEND_CLASS (klass);
@@ -1421,6 +1453,9 @@ e_book_backend_carddav_class_init (EBookBackendCardDAVClass *klass)
        book_meta_backend_class->remove_contact_sync = ebb_carddav_remove_contact_sync;
        book_meta_backend_class->get_ssl_error_details = ebb_carddav_get_ssl_error_details;
 
+       book_backend_sync_class = E_BOOK_BACKEND_SYNC_CLASS (klass);
+       book_backend_sync_class->refresh_sync = ebb_carddav_refresh_sync;
+
        book_backend_class = E_BOOK_BACKEND_CLASS (klass);
        book_backend_class->impl_get_backend_property = ebb_carddav_get_backend_property;
 
diff --git a/src/addressbook/libedata-book/e-book-meta-backend.c 
b/src/addressbook/libedata-book/e-book-meta-backend.c
index 200c5e7ca..ea79511fe 100644
--- a/src/addressbook/libedata-book/e-book-meta-backend.c
+++ b/src/addressbook/libedata-book/e-book-meta-backend.c
@@ -81,6 +81,7 @@ struct _EBookMetaBackendPrivate {
        gboolean refresh_after_authenticate;
        gint ever_connected;
        gint connected_writable;
+       gint64 last_refresh_time;       /* The time when the last refresh was called */
 
        /* Last successful connect data, for some extensions */
        guint16 authentication_port;
@@ -874,6 +875,8 @@ ebmb_refresh_internal_sync (EBookMetaBackend *meta_backend,
 
        ebmb_ensure_refresh_timeout_set_locked (meta_backend);
 
+       meta_backend->priv->last_refresh_time = g_get_real_time ();
+
        g_mutex_unlock (&meta_backend->priv->property_lock);
 
        e_book_backend_foreach_view_notify_progress (E_BOOK_BACKEND (meta_backend), TRUE, 0, NULL);
@@ -2198,10 +2201,18 @@ ebmb_notify_online_cb (GObject *object,
 
        meta_backend->priv->current_online_state = new_value;
 
-       if (new_value)
-               e_book_meta_backend_schedule_refresh (meta_backend);
-       else
+       if (new_value) {
+               gint64 now = g_get_real_time ();
+
+               /* Do not auto-run refresh (due to getting online) more than once per hour */
+               if (now - meta_backend->priv->last_refresh_time >= G_USEC_PER_SEC * 60L * 60L) {
+                       meta_backend->priv->last_refresh_time = now;
+
+                       e_book_meta_backend_schedule_refresh (meta_backend);
+               }
+       } else {
                ebmb_schedule_go_offline (meta_backend);
+       }
 }
 
 static void
diff --git a/src/calendar/backends/caldav/e-cal-backend-caldav.c 
b/src/calendar/backends/caldav/e-cal-backend-caldav.c
index 002e6c77e..5da655c82 100644
--- a/src/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/src/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -38,6 +38,10 @@ struct _ECalBackendCalDAVPrivate {
        EWebDAVSession *webdav;
        GMutex webdav_lock;
 
+       /* If already been connected, then the connect_sync() will relax server checks,
+          to avoid unnecessary requests towards the server. */
+       gboolean been_connected;
+
        /* support for 'getctag' extension */
        gboolean ctag_supported;
 
@@ -142,13 +146,21 @@ ecb_caldav_connect_sync (ECalMetaBackend *meta_backend,
                webdav, "proxy-resolver",
                G_BINDING_SYNC_CREATE);
 
-       /* Thinks the 'getctag' extension is available the first time, but unset it when realizes it isn't. */
-       cbdav->priv->ctag_supported = TRUE;
-
        e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTING);
 
        e_soup_session_set_credentials (E_SOUP_SESSION (webdav), credentials);
 
+       if (cbdav->priv->been_connected) {
+               g_mutex_lock (&cbdav->priv->webdav_lock);
+               cbdav->priv->webdav = webdav;
+               g_mutex_unlock (&cbdav->priv->webdav_lock);
+
+               return TRUE;
+       }
+
+       /* Thinks the 'getctag' extension is available the first time, but unset it when realizes it isn't. */
+       cbdav->priv->ctag_supported = TRUE;
+
        success = e_webdav_session_options_sync (webdav, NULL,
                &capabilities, &allows, cancellable, &local_error);
 
@@ -219,7 +231,7 @@ ecb_caldav_connect_sync (ECalMetaBackend *meta_backend,
                   authorized (aka without credentials), thus try something
                   more aggressive, just in case.
 
-                  The 'getctag' extension is not required, thuch check
+                  The 'getctag' extension is not required, thus check
                   for unauthorized error only. */
                if (!e_webdav_session_getctag_sync (webdav, NULL, &ctag, cancellable, &local_error) &&
                    g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
@@ -286,6 +298,7 @@ ecb_caldav_connect_sync (ECalMetaBackend *meta_backend,
                g_mutex_lock (&cbdav->priv->webdav_lock);
                cbdav->priv->webdav = webdav;
                g_mutex_unlock (&cbdav->priv->webdav_lock);
+               cbdav->priv->been_connected = TRUE;
        } else {
                if (success) {
                        e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
@@ -783,6 +796,8 @@ ecb_caldav_check_credentials_error (ECalBackendCalDAV *cbdav,
                op_error->domain = E_CLIENT_ERROR;
                op_error->code = E_CLIENT_ERROR_AUTHENTICATION_REQUIRED;
 
+               cbdav->priv->been_connected = FALSE;
+
                if (webdav) {
                        ENamedParameters *credentials;
                        gboolean empty_credentials;
@@ -2277,6 +2292,23 @@ ecb_caldav_notify_property_changed_cb (GObject *object,
        }
 }
 
+static void
+ecb_caldav_refresh_sync (ECalBackendSync *sync_backend,
+                        EDataCal *cal,
+                        GCancellable *cancellable,
+                        GError **error)
+{
+       ECalBackendCalDAV *cbdav;
+
+       g_return_if_fail (E_IS_CAL_BACKEND_CALDAV (sync_backend));
+
+       cbdav = E_CAL_BACKEND_CALDAV (sync_backend);
+       cbdav->priv->been_connected = FALSE;
+
+       /* Chain up to parent's method. */
+       E_CAL_BACKEND_SYNC_CLASS (e_cal_backend_caldav_parent_class)->refresh_sync (sync_backend, cal, 
cancellable, error);
+}
+
 static gchar *
 ecb_caldav_dup_component_revision_cb (ECalCache *cal_cache,
                                      ICalComponent *icomp)
@@ -2368,6 +2400,7 @@ e_cal_backend_caldav_class_init (ECalBackendCalDAVClass *klass)
        cal_meta_backend_class->get_ssl_error_details = ecb_caldav_get_ssl_error_details;
 
        cal_backend_sync_class = E_CAL_BACKEND_SYNC_CLASS (klass);
+       cal_backend_sync_class->refresh_sync = ecb_caldav_refresh_sync;
        cal_backend_sync_class->get_free_busy_sync = ecb_caldav_get_free_busy_sync;
 
        cal_backend_class = E_CAL_BACKEND_CLASS (klass);
diff --git a/src/calendar/libedata-cal/e-cal-meta-backend.c b/src/calendar/libedata-cal/e-cal-meta-backend.c
index 8c89237ef..37fa03731 100644
--- a/src/calendar/libedata-cal/e-cal-meta-backend.c
+++ b/src/calendar/libedata-cal/e-cal-meta-backend.c
@@ -79,6 +79,7 @@ struct _ECalMetaBackendPrivate {
        gboolean refresh_after_authenticate;
        gint ever_connected;
        gint connected_writable;
+       gint64 last_refresh_time;       /* The time when the last refresh was called */
 
        /* Last successful connect data, for some extensions */
        guint16 authentication_port;
@@ -776,6 +777,8 @@ ecmb_refresh_internal_sync (ECalMetaBackend *meta_backend,
 
        ecmb_ensure_refresh_timeout_set_locked (meta_backend);
 
+       meta_backend->priv->last_refresh_time = g_get_real_time ();
+
        g_mutex_unlock (&meta_backend->priv->property_lock);
 
        e_cal_backend_foreach_view_notify_progress (E_CAL_BACKEND (meta_backend), TRUE, 0, NULL);
@@ -3097,10 +3100,18 @@ ecmb_notify_online_cb (GObject *object,
 
        meta_backend->priv->current_online_state = new_value;
 
-       if (new_value)
-               e_cal_meta_backend_schedule_refresh (meta_backend);
-       else
+       if (new_value) {
+               gint64 now = g_get_real_time ();
+
+               /* Do not auto-run refresh (due to getting online) more than once per hour */
+               if (now - meta_backend->priv->last_refresh_time >= G_USEC_PER_SEC * 60L * 60L) {
+                       meta_backend->priv->last_refresh_time = now;
+
+                       e_cal_meta_backend_schedule_refresh (meta_backend);
+               }
+       } else {
                ecmb_schedule_go_offline (meta_backend);
+       }
 }
 
 static void


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