[gnome-online-miners/wip/rishi/miner-initable] application, miner: Make GomMiner fallible




commit 5a412991f6e6e5b7857e46e9020b1ca8f33c9e35
Author: Sam Thursfield <sam afuera me uk>
Date:   Fri May 15 01:11:24 2020 +0200

    application, miner: Make GomMiner fallible
    
    This allows for better error reporting. Instead of logging a CRITICAL
    about the context of the error, prefix it to the GError so that it can
    be sent back to the caller.
    
    https://gitlab.gnome.org/GNOME/gnome-online-miners/-/merge_requests/3
    https://gitlab.gnome.org/GNOME/gnome-online-miners/-/merge_requests/6

 src/gom-application.c |  42 ++++++++++++++++++--
 src/gom-miner.c       | 105 +++++++++++++++++++++-----------------------------
 2 files changed, 82 insertions(+), 65 deletions(-)
---
diff --git a/src/gom-application.c b/src/gom-application.c
index fadd388..0c42d56 100644
--- a/src/gom-application.c
+++ b/src/gom-application.c
@@ -33,6 +33,7 @@ struct _GomApplication
 {
   GApplication parent;
   GCancellable *cancellable;
+  GError *miner_error;
   GomDBus *skeleton;
   GomMiner *miner;
   GQueue *queue;
@@ -89,6 +90,12 @@ gom_application_insert_shared_content (GomApplication *self,
                                        const gchar *shared_type,
                                        const gchar *source_urn)
 {
+  if (G_UNLIKELY (self->miner == NULL))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, self->miner_error);
+      goto out;
+    }
+
   g_application_hold (G_APPLICATION (self));
   gom_miner_insert_shared_content_async (self->miner,
                                          account_id,
@@ -98,6 +105,8 @@ gom_application_insert_shared_content (GomApplication *self,
                                          self->cancellable,
                                          gom_application_insert_shared_content_cb,
                                          g_object_ref (invocation));
+
+ out:
   return TRUE;
 }
 
@@ -107,6 +116,8 @@ gom_application_process_queue (GomApplication *self)
   GDBusMethodInvocation *invocation = NULL;
   const gchar **index_types;
 
+  g_assert (GOM_IS_MINER (self->miner));
+
   if (self->refreshing)
     goto out;
 
@@ -163,10 +174,18 @@ gom_application_refresh_db (GomApplication *self,
 {
   gchar **index_types;
 
+  if (G_UNLIKELY (self->miner == NULL))
+    {
+      g_dbus_method_invocation_return_gerror (invocation, self->miner_error);
+      goto out;
+    }
+
   index_types = g_strdupv ((gchar **) arg_index_types);
   g_object_set_data_full (G_OBJECT (invocation), "index-types", index_types, (GDestroyNotify) g_strfreev);
   g_queue_push_tail (self->queue, g_object_ref (invocation));
   gom_application_process_queue (self);
+
+ out:
   return TRUE;
 }
 
@@ -228,13 +247,17 @@ static void
 gom_application_constructed (GObject *object)
 {
   GomApplication *self = GOM_APPLICATION (object);
-  const gchar *display_name;
 
   G_OBJECT_CLASS (gom_application_parent_class)->constructed (object);
 
-  self->miner = g_object_new (self->miner_type, NULL);
-  display_name = gom_miner_get_display_name (self->miner);
-  gom_dbus_set_display_name (self->skeleton, display_name);
+  self->miner = g_initable_new (self->miner_type, NULL, &self->miner_error, NULL);
+  if (G_LIKELY (self->miner != NULL))
+    {
+      const gchar *display_name;
+
+      display_name = gom_miner_get_display_name (self->miner);
+      gom_dbus_set_display_name (self->skeleton, display_name);
+    }
 }
 
 static void
@@ -255,6 +278,16 @@ gom_application_dispose (GObject *object)
   G_OBJECT_CLASS (gom_application_parent_class)->dispose (object);
 }
 
+static void
+gom_application_finalize (GObject *object)
+{
+  GomApplication *self = GOM_APPLICATION (object);
+
+  g_clear_error (&self->miner_error);
+
+  G_OBJECT_CLASS (gom_application_parent_class)->finalize (object);
+}
+
 static void
 gom_application_set_property (GObject *object,
                               guint prop_id,
@@ -298,6 +331,7 @@ gom_application_class_init (GomApplicationClass *klass)
 
   oclass->constructed = gom_application_constructed;
   oclass->dispose = gom_application_dispose;
+  oclass->finalize = gom_application_finalize;
   oclass->set_property = gom_application_set_property;
   application_class->dbus_register = gom_application_dbus_register;
   application_class->dbus_unregister = gom_application_dbus_unregister;
diff --git a/src/gom-miner.c b/src/gom-miner.c
index 7147b33..9b4803d 100644
--- a/src/gom-miner.c
+++ b/src/gom-miner.c
@@ -28,15 +28,15 @@
 
 #include "gom-miner.h"
 
-G_DEFINE_TYPE (GomMiner, gom_miner, G_TYPE_OBJECT)
+static void gom_miner_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GomMiner, gom_miner, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gom_miner_initable_iface_init))
 
 struct _GomMinerPrivate {
   GoaClient *client;
-  GError *client_error;
-
   TrackerSparqlConnection *connection;
-  GError *connection_error;
-
+  gboolean is_initialized;
   gchar *display_name;
   gchar **index_types;
 };
