[gnome-software/wip/hughsie/cachekey: 28/28] Allow GsApp objects to implement a custom cache key



commit 2ef318e48cb9b5f5b3e0d1f4608b59fbb241c559
Author: Richard Hughes <richard hughsie com>
Date:   Thu Jun 20 11:31:46 2019 +0100

    Allow GsApp objects to implement a custom cache key
    
    This allows us to maintain a plugin cache when the unique ID is not unique
    enough to disambiguate the objects. For instance, flatpak applications created
    from an AppStream search result do not have a "branch" set.
    
    Fixes https://gitlab.gnome.org/GNOME/gnome-software/issues/684

 lib/gs-app.c                       | 21 +++++++++++++++++++++
 lib/gs-app.h                       |  4 +++-
 lib/gs-plugin.c                    |  2 +-
 plugins/core/gs-appstream.c        |  2 +-
 plugins/flatpak/gs-flatpak-app.c   | 15 +++++++++++++++
 plugins/flatpak/gs-flatpak-utils.c |  5 +++++
 plugins/flatpak/gs-flatpak.c       | 14 ++++++++++----
 7 files changed, 56 insertions(+), 7 deletions(-)
---
diff --git a/lib/gs-app.c b/lib/gs-app.c
index 2447c604..6c97c644 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -1260,6 +1260,27 @@ gs_app_get_unique_id (GsApp *app)
        return gs_app_get_unique_id_unlocked (app);
 }
 
+/**
+ * gs_app_get_cache_key:
+ * @app: a #GsApp
+ *
+ * Gets the cache key used for de-duplication.
+ * If the plugin has not provided a custom #GsApp subclass with the `get_cache_key`
+ * vfunc implemented then gs_app_get_unique_id() will be used.
+ *
+ * Returns: A string ID suitable for deduplication
+ *
+ * Since: 3.34
+ **/
+const gchar *
+gs_app_get_cache_key (GsApp *app)
+{
+       GsAppClass *klass = GS_APP_GET_CLASS (app);
+       if (klass->get_cache_key != NULL)
+               return klass->get_cache_key (app);
+       return gs_app_get_unique_id (app);
+}
+
 /**
  * gs_app_set_unique_id:
  * @app: a #GsApp
diff --git a/lib/gs-app.h b/lib/gs-app.h
index cd185154..35240081 100644
--- a/lib/gs-app.h
+++ b/lib/gs-app.h
@@ -26,7 +26,8 @@ struct _GsAppClass
        GObjectClass             parent_class;
        void                     (*to_string)   (GsApp          *app,
                                                 GString        *str);
-       gpointer                 padding[30];
+       const gchar             *(*get_cache_key) (GsApp        *app);
+       gpointer                 padding[29];
 };
 
 /**
@@ -191,6 +192,7 @@ gboolean    gs_app_get_allow_cancel         (GsApp  *app);
 void           gs_app_set_allow_cancel          (GsApp *app,
                                                  gboolean      allow_cancel);
 const gchar    *gs_app_get_unique_id           (GsApp          *app);
+const gchar    *gs_app_get_cache_key           (GsApp          *app);
 const gchar    *gs_app_get_branch              (GsApp          *app);
 void            gs_app_set_branch              (GsApp          *app,
                                                 const gchar    *branch);
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index eeea069f..ea2f7c8b 100644
--- a/lib/gs-plugin.c
+++ b/lib/gs-plugin.c
@@ -1458,7 +1458,7 @@ gs_plugin_cache_add (GsPlugin *plugin, const gchar *key, GsApp *app)
 
        /* default */
        if (key == NULL)
-               key = gs_app_get_unique_id (app);
+               key = gs_app_get_cache_key (app);
 
        g_return_if_fail (key != NULL);
 
diff --git a/plugins/core/gs-appstream.c b/plugins/core/gs-appstream.c
index 39999437..37c5b13f 100644
--- a/plugins/core/gs-appstream.c
+++ b/plugins/core/gs-appstream.c
@@ -27,7 +27,7 @@ gs_appstream_create_app (GsPlugin *plugin, XbSilo *silo, XbNode *component, GErr
                return NULL;
 
        /* look for existing object */
-       app = gs_plugin_cache_lookup (plugin, gs_app_get_unique_id (app_new));
+       app = gs_plugin_cache_lookup (plugin, gs_app_get_cache_key (app_new));
        if (app != NULL)
                return app;
 
diff --git a/plugins/flatpak/gs-flatpak-app.c b/plugins/flatpak/gs-flatpak-app.c
index d2908ba0..0281d83e 100644
--- a/plugins/flatpak/gs-flatpak-app.c
+++ b/plugins/flatpak/gs-flatpak-app.c
@@ -50,6 +50,20 @@ gs_flatpak_app_file_kind_to_string (GsFlatpakAppFileKind file_kind)
        return NULL;
 }
 
