[gnome-documents] miner: refactor the crawling code to support multiple GOA accounts
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-documents] miner: refactor the crawling code to support multiple GOA accounts
- Date: Thu, 15 Sep 2011 20:27:14 +0000 (UTC)
commit b7be0f0925607b440b04b134741312adc863c46c
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Thu Sep 15 12:53:54 2011 -0400
miner: refactor the crawling code to support multiple GOA accounts
src/miner/gd-gdata-miner.c | 443 +++++++++++++++++++++++++++++-------------
src/miner/gdata-miner-main.c | 55 +++++-
2 files changed, 358 insertions(+), 140 deletions(-)
---
diff --git a/src/miner/gd-gdata-miner.c b/src/miner/gd-gdata-miner.c
index a996e48..dd7d34c 100644
--- a/src/miner/gd-gdata-miner.c
+++ b/src/miner/gd-gdata-miner.c
@@ -26,32 +26,21 @@
#include "gd-gdata-goa-authorizer.h"
#include "gd-gdata-miner.h"
-#define DATASOURCE_URN "urn:nepomuk:datasource:86ec9bc9-c242-427f-aa19-77b5a2c9b6f0"
+#define MINER_IDENTIFIER "gd:gdata:miner:86ec9bc9-c242-427f-aa19-77b5a2c9b6f0"
#define STARRED_CATEGORY_TERM "http://schemas.google.com/g/2005/labels#starred"
G_DEFINE_TYPE (GdGDataMiner, gd_gdata_miner, G_TYPE_OBJECT)
struct _GdGDataMinerPrivate {
GoaClient *client;
- GDataDocumentsService *service;
TrackerSparqlConnection *connection;
GCancellable *cancellable;
GSimpleAsyncResult *result;
- GHashTable *previous_resources;
+ GList *pending_jobs;
};
-static void
-gd_gdata_miner_complete_error (GdGDataMiner *self,
- GError *error)
-{
- g_assert (self->priv->result != NULL);
-
- g_simple_async_result_take_error (self->priv->result, error);
- g_simple_async_result_complete_in_idle (self->priv->result);
-}
-
static gchar *
_tracker_utils_format_into_graph (const gchar *graph)
{
@@ -370,6 +359,81 @@ _tracker_utils_iso8601_from_timestamp (gint64 timestamp)
return g_time_val_to_iso8601 (&tv);
}
+typedef struct {
+ GdGDataMiner *self;
+ TrackerSparqlConnection *connection; /* borrowed from GdGDataMiner */
+ gulong miner_cancellable_id;
+
+ GoaAccount *account;
+ GDataDocumentsService *service;
+ GSimpleAsyncResult *async_result;
+ GCancellable *cancellable;
+
+ GHashTable *previous_resources;
+} AccountMinerJob;
+
+static void
+miner_cancellable_cancelled_cb (GCancellable *cancellable,
+ gpointer user_data)
+{
+ AccountMinerJob *job = user_data;
+
+ /* forward the cancel signal to the ongoing job */
+ g_cancellable_cancel (job->cancellable);
+}
+
+static void
+account_miner_job_free (AccountMinerJob *job)
+{
+ if (job->miner_cancellable_id != 0)
+ g_cancellable_disconnect (job->self->priv->cancellable,
+ job->miner_cancellable_id);
+
+ g_clear_object (&job->service);
+ g_clear_object (&job->self);
+ g_clear_object (&job->account);
+ g_clear_object (&job->async_result);
+
+ g_hash_table_unref (job->previous_resources);
+
+ g_slice_free (AccountMinerJob, job);
+}
+
+static AccountMinerJob *
+account_miner_job_new (GdGDataMiner *self,
+ GoaObject *object)
+{
+ AccountMinerJob *retval;
+ GdGDataGoaAuthorizer *authorizer;
+ GoaAccount *account;
+
+ account = goa_object_get_account (object);
+ g_assert (account != NULL);
+
+ retval = g_slice_new0 (AccountMinerJob);
+ retval->self = g_object_ref (self);
+ retval->cancellable = g_cancellable_new ();
+ retval->account = account;
+ retval->connection = self->priv->connection;
+ retval->previous_resources =
+ g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, (GDestroyNotify) g_free);
+
+ if (self->priv->cancellable != NULL)
+ retval->miner_cancellable_id =
+ g_cancellable_connect (self->priv->cancellable,
+ G_CALLBACK (miner_cancellable_cancelled_cb),
+ retval, NULL);
+
+ authorizer = gd_gdata_goa_authorizer_new (object);
+ retval->service = gdata_documents_service_new (GDATA_AUTHORIZER (authorizer));
+
+ /* the service takes ownership of the authorizer */
+ g_object_unref (authorizer);
+
+ return retval;
+}
+
static void
previous_resources_cleanup_foreach (gpointer key,
gpointer value,
@@ -382,11 +446,11 @@ previous_resources_cleanup_foreach (gpointer key,
}
static void
-gd_gdata_miner_cleanup_previous (GdGDataMiner *self)
+account_miner_job_cleanup_previous (AccountMinerJob *job,
+ GError **error)
{
GString *delete;
GList *values;
- GError *error = NULL;
delete = g_string_new (NULL);
g_string_append (delete, "DELETE { ");
@@ -394,34 +458,29 @@ gd_gdata_miner_cleanup_previous (GdGDataMiner *self)
/* the resources left here are those who were in the database,
* but were not found during the query; remove them from the database.
*/
- g_hash_table_foreach (self->priv->previous_resources,
+ g_hash_table_foreach (job->previous_resources,
previous_resources_cleanup_foreach,
delete);
g_string_append (delete, "}");
- tracker_sparql_connection_update (self->priv->connection,
+ tracker_sparql_connection_update (job->connection,
delete->str,
G_PRIORITY_DEFAULT,
- self->priv->cancellable,
- &error);
-
- if (error != NULL) {
- g_printerr ("Unable to cleanup the previous results: %s\n", error->message);
- g_error_free (error);
- }
+ job->cancellable,
+ error);
g_string_free (delete, TRUE);
}
-static void
-gd_gdata_miner_process_entry (GdGDataMiner *self,
- GDataDocumentsEntry *doc_entry,
- GError **error)
+static gboolean
+account_miner_job_process_entry (AccountMinerJob *job,
+ GDataDocumentsEntry *doc_entry,
+ GError **error)
{
GDataEntry *entry = GDATA_ENTRY (doc_entry);
gchar *resource;
- gchar *date, *resource_url;
+ gchar *date, *resource_url, *datasource_urn;
const gchar *identifier, *class = NULL;
GList *authors, *l;
@@ -439,8 +498,10 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
if (!GDATA_IS_DOCUMENTS_DOCUMENT (doc_entry))
{
/* TODO: folders */
- g_print ("found a folder?\n");
- return;
+ g_set_error_literal (error, G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "Folders are not supported");
+ return FALSE;
}
identifier = gdata_entry_get_id (entry);
@@ -449,7 +510,7 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
gdata_documents_entry_get_path (doc_entry));
/* remove from the list of the previous resources */
- g_hash_table_remove (self->priv->previous_resources, identifier);
+ g_hash_table_remove (job->previous_resources, identifier);
if (GDATA_IS_DOCUMENTS_PRESENTATION (doc_entry))
class = "nfo:Presentation";
@@ -459,8 +520,8 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
class = "nfo:PaginatedTextDocument";
resource = _tracker_sparql_connection_ensure_resource
- (self->priv->connection,
- self->priv->cancellable, error,
+ (job->connection,
+ job->cancellable, error,
resource_url, identifier,
"nfo:RemoteDataObject",
class,
@@ -469,17 +530,24 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
if (*error != NULL)
goto out;
+ datasource_urn = g_strdup_printf ("gd:goa-account:%s",
+ goa_account_get_id (job->account));
_tracker_sparql_connection_set_triple
- (self->priv->connection, self->priv->cancellable, error,
+ (job->connection, job->cancellable, error,
identifier, resource,
- "nie:dataSource", DATASOURCE_URN);
+ "nie:dataSource", datasource_urn);
+
+ g_free (datasource_urn);
+
+ if (*error != NULL)
+ goto out;
alternate = gdata_entry_look_up_link (entry, GDATA_LINK_ALTERNATE);
alternate_uri = gdata_link_get_uri (alternate);
_tracker_sparql_connection_insert_or_replace_triple
- (self->priv->connection,
- self->priv->cancellable, error,
+ (job->connection,
+ job->cancellable, error,
identifier, resource,
"nie:url", alternate_uri);
@@ -498,16 +566,16 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
}
_tracker_sparql_connection_toggle_favorite
- (self->priv->connection,
- self->priv->cancellable, error,
+ (job->connection,
+ job->cancellable, error,
resource, starred);
if (*error != NULL)
goto out;
_tracker_sparql_connection_insert_or_replace_triple
- (self->priv->connection,
- self->priv->cancellable, error,
+ (job->connection,
+ job->cancellable, error,
identifier, resource,
"nie:description", gdata_entry_get_summary (entry));
@@ -515,8 +583,8 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
goto out;
_tracker_sparql_connection_insert_or_replace_triple
- (self->priv->connection,
- self->priv->cancellable, error,
+ (job->connection,
+ job->cancellable, error,
identifier, resource,
"nie:title", gdata_entry_get_title (entry));
@@ -530,8 +598,8 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
author = l->data;
- contact_resource = _tracker_utils_ensure_contact_resource (self->priv->connection,
- self->priv->cancellable, error,
+ contact_resource = _tracker_utils_ensure_contact_resource (job->connection,
+ job->cancellable, error,
gdata_author_get_email_address (author),
gdata_author_get_name (author));
@@ -539,8 +607,8 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
goto out;
_tracker_sparql_connection_insert_or_replace_triple
- (self->priv->connection,
- self->priv->cancellable, error,
+ (job->connection,
+ job->cancellable, error,
identifier, resource,
"nco:creator", contact_resource);
@@ -551,8 +619,8 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
}
access_rules = gdata_access_handler_get_rules (GDATA_ACCESS_HANDLER (entry),
- GDATA_SERVICE (self->priv->service),
- self->priv->cancellable,
+ GDATA_SERVICE (job->service),
+ job->cancellable,
NULL, NULL, error);
if (*error != NULL)
@@ -575,14 +643,14 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
if (g_strcmp0 (scope_type, GDATA_ACCESS_SCOPE_DOMAIN) == 0)
continue;
- contact_resource = _tracker_utils_ensure_contact_resource (self->priv->connection,
- self->priv->cancellable, error,
+ contact_resource = _tracker_utils_ensure_contact_resource (job->connection,
+ job->cancellable, error,
scope_value,
"");
_tracker_sparql_connection_insert_or_replace_triple
- (self->priv->connection,
- self->priv->cancellable, error,
+ (job->connection,
+ job->cancellable, error,
identifier, resource,
"nco:contributor", contact_resource);
@@ -594,8 +662,8 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
date = _tracker_utils_iso8601_from_timestamp (gdata_entry_get_published (entry));
_tracker_sparql_connection_insert_or_replace_triple
- (self->priv->connection,
- self->priv->cancellable, error,
+ (job->connection,
+ job->cancellable, error,
identifier, resource,
"nie:contentCreated", date);
g_free (date);
@@ -605,8 +673,8 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
date = _tracker_utils_iso8601_from_timestamp (gdata_entry_get_updated (entry));
_tracker_sparql_connection_insert_or_replace_triple
- (self->priv->connection,
- self->priv->cancellable, error,
+ (job->connection,
+ job->cancellable, error,
identifier, resource,
"nie:contentLastModified", date);
g_free (date);
@@ -617,134 +685,217 @@ gd_gdata_miner_process_entry (GdGDataMiner *self,
out:
g_clear_object (&access_rules);
g_free (resource_url);
+
+ if (*error != NULL)
+ return FALSE;
+
+ return TRUE;
}
static void
-gd_gdata_miner_query_gdata (GdGDataMiner *self)
+account_miner_job_query_gdata (AccountMinerJob *job,
+ GError **error)
{
GDataDocumentsQuery *query;
GDataDocumentsFeed *feed;
- GError *error = NULL;
GList *entries, *l;
query = gdata_documents_query_new (NULL);
feed = gdata_documents_service_query_documents
- (self->priv->service, query,
- self->priv->cancellable, NULL, NULL, &error);
+ (job->service, query,
+ job->cancellable, NULL, NULL, error);
g_object_unref (query);
- if (error != NULL)
- {
- gd_gdata_miner_complete_error (self, error);
- return;
- }
+ if (feed == NULL)
+ return;
entries = gdata_feed_get_entries (GDATA_FEED (feed));
for (l = entries; l != NULL; l = l->next)
{
- gd_gdata_miner_process_entry (self, l->data, &error);
+ account_miner_job_process_entry (job, l->data, error);
- if (error != NULL)
- {
- gd_gdata_miner_complete_error (self, error);
- g_object_unref (feed);
-
- return;
- }
+ if (*error != NULL)
+ break;
}
- gd_gdata_miner_cleanup_previous (self);
-
- g_simple_async_result_complete_in_idle (self->priv->result);
g_object_unref (feed);
}
+
static void
-gd_gdata_miner_query_existing (GdGDataMiner *self)
+account_miner_job_query_existing (AccountMinerJob *job,
+ GError **error)
{
GString *select;
TrackerSparqlCursor *cursor;
- GError *error = NULL;
+ gboolean valid;
select = g_string_new (NULL);
g_string_append_printf (select,
- "SELECT ?urn nao:identifier(?urn) WHERE { ?urn a nfo:RemoteDataObject . "
- "?urn nie:dataSource \"%s\" }", DATASOURCE_URN);
+ "SELECT ?urn nao:identifier(?urn) WHERE { ?urn nie:dataSource <gd:goa-account:%s> }",
+ goa_account_get_id (job->account));
- cursor = tracker_sparql_connection_query (self->priv->connection,
+ cursor = tracker_sparql_connection_query (job->connection,
select->str,
- self->priv->cancellable,
- &error);
+ job->cancellable,
+ error);
+ g_string_free (select, TRUE);
- if (error != NULL) {
- g_printerr ("Error while getting the previous resources: %s\n", error->message);
- g_error_free (error);
+ if (cursor == NULL)
return;
- }
- while (tracker_sparql_cursor_next (cursor, self->priv->cancellable, NULL)) {
- g_hash_table_insert (self->priv->previous_resources,
- g_strdup (tracker_sparql_cursor_get_string (cursor, 1, NULL)),
- g_strdup (tracker_sparql_cursor_get_string (cursor, 0, NULL)));
- }
-
- g_object_unref (cursor);
- g_string_free (select, TRUE);
+ while (tracker_sparql_cursor_next (cursor, job->cancellable, error))
+ {
+ g_hash_table_insert (job->previous_resources,
+ g_strdup (tracker_sparql_cursor_get_string (cursor, 1, NULL)),
+ g_strdup (tracker_sparql_cursor_get_string (cursor, 0, NULL)));
+ }
}
static void
-gd_gdata_ensure_tracker_connection (GdGDataMiner *self,
- GoaObject *object,
- GError **error)
+account_miner_job_ensure_datasource (AccountMinerJob *job,
+ GError **error)
{
GString *datasource_insert;
- GoaAccount *account;
- if (self->priv->connection != NULL)
- return;
-
- self->priv->connection =
- tracker_sparql_connection_get (self->priv->cancellable, error);
-
- if (*error != NULL)
- return;
-
- account = goa_object_peek_account (object);
datasource_insert = g_string_new (NULL);
g_string_append_printf (datasource_insert,
- "INSERT { <%s> a nie:DataSource ; nao:identifier \"goa:documents:%s\" }",
- DATASOURCE_URN, goa_account_get_id (account));
+ "INSERT OR REPLACE { <gd:goa-account:%s> a nie:DataSource ; nao:identifier \"%s\" }",
+ goa_account_get_id (job->account), MINER_IDENTIFIER);
- tracker_sparql_connection_update (self->priv->connection, datasource_insert->str,
- G_PRIORITY_DEFAULT, self->priv->cancellable,
+ tracker_sparql_connection_update (job->connection,
+ datasource_insert->str,
+ G_PRIORITY_DEFAULT,
+ job->cancellable,
error);
+
+ g_string_free (datasource_insert, TRUE);
}
-static void
-gd_gdata_miner_setup_account (GdGDataMiner *self,
- GoaObject *object)
+static gboolean
+account_miner_job (GIOSchedulerJob *sched_job,
+ GCancellable *cancellable,
+ gpointer user_data)
{
- GdGDataGoaAuthorizer *authorizer;
+ AccountMinerJob *job = user_data;
GError *error = NULL;
- authorizer = gd_gdata_goa_authorizer_new (object);
- self->priv->service =
- gdata_documents_service_new (GDATA_AUTHORIZER (authorizer));
+ account_miner_job_ensure_datasource (job, &error);
- /* the service takes ownership of the authorizer */
- g_object_unref (authorizer);
+ if (error != NULL)
+ goto out;
+
+ account_miner_job_query_existing (job, &error);
+
+ if (error != NULL)
+ goto out;
+
+ account_miner_job_query_gdata (job, &error);
- gd_gdata_ensure_tracker_connection (self, object, &error);
+ if (error != NULL)
+ goto out;
+
+ account_miner_job_cleanup_previous (job, &error);
+
+ if (error != NULL)
+ goto out;
+
+ out:
+ if (error != NULL)
+ g_simple_async_result_take_error (job->async_result, error);
+
+ g_simple_async_result_complete_in_idle (job->async_result);
+
+ return FALSE;
+}
+
+static void
+account_miner_job_process_async (AccountMinerJob *job,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_assert (job->async_result == NULL);
+
+ job->async_result = g_simple_async_result_new (NULL, callback, user_data,
+ account_miner_job_process_async);
+ g_simple_async_result_set_op_res_gpointer (job->async_result, job, NULL);
+
+ g_io_scheduler_push_job (account_miner_job, job, NULL,
+ G_PRIORITY_DEFAULT,
+ job->cancellable);
+}
+
+static gboolean
+account_miner_job_process_finish (GAsyncResult *res,
+ GError **error)
+{
+ GSimpleAsyncResult *simple_res = G_SIMPLE_ASYNC_RESULT (res);
+
+ g_assert (g_simple_async_result_is_valid (res, NULL,
+ account_miner_job_process_async));
+
+ if (g_simple_async_result_propagate_error (simple_res, error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+gd_gdata_miner_complete_error (GdGDataMiner *self,
+ GError *error)
+{
+ GList *l;
+
+ g_assert (self->priv->result != NULL);
+
+ g_simple_async_result_take_error (self->priv->result, error);
+ g_simple_async_result_complete_in_idle (self->priv->result);
+}
+
+static void
+gd_gdata_miner_check_pending_jobs (GdGDataMiner *self)
+{
+ if (g_list_length (self->priv->pending_jobs) == 0)
+ g_simple_async_result_complete_in_idle (self->priv->result);
+}
+
+static void
+miner_job_process_ready_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AccountMinerJob *job = user_data;
+ GdGDataMiner *self = job->self;
+ GError *error = NULL;
+
+ account_miner_job_process_finish (res, &error);
if (error != NULL)
{
- gd_gdata_miner_complete_error (self, error);
- return;
+ g_printerr ("Error while refreshing account %s: %s",
+ goa_account_get_id (job->account), error->message);
+
+ g_error_free (error);
}
- gd_gdata_miner_query_existing (self);
- gd_gdata_miner_query_gdata (self);
+ self->priv->pending_jobs = g_list_remove (self->priv->pending_jobs,
+ job);
+ account_miner_job_free (job);
+
+ gd_gdata_miner_check_pending_jobs (self);
+}
+
+static void
+gd_gdata_miner_setup_account (GdGDataMiner *self,
+ GoaObject *object)
+{
+ AccountMinerJob *job;
+
+ job = account_miner_job_new (self, object);
+ self->priv->pending_jobs = g_list_prepend (self->priv->pending_jobs, job);
+
+ account_miner_job_process_async (job, miner_job_process_ready_cb, job);
}
static void
@@ -803,18 +954,41 @@ client_ready_cb (GObject *source,
}
static void
+sparql_connection_ready_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GdGDataMiner *self = user_data;
+
+ self->priv->connection = tracker_sparql_connection_get_finish (res, &error);
+
+ if (error != NULL)
+ {
+ gd_gdata_miner_complete_error (self, error);
+ return;
+ }
+
+ goa_client_new (self->priv->cancellable, client_ready_cb, self);
+}
+
+static void
gd_gdata_miner_dispose (GObject *object)
{
GdGDataMiner *self = GD_GDATA_MINER (object);
- g_clear_object (&self->priv->service);
+ if (self->priv->pending_jobs != NULL)
+ {
+ g_list_free_full (self->priv->pending_jobs,
+ (GDestroyNotify) account_miner_job_free);
+ self->priv->pending_jobs = NULL;
+ }
+
g_clear_object (&self->priv->client);
g_clear_object (&self->priv->connection);
g_clear_object (&self->priv->cancellable);
g_clear_object (&self->priv->result);
- g_hash_table_unref (self->priv->previous_resources);
-
G_OBJECT_CLASS (gd_gdata_miner_parent_class)->dispose (object);
}
@@ -823,8 +997,6 @@ gd_gdata_miner_init (GdGDataMiner *self)
{
self->priv =
G_TYPE_INSTANCE_GET_PRIVATE (self, GD_TYPE_GDATA_MINER, GdGDataMinerPrivate);
- self->priv->previous_resources = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free, (GDestroyNotify) g_free);
}
static void
@@ -856,7 +1028,8 @@ gd_gdata_miner_refresh_db_async (GdGDataMiner *self,
self->priv->cancellable =
(cancellable != NULL) ? g_object_ref (cancellable) : NULL;
- goa_client_new (self->priv->cancellable, client_ready_cb, self);
+ tracker_sparql_connection_get_async (self->priv->cancellable,
+ sparql_connection_ready_cb, self);
}
gboolean
diff --git a/src/miner/gdata-miner-main.c b/src/miner/gdata-miner-main.c
index 4b7e967..1d6ed95 100644
--- a/src/miner/gdata-miner-main.c
+++ b/src/miner/gdata-miner-main.c
@@ -25,7 +25,7 @@
#include "gd-gdata-miner.h"
#define BUS_NAME "org.gnome.Documents.GDataMiner"
-#define AUTOQUIT_TIMEOUT 5
+#define AUTOQUIT_TIMEOUT 5 /* seconds */
static const gchar introspection_xml[] =
"<node>"
@@ -39,6 +39,43 @@ static GDBusNodeInfo *introspection_data = NULL;
static GCancellable *cancellable = NULL;
static GMainLoop *loop = NULL;
static guint name_owner_id = 0;
+static guint autoquit_id = 0;
+static gboolean refreshing = FALSE;
+
+static gboolean
+autoquit_timeout_cb (gpointer _unused)
+{
+ g_debug ("Timeout reached, quitting...");
+
+ autoquit_id = 0;
+ g_main_loop_quit (loop);
+
+ return FALSE;
+}
+
+static void
+ensure_autoquit_off (void)
+{
+ if (g_getenv ("GDATA_MINER_PERSIST") != NULL)
+ return;
+
+ if (autoquit_id != 0)
+ {
+ g_source_remove (autoquit_id);
+ autoquit_id = 0;
+ }
+}
+
+static void
+ensure_autoquit_on (void)
+{
+ if (g_getenv ("GDATA_MINER_PERSIST") != NULL)
+ return;
+
+ autoquit_id =
+ g_timeout_add_seconds (AUTOQUIT_TIMEOUT,
+ autoquit_timeout_cb, NULL);
+}
static gboolean
signal_handler_cb (gpointer user_data)
@@ -62,6 +99,7 @@ miner_refresh_db_ready_cb (GObject *source,
GError *error = NULL;
gd_gdata_miner_refresh_db_finish (GD_GDATA_MINER (source), res, &error);
+ refreshing = FALSE;
if (error != NULL)
{
@@ -73,8 +111,7 @@ miner_refresh_db_ready_cb (GObject *source,
g_dbus_method_invocation_return_value (invocation, NULL);
}
- g_object_unref (cancellable);
- g_main_loop_quit (loop);
+ ensure_autoquit_on ();
}
static void
@@ -82,6 +119,13 @@ handle_refresh_db (GDBusMethodInvocation *invocation)
{
GdGDataMiner *miner;
+ ensure_autoquit_off ();
+
+ /* if we're refreshing already, compress with the current request */
+ if (refreshing)
+ return;
+
+ refreshing = TRUE;
cancellable = g_cancellable_new ();
miner = gd_gdata_miner_new ();
@@ -169,6 +213,8 @@ main (int argc,
char **argv)
{
g_type_init ();
+
+ ensure_autoquit_on ();
loop = g_main_loop_new (NULL, FALSE);
g_unix_signal_add_full (G_PRIORITY_DEFAULT,
@@ -185,8 +231,7 @@ main (int argc,
name_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
BUS_NAME,
- G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
- G_BUS_NAME_OWNER_FLAGS_REPLACE,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
on_bus_acquired,
on_name_acquired,
on_name_lost,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]