[gnome-software/wip/hughsie/unique-id-hash: 6/6] Allow plugins to optionally share a global cache



commit 3ab931d194a1d4598ed02875c3676cbd280b7b00
Author: Richard Hughes <richard hughsie com>
Date:   Thu Aug 25 18:47:26 2016 +0100

    Allow plugins to optionally share a global cache
    
    This means the plugins HAVE to use the unique_id as the key, and also
    explicitly opt-in to the new shared cache.

 src/gs-plugin-loader.c                 |    4 ++
 src/gs-plugin-private.h                |    2 +
 src/gs-plugin.c                        |   49 +++++++++++++++++++++++++++++--
 src/gs-plugin.h                        |    2 +
 src/gs-self-test.c                     |   39 ++++++++++++++++++++++++-
 src/plugins/gs-plugin-appstream.c      |    3 ++
 src/plugins/gs-plugin-flatpak-system.c |    3 ++
 src/plugins/gs-plugin-flatpak-user.c   |    3 ++
 8 files changed, 100 insertions(+), 5 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index f0b929e..83a9fb3 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -43,6 +43,7 @@ typedef struct
        gchar                   *locale;
        gchar                   *language;
        GsPluginStatus           status_last;
+       GsAppList               *global_cache;
        AsProfile               *profile;
        SoupSession             *soup_session;
        GPtrArray               *auth_array;
@@ -3470,6 +3471,7 @@ gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
        gs_plugin_set_locale (plugin, priv->locale);
        gs_plugin_set_language (plugin, priv->language);
        gs_plugin_set_scale (plugin, gs_plugin_loader_get_scale (plugin_loader));
+       gs_plugin_set_global_cache (plugin, priv->global_cache);
        g_debug ("opened plugin %s: %s", filename, gs_plugin_get_name (plugin));
 
        /* add to array */
@@ -3865,6 +3867,7 @@ gs_plugin_loader_finalize (GObject *object)
        g_free (priv->location);
        g_free (priv->locale);
        g_free (priv->language);
+       g_object_unref (priv->global_cache);
 
        g_mutex_clear (&priv->pending_apps_mutex);
 
@@ -3915,6 +3918,7 @@ gs_plugin_loader_init (GsPluginLoader *plugin_loader)
        guint i;
 
        priv->scale = 1;
+       priv->global_cache = gs_app_list_new ();
        priv->plugins = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
        priv->status_last = GS_PLUGIN_STATUS_LAST;
        priv->pending_apps = g_ptr_array_new_with_free_func ((GFreeFunc) g_object_unref);
diff --git a/src/gs-plugin-private.h b/src/gs-plugin-private.h
index 3566449..c9cf71a 100644
--- a/src/gs-plugin-private.h
+++ b/src/gs-plugin-private.h
@@ -56,6 +56,8 @@ void           gs_plugin_set_auth_array               (GsPlugin       *plugin,
                                                         GPtrArray      *auth_array);
 void            gs_plugin_set_soup_session             (GsPlugin       *plugin,
                                                         SoupSession    *soup_session);