+static const gchar *
+gs_flatpak_app_get_cache_key (GsApp *app)
+{
+       /* check exists */
+       if (gs_app_get_source_default (app) == NULL) {
+               g_autofree gchar *tmp = gs_app_to_string (app);
+               g_critical ("no source set for cache key: %s", tmp);
+               return gs_app_get_unique_id (app);
+       }
+
+       /* something like 'runtime/org.test.Runtime/x86_64/master' */
+       return gs_app_get_source_default (app);
+}
+
 static void
 gs_flatpak_app_to_string (GsApp *app, GString *str)
 {
@@ -276,6 +290,7 @@ gs_flatpak_app_class_init (GsFlatpakAppClass *klass)
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
        GsAppClass *klass_app = GS_APP_CLASS (klass);
        klass_app->to_string = gs_flatpak_app_to_string;
+       klass_app->get_cache_key = gs_flatpak_app_get_cache_key;
        object_class->finalize = gs_flatpak_app_finalize;
 }
 
diff --git a/plugins/flatpak/gs-flatpak-utils.c b/plugins/flatpak/gs-flatpak-utils.c
index 89cc3cf2..c2407009 100644
--- a/plugins/flatpak/gs-flatpak-utils.c
+++ b/plugins/flatpak/gs-flatpak-utils.c
@@ -59,6 +59,7 @@ gs_flatpak_app_new_from_remote (FlatpakRemote *xremote)
 {
        g_autofree gchar *title = NULL;
        g_autofree gchar *url = NULL;
+       g_autofree gchar *source = NULL;
        g_autoptr(GsApp) app = NULL;
 
        app = gs_flatpak_app_new (flatpak_remote_get_name (xremote));
@@ -70,6 +71,10 @@ gs_flatpak_app_new_from_remote (FlatpakRemote *xremote)
                         flatpak_remote_get_name (xremote));
        gs_app_set_size_download (app, GS_APP_SIZE_UNKNOWABLE);
 
+       /* for intra-plugin dedepe */
+       source = g_strdup_printf ("source/%s", flatpak_remote_get_name (xremote));
+       gs_app_add_source (app, source);
+
        /* title */
        title = flatpak_remote_get_title (xremote);
        if (title != NULL)
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
index 476f57cd..1fb8c986 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -205,6 +205,8 @@ gs_flatpak_set_update_permissions (GsFlatpak *self, GsApp *app, FlatpakInstalled
 static void
 gs_flatpak_set_metadata (GsFlatpak *self, GsApp *app, FlatpakRef *xref)
 {
+       g_autofree gchar *source = NULL;
+
        /* core */
        gs_flatpak_claim_app (self, app);
        gs_app_set_branch (app, flatpak_ref_get_branch (xref));
@@ -216,6 +218,10 @@ gs_flatpak_set_metadata (GsFlatpak *self, GsApp *app, FlatpakRef *xref)
        gs_flatpak_app_set_ref_arch (app, flatpak_ref_get_arch (xref));
        gs_flatpak_app_set_commit (app, flatpak_ref_get_commit (xref));
 
+       /* custom cachekey */
+       source = flatpak_ref_format_ref (xref);
+       gs_app_add_source (app, source);
+
        /* map the flatpak kind to the gnome-software kind */
        if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN ||
            gs_app_get_kind (app) == AS_APP_KIND_GENERIC) {
@@ -236,7 +242,7 @@ gs_flatpak_create_app (GsFlatpak *self, const gchar *origin, FlatpakRef *xref)
                gs_app_set_origin (app, origin);
 
        /* return the ref'd cached copy */
-       app_cached = gs_plugin_cache_lookup (self->plugin, gs_app_get_unique_id (app));
+       app_cached = gs_plugin_cache_lookup (self->plugin, gs_app_get_cache_key (app));
        if (app_cached != NULL)
                return app_cached;
 
@@ -270,7 +276,7 @@ gs_flatpak_create_source (GsFlatpak *self, FlatpakRemote *xremote)
        gs_flatpak_claim_app (self, app);
 
        /* we already have one, returned the ref'd cached copy */
-       app_cached = gs_plugin_cache_lookup (self->plugin, gs_app_get_unique_id (app));
+       app_cached = gs_plugin_cache_lookup (self->plugin, gs_app_get_cache_key (app));
        if (app_cached != NULL)
                return app_cached;
 
@@ -1779,7 +1785,7 @@ gs_flatpak_create_runtime (GsFlatpak *self, GsApp *parent, const gchar *runtime)
        gs_app_set_branch (app, split[2]);
 
        /* search in the cache */
-       app_cache = gs_plugin_cache_lookup (self->plugin, gs_app_get_unique_id (app));
+       app_cache = gs_plugin_cache_lookup (self->plugin, gs_app_get_cache_key (app));
        if (app_cache != NULL) {
                /* since the cached runtime can have been created somewhere else
                 * (we're using a global cache), we need to make sure that a
@@ -1792,7 +1798,7 @@ gs_flatpak_create_runtime (GsFlatpak *self, GsApp *parent, const gchar *runtime)
        /* if the app is per-user we can also use the installed system runtime */
        if (gs_app_get_scope (parent) == AS_APP_SCOPE_USER) {
                gs_app_set_scope (app, AS_APP_SCOPE_UNKNOWN);
-               app_cache = gs_plugin_cache_lookup (self->plugin, gs_app_get_unique_id (app));
+               app_cache = gs_plugin_cache_lookup (self->plugin, gs_app_get_cache_key (app));
                if (app_cache != NULL)
                        return g_steal_pointer (&app_cache);
        }


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