@@ -125,14 +125,12 @@ gom_miner_dispose (GObject *object)
 
   g_free (self->priv->display_name);
   g_strfreev (self->priv->index_types);
-  g_clear_error (&self->priv->client_error);
-  g_clear_error (&self->priv->connection_error);
 
   G_OBJECT_CLASS (gom_miner_parent_class)->dispose (object);
 }
 
 static void
-gom_miner_init_goa (GomMiner *self)
+gom_miner_init_goa (GomMiner *self, GError **error)
 {
   GoaAccount *account;
   GoaObject *object;
@@ -140,14 +138,10 @@ gom_miner_init_goa (GomMiner *self)
   GList *accounts, *l;
   GomMinerClass *miner_class = GOM_MINER_GET_CLASS (self);
 
-  self->priv->client = goa_client_new_sync (NULL, &self->priv->client_error);
+  self->priv->client = goa_client_new_sync (NULL, error);
 
-  if (self->priv->client_error != NULL)
-    {
-      g_critical ("Unable to create GoaClient: %s - indexing for %s will not work",
-                  self->priv->client_error->message, miner_class->goa_provider_type);
-      return;
-    }
+  if (self->priv->client == NULL)
+    return;
 
   accounts = goa_client_get_accounts (self->priv->client);
   for (l = accounts; l != NULL; l = l->next)
@@ -170,16 +164,6 @@ gom_miner_init_goa (GomMiner *self)
   g_list_free_full (accounts, g_object_unref);
 }
 
-static void
-gom_miner_constructed (GObject *obj)
-{
-  GomMiner *self = GOM_MINER (obj);
-
-  G_OBJECT_CLASS (gom_miner_parent_class)->constructed (obj);
-
-  gom_miner_init_goa (self);
-}
-
 static void
 gom_miner_init (GomMiner *self)
 {
@@ -187,14 +171,6 @@ gom_miner_init (GomMiner *self)
 
   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GOM_TYPE_MINER, GomMinerPrivate);
   self->priv->display_name = g_strdup ("");
-
-  self->priv->connection = tracker_sparql_connection_get (NULL, &self->priv->connection_error);
-  if (self->priv->connection_error != NULL)
-    {
-      g_critical ("Unable to create TrackerSparqlConnection: %s - indexing for %s will not work",
-                  self->priv->connection_error->message,
-                  klass->goa_provider_type);
-    }
 }
 
 static void
@@ -202,7 +178,6 @@ gom_miner_class_init (GomMinerClass *klass)
 {
   GObjectClass *oclass = G_OBJECT_CLASS (klass);
 
-  oclass->constructed = gom_miner_constructed;
   oclass->dispose = gom_miner_dispose;
 
   cleanup_pool = g_thread_pool_new (cleanup_job, NULL, 1, FALSE, NULL);
@@ -210,6 +185,41 @@ gom_miner_class_init (GomMinerClass *klass)
   g_type_class_add_private (klass, sizeof (GomMinerPrivate));
 }
 
+static gboolean
+gom_miner_initable_init (GInitable *initable, GCancellable *cancellable, GError **error)
+{
+  GomMiner *self = GOM_MINER (initable);
+  gboolean ret_val = FALSE;
+
+  g_return_val_if_fail (!self->priv->is_initialized, FALSE);
+
+  self->priv->connection = tracker_sparql_connection_get (cancellable, error);
+  if (G_UNLIKELY (self->priv->connection == NULL))
+    {
+      g_prefix_error (error, "Unable to connect to Tracker store: ");
+      goto out;
+    }
+
+  gom_miner_init_goa (self, error);
+  if (G_UNLIKELY (self->priv->client == NULL))
+    {
+      g_prefix_error (error, "Unable to connect to GNOME Online Accounts: ");
+      goto out;
+    }
+
+  ret_val = TRUE;
+
+ out:
+  self->priv->is_initialized = TRUE;
+  return ret_val;
+}
+
+static void
+gom_miner_initable_iface_init (GInitableIface *iface)
+{
+  iface->init = gom_miner_initable_init;
+}
+
 static void
 gom_miner_check_pending_jobs (GTask *task)
 {
@@ -821,18 +831,6 @@ gom_miner_insert_shared_content_async (GomMiner *self,
   task = g_task_new (self, cancellable, callback, user_data);
   g_task_set_source_tag (task, gom_miner_insert_shared_content_async);
 
-  if (self->priv->client_error != NULL)
-    {
-      g_task_return_error (task, g_error_copy (self->priv->client_error));
-      goto out;
-    }
-
-  if (self->priv->connection_error != NULL)
-    {
-      g_task_return_error (task, g_error_copy (self->priv->connection_error));
-      goto out;
-    }
-
   object = goa_client_lookup_by_id (self->priv->client, account_id);
   if (object == NULL)
     {
@@ -895,22 +893,7 @@ gom_miner_refresh_db_async (GomMiner *self,
 
   task = g_task_new (self, cancellable, callback, user_data);
   g_task_set_source_tag (task, gom_miner_refresh_db_async);
-
-  if (self->priv->client_error != NULL)
-    {
-      g_task_return_error (task, g_error_copy (self->priv->client_error));
-      goto out;
-    }
-
-  if (self->priv->connection_error != NULL)
-    {
-      g_task_return_error (task, g_error_copy (self->priv->connection_error));
-      goto out;
-    }
-
   gom_miner_refresh_db_real (self, task);
-
- out:
   g_clear_object (&task);
 }
 


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