[evolution-data-server] Bug #660383 - Backends should listen for changes in refresh interval



commit b6ca76f235bb8e29f1da7faabcb1e5909c5445d1
Author: Milan Crha <mcrha redhat com>
Date:   Wed Aug 22 19:24:42 2012 +0200

    Bug #660383 - Backends should listen for changes in refresh interval

 .../backends/google/e-book-backend-google.c        |  179 +++----------------
 calendar/backends/caldav/e-cal-backend-caldav.c    |   53 +++---
 calendar/backends/http/e-cal-backend-http.c        |  122 ++++----------
 3 files changed, 91 insertions(+), 263 deletions(-)
---
diff --git a/addressbook/backends/google/e-book-backend-google.c b/addressbook/backends/google/e-book-backend-google.c
index 0131c81..ef901cd 100644
--- a/addressbook/backends/google/e-book-backend-google.c
+++ b/addressbook/backends/google/e-book-backend-google.c
@@ -77,10 +77,6 @@ struct _EBookBackendGooglePrivate {
 	GDataAuthorizer *authorizer;
 	GDataService *service;
 	EProxy *proxy;
-	guint refresh_interval;
-
-	/* If views are open we will send out signals in an idle_handler */
-	guint idle_id;
 
 	guint refresh_id;
 
@@ -241,23 +237,6 @@ cache_get_last_update (EBookBackend *backend)
 	return e_book_backend_cache_get_time (priv->cache);
 }
 
-static gboolean
-cache_get_last_update_tv (EBookBackend *backend,
-                          GTimeVal *tv)
-{
-	EBookBackendGooglePrivate *priv;
-	gchar *last_update;
-	gint rv;
-
-	priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
-
-	last_update = e_book_backend_cache_get_time (priv->cache);
-	rv = last_update ? g_time_val_from_iso8601 (last_update, tv) : FALSE;
-	g_free (last_update);
-
-	return rv;
-}
-
 static void
 cache_set_last_update (EBookBackend *backend,
                        GTimeVal *tv)
@@ -273,49 +252,6 @@ cache_set_last_update (EBookBackend *backend,
 }
 
 static gboolean
