[evolution-ews] Bug 731454 - Add option to set number of concurrent connections to use



commit 50cb00c75ab93682f3b85f1ae05fd6ec197492f4
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jan 16 09:02:50 2020 +0100

    Bug 731454 - Add option to set number of concurrent connections to use
    
    Closes https://bugzilla.gnome.org/show_bug.cgi?id=731454

 src/camel/camel-ews-provider.c  |  2 ++
 src/server/camel-ews-settings.c | 59 ++++++++++++++++++++++++++++++-
 src/server/camel-ews-settings.h |  8 +++++
 src/server/e-ews-connection.c   | 78 +++++++++++++++++++++++++++++++++++++----
 4 files changed, 140 insertions(+), 7 deletions(-)
---
diff --git a/src/camel/camel-ews-provider.c b/src/camel/camel-ews-provider.c
index a5fac675..3b10de48 100644
--- a/src/camel/camel-ews-provider.c
+++ b/src/camel/camel-ews-provider.c
@@ -70,6 +70,8 @@ static CamelProviderConfEntry ews_conf_entries[] = {
          /* Translators: '%s' is preplaced with a widget, where "
           * user can select how long the timeout should be. */
          N_("Connection _timeout (in seconds) %s"), "0:1:0:32768" },
+       { CAMEL_PROVIDER_CONF_CHECKSPIN, "concurrent-connections", NULL,
+         N_("Numbe_r of concurrent connections to use"), "y:1:1:7" },
        { CAMEL_PROVIDER_CONF_CHECKBOX, "override-user-agent", NULL,
          N_("Override _User-Agent header value"), "0" },
        { CAMEL_PROVIDER_CONF_ENTRY, "user-agent", "override-user-agent", "" },