+void            gs_plugin_set_global_cache             (GsPlugin       *plugin,
+                                                        GsAppList      *global_cache);
 void            gs_plugin_set_running_other            (GsPlugin       *plugin,
                                                         gboolean        running_other);
 GPtrArray      *gs_plugin_get_rules                    (GsPlugin       *plugin,
diff --git a/src/gs-plugin.c b/src/gs-plugin.c
index a51e005..5d37fd8 100644
--- a/src/gs-plugin.c
+++ b/src/gs-plugin.c
@@ -63,6 +63,7 @@ typedef struct
        GsPluginData            *data;                  /* for gs-plugin-{name}.c */
        GsPluginFlags            flags;
        SoupSession             *soup_session;
+       GsAppList               *global_cache;
        GPtrArray               *rules[GS_PLUGIN_RULE_LAST];
        gboolean                 enabled;
        gchar                   *locale;                /* allow-none */
@@ -192,12 +193,17 @@ gs_plugin_finalize (GObject *object)
        g_free (priv->language);
        g_rw_lock_clear (&priv->rwlock);
        g_object_unref (priv->profile);
-       g_ptr_array_unref (priv->auth_array);
-       g_object_unref (priv->soup_session);
+       if (priv->auth_array != NULL)
+               g_ptr_array_unref (priv->auth_array);
+       if (priv->soup_session != NULL)
+               g_object_unref (priv->soup_session);
+       if (priv->global_cache != NULL)
+               g_object_unref (priv->global_cache);
        g_hash_table_unref (priv->cache);
        g_mutex_clear (&priv->cache_mutex);
        g_mutex_clear (&priv->timer_mutex);
-       g_module_close (priv->module);
+       if (priv->module != NULL)
+               g_module_close (priv->module);
 }
 
 /**
@@ -681,6 +687,22 @@ gs_plugin_set_soup_session (GsPlugin *plugin, SoupSession *soup_session)
 }
 
 /**
+ * gs_plugin_set_global_cache:
+ * @plugin: a #GsPlugin
+ * @global_cache: a #GsAppList
+ *
+ * Sets the global cache that plugins can opt to use.
+ *
+ * Since: 3.22
+ **/
+void
+gs_plugin_set_global_cache (GsPlugin *plugin, GsAppList *global_cache)
+{
+       GsPluginPrivate *priv = gs_plugin_get_instance_private (plugin);
+       g_set_object (&priv->global_cache, global_cache);
+}
+
+/**
  * gs_plugin_has_flags:
  * @plugin: a #GsPlugin
  * @flags: a #GsPluginFlags, e.g. %GS_PLUGIN_FLAGS_RUNNING_SELF
@@ -1170,7 +1192,16 @@ gs_plugin_cache_lookup (GsPlugin *plugin, const gchar *key)
        g_return_val_if_fail (GS_IS_PLUGIN (plugin), NULL);
        g_return_val_if_fail (key != NULL, NULL);
 
-       app = g_hash_table_lookup (priv->cache, key);
+       /* global, so using a unique_id */
+       if (gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_GLOBAL_CACHE)) {
+               if (!as_utils_unique_id_valid (key)) {
+                       g_critical ("key %s is not a unique_id", key);
+                       return NULL;
+               }
+               app = gs_app_list_lookup (priv->global_cache, key);
+       } else {
+               app = g_hash_table_lookup (priv->cache, key);
+       }
        if (app == NULL)
                return NULL;
        return g_object_ref (app);
@@ -1197,6 +1228,16 @@ gs_plugin_cache_add (GsPlugin *plugin, const gchar *key, GsApp *app)
        g_return_if_fail (key != NULL);
        g_return_if_fail (GS_IS_APP (app));
 