-cache_needs_update (EBookBackend *backend,
-                    guint *remaining_secs)
-{
-	EBookBackendGooglePrivate *priv;
-	GTimeVal last, current;
-	guint diff;
-	gboolean rv;
-
-	priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
-
-	if (remaining_secs)
-		*remaining_secs = G_MAXUINT;
-
-	/* We never want to update in offline mode */
-	if (!e_backend_get_online (E_BACKEND (backend)))
-		return FALSE;
-
-	rv = cache_get_last_update_tv (backend, &last);
-
-	if (!rv)
-		return TRUE;
-
-	g_get_current_time (&current);
-	if (last.tv_sec > current.tv_sec) {
-		g_warning ("last update is in the feature?");
-
-		/* Do an update so we can fix this */
-		return TRUE;
-	}
-	diff = current.tv_sec - last.tv_sec;
-
-	if (diff >= priv->refresh_interval)
-		return TRUE;
-
-	if (remaining_secs)
-		*remaining_secs = priv->refresh_interval - diff;
-
-	__debug__ ("No update needed. Next update needed in %d secs", priv->refresh_interval - diff);
-
-	return FALSE;
-}
-
-static gboolean
 backend_is_authorized (EBookBackend *backend)
 {
 	EBookBackendGooglePrivate *priv;
@@ -942,30 +878,22 @@ _create_group (const gchar *category_name,
 	return create_group (E_BOOK_BACKEND (user_data), category_name, error);
 }
 
-static gboolean cache_refresh_if_needed (EBookBackend *backend);
-
-static gboolean
-on_refresh_timeout (EBookBackend *backend)
+static void
+refresh_local_cache_cb (ESource *source,
+			gpointer user_data)
 {
-	EBookBackendGooglePrivate *priv;
+	EBookBackend *backend = user_data;
 
-	priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
+	__debug__ ("Invoking cache refresh");
 
-	__debug__ (G_STRFUNC);
-
-	priv->refresh_id = 0;
-	if (priv->bookviews != NULL)
-		cache_refresh_if_needed (backend);
-
-	return FALSE;
+	get_groups (backend);
+	get_new_contacts (backend);
 }
 
-static gboolean
+static void
 cache_refresh_if_needed (EBookBackend *backend)
 {
 	EBookBackendGooglePrivate *priv;
-	guint remaining_secs;
-	gboolean install_timeout;
 	gboolean is_online;
 
 	priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
@@ -976,25 +904,24 @@ cache_refresh_if_needed (EBookBackend *backend)
 
 	if (!is_online || !backend_is_authorized (backend)) {
 		__debug__ ("We are not connected to Google%s.", (!is_online) ? " (offline mode)" : "");
-		return TRUE;
+		return;
 	}
 
-	install_timeout = (priv->bookviews != NULL && priv->refresh_interval > 0 && 0 == priv->refresh_id);
+	if (!priv->refresh_id) {
+		/* Update the cache asynchronously */
+		refresh_local_cache_cb (NULL, backend);
 
-	if (cache_needs_update (backend, &remaining_secs)) {
-		/* Update the cache asynchronously and schedule a new timeout */
+		priv->refresh_id = e_source_refresh_add_timeout (
+			e_backend_get_source (E_BACKEND (backend)),
+			NULL,
+			refresh_local_cache_cb,
+			backend,
+			NULL);
+	} else if (g_hash_table_size (priv->system_groups_by_id) == 0) {
 		get_groups (backend);
-		get_new_contacts (backend);
-		remaining_secs = priv->refresh_interval;
-	} else if (g_hash_table_size (priv->system_groups_by_id) == 0)
-		get_groups (backend);
-
-	if (install_timeout) {
-		__debug__ ("Installing timeout with %d seconds", remaining_secs);
-		priv->refresh_id = g_timeout_add_seconds (remaining_secs, (GSourceFunc) on_refresh_timeout, backend);
 	}
 
-	return TRUE;
+	return;
 }
 
 static void
@@ -1861,19 +1788,6 @@ e_book_backend_google_get_contact_list_uids (EBookBackend *backend,
 	g_slist_free (filtered_uids);
 }
 
-static gboolean
-on_refresh_idle (EBookBackend *backend)
-{
-	EBookBackendGooglePrivate *priv;
-
-	priv = E_BOOK_BACKEND_GOOGLE_GET_PRIVATE (backend);
-
-	priv->idle_id = 0;
-	cache_refresh_if_needed (backend);
-
-	return FALSE;
-}
-
 static void
 e_book_backend_google_start_book_view (EBookBackend *backend,
                                        EDataBookView *bookview)
@@ -1897,19 +1811,6 @@ e_book_backend_google_start_book_view (EBookBackend *backend,
 	/* Ensure that we're ready to support a view */
 	cache_refresh_if_needed (backend);
 
-	/* Update the cache if necessary */
-	if (cache_needs_update (backend, NULL)) {
-		/* XXX We ought to be authorized by now, I would think.
-		 *     Not sure when we wouldn't be or how to handle it. */
-		if (!backend_is_authorized (backend)) {
-			error = EDB_ERROR (AUTHENTICATION_REQUIRED);
-			goto exit;
-		} else {
-			/* Update in an idle function, so that this call doesn't block */
-			priv->idle_id = g_idle_add ((GSourceFunc) on_refresh_idle, backend);
-		}
-	}
-
 	/* Get the contacts */
 	cached_contacts = cache_get_contacts (backend);
 	__debug__ ("%d contacts found in cache", g_list_length (cached_contacts));
@@ -1921,7 +1822,6 @@ e_book_backend_google_start_book_view (EBookBackend *backend,
 		g_object_unref (contact);
 	}
 
-exit:
 	/* This function frees the GError passed to it. */
 	e_data_book_view_notify_complete (bookview, error);
 }
@@ -1942,12 +1842,6 @@ e_book_backend_google_stop_book_view (EBookBackend *backend,
 		priv->bookviews = g_list_delete_link (priv->bookviews, view);
 		e_data_book_view_unref (bookview);
 	}
-
-	/* If there are no book views left, we can stop doing certain things, like refreshes */
-	if (!priv->bookviews && priv->refresh_id != 0) {
-		g_source_remove (priv->refresh_id);
-		priv->refresh_id = 0;
-	}
 }
 
 static void
@@ -1958,10 +1852,6 @@ e_book_backend_google_open (EBookBackend *backend,
                             gboolean only_if_exists)
 {
 	EBookBackendGooglePrivate *priv;
-	ESourceRefresh *refresh_extension;
-	ESource *source;
-	guint interval_in_minutes;
-	const gchar *extension_name;
 	gboolean is_online;
 	GError *error = NULL;
 
@@ -1974,15 +1864,6 @@ e_book_backend_google_open (EBookBackend *backend,
 		return;
 	}
 
-	source = e_backend_get_source (E_BACKEND (backend));
-
-	extension_name = E_SOURCE_EXTENSION_REFRESH;
-	refresh_extension = e_source_get_extension (source, extension_name);
-
-	interval_in_minutes =
-		e_source_refresh_get_enabled (refresh_extension) ?
-		e_source_refresh_get_interval_minutes (refresh_extension) : 0;
-
 	/* Set up our object */
 	if (!priv->cancellables) {
 		priv->groups_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
@@ -1993,13 +1874,6 @@ e_book_backend_google_open (EBookBackend *backend,
 	}
 
 	cache_init (backend);
-	priv->refresh_interval = interval_in_minutes * 60;
-
-	/* Remove and re-add the timeout */
-	if (priv->refresh_id != 0 && priv->refresh_interval > 0) {
-		g_source_remove (priv->refresh_id);
-		priv->refresh_id = g_timeout_add_seconds (priv->refresh_interval, (GSourceFunc) on_refresh_timeout, backend);
-	}
 
 	/* Set up ready to be interacted with */
 	is_online = e_backend_get_online (E_BACKEND (backend));
@@ -2015,8 +1889,11 @@ e_book_backend_google_open (EBookBackend *backend,
 	}
 
 	if (!is_online || backend_is_authorized (backend)) {
-		if (is_online)
+		if (is_online) {
 			e_book_backend_notify_readonly (backend, FALSE);
+			cache_refresh_if_needed (backend);
+		}
+
 		e_book_backend_notify_opened (backend, NULL /* Success */);
 	}
 
@@ -2258,9 +2135,11 @@ e_book_backend_google_dispose (GObject *object)
 		priv->bookviews = g_list_delete_link (priv->bookviews, priv->bookviews);
 	}
 
-	if (priv->idle_id) {
-		g_source_remove (priv->idle_id);
-		priv->idle_id = 0;
+	if (priv->refresh_id) {
+		e_source_refresh_remove_timeout (
+			e_backend_get_source (E_BACKEND (object)),
+			priv->refresh_id);
+		priv->refresh_id = 0;
 	}
 
 	if (priv->service)
diff --git a/calendar/backends/caldav/e-cal-backend-caldav.c b/calendar/backends/caldav/e-cal-backend-caldav.c
index e98e7f2..e6416ab 100644
--- a/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -90,7 +90,6 @@ struct _ECalBackendCalDAVPrivate {
 	const GThread *synch_slave; /* just for a reference, whether thread exists */
 	SlaveCommand slave_cmd;
 	gboolean slave_busy; /* whether is slave working */
-	GTimeVal refresh_time;
 
 	/* The main soup session  */
 	SoupSession *session;
@@ -127,6 +126,8 @@ struct _ECalBackendCalDAVPrivate {
 
 	/* set to true if thread for ESource::changed is invoked */
 	gboolean updating_source;
+
+	guint refresh_id;
 };
 
 /* ************************************************************************* */
@@ -2294,12 +2295,23 @@ is_google_uri (const gchar *uri)
 	return res;
 }
 
+static void
+time_to_refresh_caldav_calendar_cb (ESource *source,
+				    gpointer user_data)
+{
+	ECalBackendCalDAV *cbdav = user_data;
+
+	g_return_if_fail (E_IS_CAL_BACKEND_CALDAV (cbdav));
+
+	g_cond_signal (cbdav->priv->cond);
+}
+
 /* ************************************************************************* */
 
 static gpointer
 caldav_synch_slave_loop (gpointer data)
 {
-	ECalBackendCalDAV        *cbdav;
+	ECalBackendCalDAV *cbdav;
 	time_t now;
 	icaltimezone *utc = icaltimezone_get_utc_timezone ();
 	gboolean know_unreachable;
@@ -2311,7 +2323,6 @@ caldav_synch_slave_loop (gpointer data)
 	know_unreachable = !cbdav->priv->opened;
 
 	while (cbdav->priv->slave_cmd != SLAVE_SHOULD_DIE) {
-		GTimeVal alarm_clock;
 		if (cbdav->priv->slave_cmd == SLAVE_SHOULD_SLEEP) {
 			/* just sleep until we get woken up again */
 			g_cond_wait (cbdav->priv->cond, cbdav->priv->busy_lock);
@@ -2390,12 +2401,7 @@ caldav_synch_slave_loop (gpointer data)
 		cbdav->priv->slave_busy = FALSE;
 
 		/* puhh that was hard, get some rest :) */
-		g_get_current_time (&alarm_clock);
-		alarm_clock.tv_sec += cbdav->priv->refresh_time.tv_sec;
-		g_cond_timed_wait (cbdav->priv->cond,
-				   cbdav->priv->busy_lock,
-				   &alarm_clock);
-
+		g_cond_wait (cbdav->priv->cond, cbdav->priv->busy_lock);
 	}
 
 	/* signal we are done */
@@ -2542,7 +2548,6 @@ initialize_backend (ECalBackendCalDAV *cbdav,
 {
 	ESourceAuthentication    *auth_extension;
 	ESourceOffline           *offline_extension;
-	ESourceRefresh           *refresh_extension;
 	ESourceWebdav            *webdav_extension;
 	ECalBackend              *backend;
 	SoupURI                  *soup_uri;
@@ -2550,7 +2555,6 @@ initialize_backend (ECalBackendCalDAV *cbdav,
 	gsize                     len;
 	const gchar              *cache_dir;
 	const gchar              *extension_name;
-	guint                     interval_in_minutes;
 
 	backend = E_CAL_BACKEND (cbdav);
 	cache_dir = e_cal_backend_get_cache_dir (backend);
@@ -2562,9 +2566,6 @@ initialize_backend (ECalBackendCalDAV *cbdav,
 	extension_name = E_SOURCE_EXTENSION_OFFLINE;
 	offline_extension = e_source_get_extension (source, extension_name);
 
-	extension_name = E_SOURCE_EXTENSION_REFRESH;
-	refresh_extension = e_source_get_extension (source, extension_name);
-
 	extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
 	webdav_extension = e_source_get_extension (source, extension_name);
 
@@ -2648,15 +2649,6 @@ initialize_backend (ECalBackendCalDAV *cbdav,
 		return FALSE;
 	}
 
-	/* FIXME Not honoring ESourceRefresh:enabled. */
-	interval_in_minutes =
-		e_source_refresh_get_interval_minutes (refresh_extension);
-
-	if (interval_in_minutes == 0)
-		cbdav->priv->refresh_time.tv_sec = DEFAULT_REFRESH_TIME;
-	else
-		cbdav->priv->refresh_time.tv_sec = interval_in_minutes * 60;
-
 	if (!cbdav->priv->synch_slave) {
 		GThread *slave;
 
@@ -2670,6 +2662,11 @@ initialize_backend (ECalBackendCalDAV *cbdav,
 		cbdav->priv->synch_slave = slave;
 	}
 
+	if (cbdav->priv->refresh_id == 0) {
+		cbdav->priv->refresh_id = e_source_refresh_add_timeout (
+			source, NULL, time_to_refresh_caldav_calendar_cb, cbdav, NULL);
+	}
+
 	return TRUE;
 }
 
@@ -4932,9 +4929,15 @@ e_cal_backend_caldav_dispose (GObject *object)
 	}
 
 	source = e_backend_get_source (E_BACKEND (object));
-	if (source)
+	if (source) {
 		g_signal_handlers_disconnect_by_func (G_OBJECT (source), caldav_source_changed_cb, object);
 
+		if (priv->refresh_id) {
+			e_source_refresh_remove_timeout	(source, priv->refresh_id);
+			priv->refresh_id = 0;
+		}
+	}
+
 	/* stop the slave  */
 	if (priv->synch_slave) {
 		g_cond_signal (priv->cond);
@@ -5035,8 +5038,6 @@ e_cal_backend_caldav_init (ECalBackendCalDAV *cbdav)
 	/* Slave control ... */
 	cbdav->priv->slave_cmd = SLAVE_SHOULD_SLEEP;
 	cbdav->priv->slave_busy = FALSE;
-	cbdav->priv->refresh_time.tv_usec = 0;
-	cbdav->priv->refresh_time.tv_sec  = DEFAULT_REFRESH_TIME;
 
 	g_signal_connect (cbdav->priv->session, "authenticate",
 			  G_CALLBACK (soup_authenticate), cbdav);
diff --git a/calendar/backends/http/e-cal-backend-http.c b/calendar/backends/http/e-cal-backend-http.c
index 0c2f371..62a503e 100644
--- a/calendar/backends/http/e-cal-backend-http.c
+++ b/calendar/backends/http/e-cal-backend-http.c
@@ -114,7 +114,8 @@ e_cal_backend_http_dispose (GObject *object)
 	priv = cbhttp->priv;
 
 	if (priv->reload_timeout_id) {
-		g_source_remove (priv->reload_timeout_id);
+		ESource *source = e_backend_get_source (E_BACKEND (cbhttp));
+		e_source_refresh_remove_timeout (source, priv->reload_timeout_id);
 		priv->reload_timeout_id = 0;
 	}
 
@@ -731,8 +732,6 @@ cal_backend_http_ensure_uri (ECalBackendHttp *backend)
 	return backend->priv->uri;
 }
 
-static void     maybe_start_reload_timeout (ECalBackendHttp *cbhttp);
-
 static gboolean
 begin_retrieval_cb (GIOSchedulerJob *job,
                     GCancellable *cancellable,
@@ -744,8 +743,6 @@ begin_retrieval_cb (GIOSchedulerJob *job,
 	if (!e_backend_get_online (E_BACKEND (backend)))
 		return FALSE;
 
-	maybe_start_reload_timeout (backend);
-
 	if (backend->priv->is_loading)
 		return FALSE;
 
@@ -779,64 +776,6 @@ begin_retrieval_cb (GIOSchedulerJob *job,
 	return FALSE;
 }
 
-static gboolean
-reload_cb (ECalBackendHttp *cbhttp)
-{
-	ECalBackendHttpPrivate *priv;
-
-	priv = cbhttp->priv;
-
-	if (priv->is_loading)
-		return TRUE;
-
-	d (g_message ("Reload!\n"));
-
-	priv->reload_timeout_id = 0;
-
-	g_io_scheduler_push_job (
-		(GIOSchedulerJobFunc) begin_retrieval_cb,
-		g_object_ref (cbhttp),
-		(GDestroyNotify) g_object_unref,
-		G_PRIORITY_DEFAULT, NULL);
-
-	return FALSE;
-}
-
-static void
-maybe_start_reload_timeout (ECalBackendHttp *cbhttp)
-{
-	ECalBackendHttpPrivate *priv;
-	ESource *source;
-	ESourceRefresh *extension;
-	const gchar *extension_name;
-	guint interval_in_minutes = 0;
-
-	priv = cbhttp->priv;
-
-	d (g_message ("Setting reload timeout.\n"));
-
-	if (priv->reload_timeout_id)
-		return;
-
-	source = e_backend_get_source (E_BACKEND (cbhttp));
-	if (!source) {
-		g_warning ("Could not get source for ECalBackendHttp reload.");
-		return;
-	}
-
-	extension_name = E_SOURCE_EXTENSION_REFRESH;
-	extension = e_source_get_extension (source, extension_name);
-
-	if (e_source_refresh_get_enabled (extension))
-		interval_in_minutes =
-			e_source_refresh_get_interval_minutes (extension);
-
-	if (interval_in_minutes > 0)
-		priv->reload_timeout_id = g_timeout_add_seconds (
-			interval_in_minutes * 60,
-			(GSourceFunc) reload_cb, cbhttp);
-}
-
 static void
 source_changed_cb (ESource *source,
                    ECalBackendHttp *cbhttp)
@@ -868,6 +807,24 @@ source_changed_cb (ESource *source,
 	}
 }
 
+static void
+http_cal_reload_cb (ESource *source,
+		    gpointer user_data)
+{
+	ECalBackendHttp *cbhttp = user_data;
+
+	g_return_if_fail (E_IS_CAL_BACKEND_HTTP (cbhttp));
+
+	if (!e_backend_get_online (E_BACKEND (cbhttp)))
+		return;
+
+	g_io_scheduler_push_job (
+		(GIOSchedulerJobFunc) begin_retrieval_cb,
+		g_object_ref (cbhttp),
+		(GDestroyNotify) g_object_unref,
+		G_PRIORITY_DEFAULT, NULL);
+}
+
 /* Open handler for the file backend */
 static void
 e_cal_backend_http_open (ECalBackendSync *backend,
@@ -967,8 +924,12 @@ e_cal_backend_http_open (ECalBackendSync *backend,
 			g_propagate_error (perror, local_error);
 	}
 
-	if (opened)
+	if (opened) {
 		e_cal_backend_notify_opened (E_CAL_BACKEND (backend), NULL);
+
+		if (!priv->reload_timeout_id)
+			priv->reload_timeout_id = e_source_refresh_add_timeout (source, NULL, http_cal_reload_cb, backend, NULL);
+	}
 }
 
 static void
@@ -979,6 +940,7 @@ e_cal_backend_http_refresh (ECalBackendSync *backend,
 {
 	ECalBackendHttp *cbhttp;
 	ECalBackendHttpPrivate *priv;
+	ESource *source;
 
 	cbhttp = E_CAL_BACKEND_HTTP (backend);
 	priv = cbhttp->priv;
@@ -987,12 +949,10 @@ e_cal_backend_http_refresh (ECalBackendSync *backend,
 	    priv->is_loading)
 		return;
 
-	if (priv->reload_timeout_id)
-		g_source_remove (priv->reload_timeout_id);
-	priv->reload_timeout_id = 0;
+	source = e_backend_get_source (E_BACKEND (cbhttp));
+	g_return_if_fail (source != NULL);
 
-	/* wait a second, then start reloading */
-	priv->reload_timeout_id = g_timeout_add (1000, (GSourceFunc) reload_cb, cbhttp);
+	e_source_refresh_force_timeout (source);
 }
 
 /* Set_mode handler for the http backend */
@@ -1000,30 +960,18 @@ static void
 e_cal_backend_http_notify_online_cb (ECalBackend *backend,
                                      GParamSpec *pspec)
 {
-	ECalBackendHttp *cbhttp;
-	ECalBackendHttpPrivate *priv;
 	gboolean loaded;
 	gboolean online;
 
-	cbhttp = E_CAL_BACKEND_HTTP (backend);
-	priv = cbhttp->priv;
-
 	online = e_backend_get_online (E_BACKEND (backend));
 	loaded = e_cal_backend_is_opened (backend);
 
-	if (!online) {
-		if (loaded && priv->reload_timeout_id) {
-			g_source_remove (priv->reload_timeout_id);
-			priv->reload_timeout_id = 0;
-		}
-	} else {
-		if (loaded)
-			g_io_scheduler_push_job (
-				(GIOSchedulerJobFunc) begin_retrieval_cb,
-				g_object_ref (backend),
-				(GDestroyNotify) g_object_unref,
-				G_PRIORITY_DEFAULT, NULL);
-	}
+	if (online && loaded)
+		g_io_scheduler_push_job (
+			(GIOSchedulerJobFunc) begin_retrieval_cb,
+			g_object_ref (backend),
+			(GDestroyNotify) g_object_unref,
+			G_PRIORITY_DEFAULT, NULL);
 
 	if (loaded)
 		e_cal_backend_notify_online (backend, online);



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