diff --git a/src/server/camel-ews-settings.c b/src/server/camel-ews-settings.c
index 8f0e3714..13ed56f9 100644
--- a/src/server/camel-ews-settings.c
+++ b/src/server/camel-ews-settings.c
@@ -41,6 +41,7 @@ struct _CamelEwsSettingsPrivate {
        gchar *oaburl;
        gchar *oal_selected;
        guint timeout;
+       guint concurrent_connections;
        gchar *impersonate_user;
        gboolean override_user_agent;
        gchar *user_agent;
@@ -76,7 +77,8 @@ enum {
        PROP_OAUTH2_TENANT,
        PROP_OAUTH2_CLIENT_ID,
        PROP_OAUTH2_REDIRECT_URI,
-       PROP_SHOW_PUBLIC_FOLDERS
+       PROP_SHOW_PUBLIC_FOLDERS,
+       PROP_CONCURRENT_CONNECTIONS
 };
 
 G_DEFINE_TYPE_WITH_CODE (
@@ -271,6 +273,12 @@ ews_settings_set_property (GObject *object,
                                CAMEL_EWS_SETTINGS (object),
                                g_value_get_boolean (value));
                        return;
+
+               case PROP_CONCURRENT_CONNECTIONS:
+                       camel_ews_settings_set_concurrent_connections (
+                               CAMEL_EWS_SETTINGS (object),
+                               g_value_get_uint (value));
+                       return;
        }
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -457,6 +465,13 @@ ews_settings_get_property (GObject *object,
                                camel_ews_settings_get_show_public_folders (
                                CAMEL_EWS_SETTINGS (object)));
                        return;
+
+               case PROP_CONCURRENT_CONNECTIONS:
+                       g_value_set_uint (
+                               value,
+                               camel_ews_settings_get_concurrent_connections (
+                               CAMEL_EWS_SETTINGS (object)));
+                       return;
        }
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -767,6 +782,21 @@ camel_ews_settings_class_init (CamelEwsSettingsClass *class)
                        G_PARAM_READWRITE |
                        G_PARAM_CONSTRUCT |
                        G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (
+               object_class,
+               PROP_CONCURRENT_CONNECTIONS,
+               g_param_spec_uint (
+                       "concurrent-connections",
+                       "Concurrent Connections",
+                       "Number of concurrent connections to use",
+                       MIN_CONCURRENT_CONNECTIONS,
+                       MAX_CONCURRENT_CONNECTIONS,
+                       1,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT |
+                       G_PARAM_EXPLICIT_NOTIFY |
+                       G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -1592,3 +1622,30 @@ camel_ews_settings_set_show_public_folders (CamelEwsSettings *settings,
 
        g_object_notify (G_OBJECT (settings), "show-public-folders");
 }
+
+guint
+camel_ews_settings_get_concurrent_connections (CamelEwsSettings *settings)
+{
+       g_return_val_if_fail (CAMEL_IS_EWS_SETTINGS (settings), 1);
+
+       return settings->priv->concurrent_connections;
+}
+
+void
+camel_ews_settings_set_concurrent_connections (CamelEwsSettings *settings,
+                                              guint concurrent_connections)
+{
+       g_return_if_fail (CAMEL_IS_EWS_SETTINGS (settings));
+
+       concurrent_connections = CLAMP (
+               concurrent_connections,
+               MIN_CONCURRENT_CONNECTIONS,
+               MAX_CONCURRENT_CONNECTIONS);
+
+       if (settings->priv->concurrent_connections == concurrent_connections)
+               return;
+
+       settings->priv->concurrent_connections = concurrent_connections;
+
+       g_object_notify (G_OBJECT (settings), "concurrent-connections");
+}
diff --git a/src/server/camel-ews-settings.h b/src/server/camel-ews-settings.h
index 8df535c2..f80d3d62 100644
--- a/src/server/camel-ews-settings.h
+++ b/src/server/camel-ews-settings.h
@@ -40,6 +40,9 @@
        (G_TYPE_INSTANCE_GET_CLASS \
        ((obj), CAMEL_TYPE_EWS_SETTINGS))
 
+#define MIN_CONCURRENT_CONNECTIONS 1
+#define MAX_CONCURRENT_CONNECTIONS 7
+
 G_BEGIN_DECLS
 
 typedef struct _CamelEwsSettings CamelEwsSettings;
@@ -172,6 +175,11 @@ gboolean   camel_ews_settings_get_show_public_folders
 void           camel_ews_settings_set_show_public_folders
                                                (CamelEwsSettings *settings,
                                                 gboolean show_public_folders);
+guint          camel_ews_settings_get_concurrent_connections
+                                               (CamelEwsSettings *settings);
+void           camel_ews_settings_set_concurrent_connections
+                                               (CamelEwsSettings *settings,
+                                                guint concurrent_connections);
 
 G_END_DECLS
 
diff --git a/src/server/e-ews-connection.c b/src/server/e-ews-connection.c
index 81419d54..68ff196f 100644
--- a/src/server/e-ews-connection.c
+++ b/src/server/e-ews-connection.c
@@ -49,9 +49,6 @@
        (G_TYPE_INSTANCE_GET_PRIVATE \
        ((obj), E_TYPE_EWS_CONNECTION, EEwsConnectionPrivate))
 
-/* For the number of connections */
-#define EWS_CONNECTION_MAX_REQUESTS 1
-
 /* A chunk size limit when moving items in chunks. */
 #define EWS_MOVE_ITEMS_CHUNK_SIZE 500
 
@@ -87,6 +84,7 @@ struct _EEwsConnectionPrivate {
        EEwsNotification *notification;
 
        CamelEwsSettings *settings;
+       guint concurrent_connections;
        GMutex property_lock;
 
        /* Hash key for the loaded_connections_permissions table. */
@@ -121,7 +119,8 @@ enum {
        PROP_PASSWORD,
        PROP_PROXY_RESOLVER,
        PROP_SETTINGS,
-       PROP_SOURCE
+       PROP_SOURCE,
+       PROP_CONCURRENT_CONNECTIONS
 };
 
 enum {
@@ -181,7 +180,39 @@ struct _EwsUrls {
 
 G_DEFINE_TYPE (EEwsConnection, e_ews_connection, G_TYPE_OBJECT)
 
-/* Static Functions */
+static guint
+ews_connection_get_concurrent_connections (EEwsConnection *cnc)
+{
+       g_return_val_if_fail (E_IS_EWS_CONNECTION (cnc), 1);
+
+       return cnc->priv->concurrent_connections;
+}
+
+static void
+ews_connection_set_concurrent_connections (EEwsConnection *cnc,
+                                          guint concurrent_connections)
+{
+       g_return_if_fail (E_IS_EWS_CONNECTION (cnc));
+
+       concurrent_connections = CLAMP (
+               concurrent_connections,
+               MIN_CONCURRENT_CONNECTIONS,
+               MAX_CONCURRENT_CONNECTIONS);
+
+       if (cnc->priv->concurrent_connections == concurrent_connections)
+               return;
+
+       cnc->priv->concurrent_connections = concurrent_connections;
+
+       if (cnc->priv->soup_session) {
+               g_object_set (G_OBJECT (cnc->priv->soup_session),
+                       SOUP_SESSION_MAX_CONNS, concurrent_connections,
+                       SOUP_SESSION_MAX_CONNS_PER_HOST, concurrent_connections,
+                       NULL);
+       }
+
+       g_object_notify (G_OBJECT (cnc), "concurrent-connections");
+}
 
 GQuark
 ews_connection_error_quark (void)
@@ -683,7 +714,7 @@ ews_next_request (gpointer _cnc)
 
        l = cnc->priv->jobs;
 
-       if (!l || g_slist_length (cnc->priv->active_job_queue) >= EWS_CONNECTION_MAX_REQUESTS) {
+       if (!l || g_slist_length (cnc->priv->active_job_queue) >= ews_connection_get_concurrent_connections 
(cnc)) {
                QUEUE_UNLOCK (cnc);
                return FALSE;
        }
@@ -1839,6 +1870,10 @@ ews_connection_set_settings (EEwsConnection *connection,
        g_return_if_fail (connection->priv->settings == NULL);
 
        connection->priv->settings = g_object_ref (settings);
+
+       e_binding_bind_property (connection->priv->settings, "concurrent-connections",
+               connection, "concurrent-connections",
+               G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
 }
 
 static void
@@ -1882,6 +1917,12 @@ ews_connection_set_property (GObject *object,
                                E_EWS_CONNECTION (object),
                                g_value_get_object (value));
                        return;
+
+               case PROP_CONCURRENT_CONNECTIONS:
+                       ews_connection_set_concurrent_connections (
+                               E_EWS_CONNECTION (object),
+                               g_value_get_uint (value));
+                       return;
        }
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -1921,6 +1962,13 @@ ews_connection_get_property (GObject *object,
                                e_ews_connection_get_source (
                                E_EWS_CONNECTION (object)));
                        return;
+
+               case PROP_CONCURRENT_CONNECTIONS:
+                       g_value_set_uint (
+                               value,
+                               ews_connection_get_concurrent_connections (
+                               E_EWS_CONNECTION (object)));
+                       return;
        }
 
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -1942,6 +1990,8 @@ ews_connection_constructed (GObject *object)
                SOUP_SESSION_SSL_STRICT, TRUE,
                SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
                SOUP_SESSION_ASYNC_CONTEXT, cnc->priv->soup_context,
+               SOUP_SESSION_MAX_CONNS, cnc->priv->concurrent_connections,
+               SOUP_SESSION_MAX_CONNS_PER_HOST, cnc->priv->concurrent_connections,
                NULL);
 
        /* Do not use G_BINDING_SYNC_CREATE because the property_lock is
@@ -2129,6 +2179,21 @@ e_ews_connection_class_init (EEwsConnectionClass *class)
                        G_PARAM_CONSTRUCT_ONLY |
                        G_PARAM_STATIC_STRINGS));
 
+       g_object_class_install_property (
+               object_class,
+               PROP_CONCURRENT_CONNECTIONS,
+               g_param_spec_uint (
+                       "concurrent-connections",
+                       "Concurrent Connections",
+                       "Number of concurrent connections to use",
+                       MIN_CONCURRENT_CONNECTIONS,
+                       MAX_CONCURRENT_CONNECTIONS,
+                       1,
+                       /* Do not construct it, otherwise it overrides the value derived from 
CamelEwsSettings */
+                       G_PARAM_READWRITE |
+                       G_PARAM_EXPLICIT_NOTIFY |
+                       G_PARAM_STATIC_STRINGS));
+
        signals[SERVER_NOTIFICATION] = g_signal_new (
                "server-notification",
                G_OBJECT_CLASS_TYPE (object_class),
@@ -2164,6 +2229,7 @@ e_ews_connection_init (EEwsConnection *cnc)
        cnc->priv->soup_loop = g_main_loop_new (cnc->priv->soup_context, FALSE);
        cnc->priv->backoff_enabled = TRUE;
        cnc->priv->disconnected_flag = FALSE;
+       cnc->priv->concurrent_connections = 1;
 
        cnc->priv->subscriptions = g_hash_table_new_full (
                        g_direct_hash, g_direct_equal,


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