+       /* global, so using internal unique_id */
+       if (gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_GLOBAL_CACHE)) {
+               if (!as_utils_unique_id_valid (key)) {
+                       g_critical ("key %s is not a unique_id", key);
+                       return;
+               }
+               gs_app_list_add (priv->global_cache, app);
+               return;
+       }
+
        if (g_hash_table_lookup (priv->cache, key) == app)
                return;
        g_hash_table_insert (priv->cache, g_strdup (key), g_object_ref (app));
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index 653216b..7c34db9 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -85,6 +85,7 @@ typedef enum {
  * @GS_PLUGIN_FLAGS_RUNNING_OTHER:     Another plugin is running
  * @GS_PLUGIN_FLAGS_EXCLUSIVE:         An exclusive action is running
  * @GS_PLUGIN_FLAGS_RECENT:            This plugin recently ran
+ * @GS_PLUGIN_FLAGS_GLOBAL_CACHE:      Use the global app cache
  *
  * The flags for the plugin at this point in time.
  **/
@@ -93,6 +94,7 @@ typedef enum {
 #define GS_PLUGIN_FLAGS_RUNNING_OTHER  (1u << 1)
 #define GS_PLUGIN_FLAGS_EXCLUSIVE      (1u << 2)
 #define GS_PLUGIN_FLAGS_RECENT         (1u << 3)
+#define GS_PLUGIN_FLAGS_GLOBAL_CACHE   (1u << 4)
 typedef guint64 GsPluginFlags;
 
 /**
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index cec0caa..4b03881 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -29,7 +29,7 @@
 #include "gs-app-private.h"
 #include "gs-app-list-private.h"
 #include "gs-os-release.h"
-#include "gs-plugin.h"
+#include "gs-plugin-private.h"
 #include "gs-plugin-loader.h"
 #include "gs-plugin-loader-sync.h"
 #include "gs-utils.h"
@@ -89,6 +89,42 @@ gs_os_release_func (void)
 }
 
 static void
+gs_plugin_global_cache_func (void)
+{
+       const gchar *unique_id;
+       g_autoptr(GsPlugin) plugin1 = NULL;
+       g_autoptr(GsPlugin) plugin2 = NULL;
+       g_autoptr(GsAppList) list = gs_app_list_new ();
+       g_autoptr(GsApp) app = gs_app_new ("gimp.desktop");
+       g_autoptr(GsApp) app1 = NULL;
+       g_autoptr(GsApp) app2 = NULL;
+
+       plugin1 = gs_plugin_new ();
+       gs_plugin_set_global_cache (plugin1, list);
+
+       plugin2 = gs_plugin_new ();
+       gs_plugin_set_global_cache (plugin2, list);
+
+       /* both plugins not opted into the global cache */
+       unique_id = gs_app_get_unique_id (app);
+       gs_plugin_cache_add (plugin1, unique_id, app);
+       g_assert (gs_plugin_cache_lookup (plugin2, unique_id) == NULL);
+       app1 = gs_plugin_cache_lookup (plugin1, unique_id);
+       g_assert (app1 != NULL);
+
+       /* one plugin opted in */
+       gs_plugin_add_flags (plugin1, GS_PLUGIN_FLAGS_GLOBAL_CACHE);
+       gs_plugin_cache_add (plugin1, unique_id, app);
+       g_assert (gs_plugin_cache_lookup (plugin2, unique_id) == NULL);
+
+       /* both plugins opted in */
+       gs_plugin_add_flags (plugin2, GS_PLUGIN_FLAGS_GLOBAL_CACHE);
+       gs_plugin_cache_add (plugin1, unique_id, app);
+       app2 = gs_plugin_cache_lookup (plugin2, unique_id);
+       g_assert (app2 != NULL);
+}
+
+static void
 gs_plugin_func (void)
 {
        GsAppList *list;
@@ -1244,6 +1280,7 @@ main (int argc, char **argv)
        g_test_add_func ("/gnome-software/os-release", gs_os_release_func);
        g_test_add_func ("/gnome-software/app", gs_app_func);
        g_test_add_func ("/gnome-software/plugin", gs_plugin_func);
+       g_test_add_func ("/gnome-software/plugin{global-cache}", gs_plugin_global_cache_func);
        g_test_add_func ("/gnome-software/auth{secret}", gs_auth_secret_func);
 
        /* we can only load this once per process */
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index ff2adfe..40cb544 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -144,6 +144,9 @@ gs_plugin_initialize (GsPlugin *plugin)
                                  AS_STORE_WATCH_FLAG_ADDED |
                                  AS_STORE_WATCH_FLAG_REMOVED);
 
+       /* set plugin flags */
+       gs_plugin_add_flags (plugin, GS_PLUGIN_FLAGS_GLOBAL_CACHE);
+
        /* need package name */
        gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "dpkg");
 }
diff --git a/src/plugins/gs-plugin-flatpak-system.c b/src/plugins/gs-plugin-flatpak-system.c
index 2d6eae9..0c4b993 100644
--- a/src/plugins/gs-plugin-flatpak-system.c
+++ b/src/plugins/gs-plugin-flatpak-system.c
@@ -46,6 +46,9 @@ gs_plugin_initialize (GsPlugin *plugin)
        priv->flatpak = gs_flatpak_new (plugin, GS_FLATPAK_SCOPE_SYSTEM);
        priv->settings = g_settings_new ("org.gnome.software");
 
+       /* set plugin flags */
+       gs_plugin_add_flags (plugin, GS_PLUGIN_FLAGS_GLOBAL_CACHE);
+
        /* getting app properties from appstream is quicker */
        gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "appstream");
 
diff --git a/src/plugins/gs-plugin-flatpak-user.c b/src/plugins/gs-plugin-flatpak-user.c
index 3b64858..97b0421 100644
--- a/src/plugins/gs-plugin-flatpak-user.c
+++ b/src/plugins/gs-plugin-flatpak-user.c
@@ -46,6 +46,9 @@ gs_plugin_initialize (GsPlugin *plugin)
        priv->flatpak = gs_flatpak_new (plugin, GS_FLATPAK_SCOPE_USER);
        priv->settings = g_settings_new ("org.gnome.software");
 
+       /* set plugin flags */
+       gs_plugin_add_flags (plugin, GS_PLUGIN_FLAGS_GLOBAL_CACHE);
+
        /* getting app properties from appstream is quicker */
        gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "appstream");
 


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