[gnome-software] Use the plugin cache in more places



commit 4f927d476faf204c56c96b1d0e26b27913039123
Author: Richard Hughes <richard hughsie com>
Date:   Mon May 23 17:53:21 2016 +0100

    Use the plugin cache in more places
    
    This speeds up gnome-software considerably and fixes a few UI-update bugs.

 src/gs-app.c                                   |    3 +-
 src/gs-plugin.c                                |   13 +++++++-
 src/gs-self-test.c                             |   36 ++++++++++++++++++++++
 src/plugins/gs-appstream.c                     |   18 ++++++++--
 src/plugins/gs-appstream.h                     |    3 +-
 src/plugins/gs-plugin-appstream.c              |   26 ++++++++++++----
 src/plugins/gs-plugin-dummy.c                  |   16 ++++++++--
 src/plugins/gs-plugin-fedora-distro-upgrades.c |   15 +++++++++
 src/plugins/gs-plugin-flatpak.c                |   10 ++++--
 src/plugins/gs-plugin-hardcoded-popular.c      |   12 +++++++
 src/plugins/gs-plugin-shell-extensions.c       |   39 +++++++++++++++++++----
 src/plugins/gs-plugin-systemd-updates.c        |   17 ++++++++++
 12 files changed, 181 insertions(+), 27 deletions(-)
---
diff --git a/src/gs-app.c b/src/gs-app.c
index 9550117..ddb6d60 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -182,7 +182,8 @@ gs_app_to_string (GsApp *app)
 
        g_return_val_if_fail (GS_IS_APP (app), NULL);
 
-       str = g_string_new ("GsApp:\n");
+       str = g_string_new ("GsApp:");
+       g_string_append_printf (str, " [%p]\n", app);
        gs_app_kv_lpad (str, "kind", as_app_kind_to_string (app->kind));
        if (app->last_error != NULL)
                gs_app_kv_lpad (str, "last-error", app->last_error->message);
diff --git a/src/gs-plugin.c b/src/gs-plugin.c
index 411e3b1..8953405 100644
--- a/src/gs-plugin.c
+++ b/src/gs-plugin.c
@@ -909,7 +909,12 @@ GsApp *
 gs_plugin_cache_lookup (GsPlugin *plugin, const gchar *key)
 {
        GsPluginPrivate *priv = gs_plugin_get_instance_private (plugin);
-       GsApp *app = g_hash_table_lookup (priv->cache, key);
+       GsApp *app;
+
+       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);
        if (app == NULL)
                return NULL;
        return g_object_ref (app);
@@ -928,6 +933,11 @@ void
 gs_plugin_cache_add (GsPlugin *plugin, const gchar *key, GsApp *app)
 {
        GsPluginPrivate *priv = gs_plugin_get_instance_private (plugin);
+
+       g_return_if_fail (GS_IS_PLUGIN (plugin));
+       g_return_if_fail (key != NULL);
+       g_return_if_fail (GS_IS_APP (app));
+
        if (g_hash_table_lookup (priv->cache, key) == app)
                return;
        g_hash_table_insert (priv->cache, g_strdup (key), g_object_ref (app));
@@ -944,6 +954,7 @@ void
 gs_plugin_cache_invalidate (GsPlugin *plugin)
 {
        GsPluginPrivate *priv = gs_plugin_get_instance_private (plugin);
+       g_return_if_fail (GS_IS_PLUGIN (plugin));
        g_hash_table_remove_all (priv->cache);
 }
 
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index 1222555..507c794 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -797,6 +797,39 @@ gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
        g_assert (!g_file_test (desktop_fn, G_FILE_TEST_IS_REGULAR));
 }
 
+static void
+gs_plugin_loader_plugin_cache_func (GsPluginLoader *plugin_loader)
+{
+       GsApp *app1;
+       GsApp *app2;
+       g_autoptr(GError) error = NULL;
+       g_autoptr(GsAppList) list1 = NULL;
+       g_autoptr(GsAppList) list2 = NULL;
+
+       /* ensure we get the same results back from calling the methods twice */
+       list1 = gs_plugin_loader_get_distro_upgrades (plugin_loader,
+                                                     GS_PLUGIN_REFINE_FLAGS_DEFAULT,
+                                                     NULL,
+                                                     &error);
+       g_assert_no_error (error);
+       g_assert (list1 != NULL);
+       g_assert_cmpint (gs_app_list_length (list1), ==, 1);
+       app1 = gs_app_list_index (list1, 0);
+
+       list2 = gs_plugin_loader_get_distro_upgrades (plugin_loader,
+                                                     GS_PLUGIN_REFINE_FLAGS_DEFAULT,
+                                                     NULL,
+                                                     &error);
+       g_assert_no_error (error);
+       g_assert (list2 != NULL);
+       g_assert_cmpint (gs_app_list_length (list2), ==, 1);
+       app2 = gs_app_list_index (list2, 0);
+
+       /* make sure there is one GObject */
+       g_assert_cmpstr (gs_app_get_id (app1), ==, gs_app_get_id (app2));
+       g_assert (app1 == app2);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -932,6 +965,9 @@ main (int argc, char **argv)
        g_assert (gs_plugin_loader_get_enabled (plugin_loader, "dummy"));
 
        /* plugin tests go here */
+       g_test_add_data_func ("/gnome-software/plugin-loader{plugin-cache}",
+                             plugin_loader,
+                             (GTestDataFunc) gs_plugin_loader_plugin_cache_func);
        g_test_add_data_func ("/gnome-software/plugin-loader{flatpak}",
                              plugin_loader,
                              (GTestDataFunc) gs_plugin_loader_flatpak_func);
diff --git a/src/plugins/gs-appstream.c b/src/plugins/gs-appstream.c
index f17360c..4bb0c23 100644
--- a/src/plugins/gs-appstream.c
+++ b/src/plugins/gs-appstream.c
@@ -214,7 +214,9 @@ gs_appstream_copy_metadata (GsApp *app, AsApp *item)
 }
 
 GsApp *
-gs_appstream_create_runtime (GsApp *parent, const gchar *runtime)
+gs_appstream_create_runtime (GsPlugin *plugin,
+                            GsApp *parent,
+                            const gchar *runtime)
 {
        const gchar *id_parent;
        g_autofree gchar *id = NULL;
@@ -241,6 +243,11 @@ gs_appstream_create_runtime (GsApp *parent, const gchar *runtime)
                id = g_strdup_printf ("%s.runtime", runtime_split[0]);
        }
 
+       /* search in the cache */
+       app = gs_plugin_cache_lookup (plugin, id);
+       if (app != NULL)
+               return g_steal_pointer (&app);
+
        /* create the complete GsApp from the single string */
        app = gs_app_new (id);
        source = g_strdup_printf ("runtime/%s", runtime);
@@ -248,11 +255,14 @@ gs_appstream_create_runtime (GsApp *parent, const gchar *runtime)
        gs_app_set_kind (app, AS_APP_KIND_RUNTIME);
        gs_app_set_version (app, runtime_split[2]);
 
+       /* save in the cache */
+       gs_plugin_cache_add (plugin, id, app);
+
        return g_steal_pointer (&app);
 }
 
 static void
-gs_refine_item_management_plugin (GsApp *app, AsApp *item)
+gs_refine_item_management_plugin (GsPlugin *plugin, GsApp *app, AsApp *item)
 {
        GPtrArray *bundles;
        const gchar *management_plugin = NULL;
@@ -281,7 +291,7 @@ gs_refine_item_management_plugin (GsApp *app, AsApp *item)
                        runtime = as_bundle_get_runtime (bundle);
                        if (runtime != NULL) {
                                g_autoptr(GsApp) app2 = NULL;
-                               app2 = gs_appstream_create_runtime (app, runtime);
+                               app2 = gs_appstream_create_runtime (plugin, app, runtime);
                                if (app2 != NULL) {
                                        g_debug ("runtime for %s is %s",
                                                 gs_app_get_id (app), runtime);
@@ -429,7 +439,7 @@ gs_appstream_refine_app (GsPlugin *plugin,
        }
 
        /* set management plugin automatically */
-       gs_refine_item_management_plugin (app, item);
+       gs_refine_item_management_plugin (plugin, app, item);
 
        /* set id */
        if (as_app_get_id (item) != NULL && gs_app_get_id (app) == NULL)
diff --git a/src/plugins/gs-appstream.h b/src/plugins/gs-appstream.h
index b6ef2a8..6e2a4d6 100644
--- a/src/plugins/gs-appstream.h
+++ b/src/plugins/gs-appstream.h
@@ -30,7 +30,8 @@ gboolean       gs_appstream_refine_app                (GsPlugin       *plugin,
                                                         GsApp          *app,
                                                         AsApp          *item,
                                                         GError         **error);
-GsApp          *gs_appstream_create_runtime            (GsApp          *parent,
+GsApp          *gs_appstream_create_runtime            (GsPlugin       *plugin,
+                                                        GsApp          *parent,
                                                         const gchar    *runtime);
 
 G_END_DECLS
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index a5bae2c..093cad6 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -45,6 +45,9 @@ gs_plugin_appstream_store_changed_cb (AsStore *store, GsPlugin *plugin)
 {
        g_debug ("AppStream metadata changed");
 
+       /* cache no longer valid */
+       gs_plugin_cache_invalidate (plugin);
+
        /* this is not strictly true, but it causes all the UI to be reloaded
         * which is what we really want */
        if (!gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_RUNNING_OTHER))
@@ -300,6 +303,17 @@ gs_plugin_refine_from_pkgname (GsPlugin *plugin,
        return gs_appstream_refine_app (plugin, app, item, error);
 }
 
+static GsApp *
+gs_plugin_appstream_create_app (GsPlugin *plugin, const gchar *id)
+{
+       GsApp *app = gs_plugin_cache_lookup (plugin, id);
+       if (app == NULL) {
+               app = gs_app_new (id);
+               gs_plugin_cache_add (plugin, id, app);
+       }
+       return app;
+}
+
 gboolean
 gs_plugin_add_distro_upgrades (GsPlugin *plugin,
                               GsAppList *list,
@@ -320,7 +334,7 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
                        continue;
 
                /* create */
-               app = gs_app_new (as_app_get_id (item));
+               app = gs_plugin_appstream_create_app (plugin, as_app_get_id (item));
                gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE);
                gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
                if (!gs_appstream_refine_app (plugin, app, item, error))
@@ -395,7 +409,7 @@ gs_plugin_add_category_apps (GsPlugin *plugin,
                        continue;
 
                /* got a search match, so add all the data we can */
-               app = gs_app_new (as_app_get_id (item));
+               app = gs_plugin_appstream_create_app (plugin, as_app_get_id (item));
                if (!gs_appstream_refine_app (plugin, app, item, error))
                        return FALSE;
                gs_app_list_add (list, app);
@@ -430,7 +444,7 @@ gs_plugin_add_search_item (GsPlugin *plugin,
                return TRUE;
 
        /* create app */
-       app = gs_app_new (as_app_get_id (item));
+       app = gs_plugin_appstream_create_app (plugin, as_app_get_id (item));
        if (!gs_appstream_refine_app (plugin, app, item, error))
                return FALSE;
        gs_app_set_match_value (app, match_value);
@@ -488,7 +502,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
                item = g_ptr_array_index (array, i);
                if (as_app_get_state (item) == AS_APP_STATE_INSTALLED) {
                        g_autoptr(GsApp) app = NULL;
-                       app = gs_app_new (as_app_get_id (item));
+                       app = gs_plugin_appstream_create_app (plugin, as_app_get_id (item));
                        if (!gs_appstream_refine_app (plugin, app, item, error))
                                return FALSE;
                        gs_app_list_add (list, app);
@@ -589,7 +603,7 @@ gs_plugin_add_popular (GsPlugin *plugin,
                        continue;
                if (!as_app_has_kudo (item, "GnomeSoftware::popular"))
                        continue;
-               app = gs_app_new (as_app_get_id_no_prefix (item));
+               app = gs_plugin_appstream_create_app (plugin, as_app_get_id_no_prefix (item));
                gs_app_add_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX);
                gs_app_list_add (list, app);
        }
@@ -619,7 +633,7 @@ gs_plugin_add_featured (GsPlugin *plugin,
                        continue;
                if (as_app_get_metadata_item (item, "GnomeSoftware::FeatureTile-css") == NULL)
                        continue;
-               app = gs_app_new (as_app_get_id_no_prefix (item));
+               app = gs_plugin_appstream_create_app (plugin, as_app_get_id_no_prefix (item));
                if (!gs_appstream_refine_app (plugin, app, item, error))
                        return FALSE;
                gs_app_add_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX);
diff --git a/src/plugins/gs-plugin-dummy.c b/src/plugins/gs-plugin-dummy.c
index d3be326..4af6660 100644
--- a/src/plugins/gs-plugin-dummy.c
+++ b/src/plugins/gs-plugin-dummy.c
@@ -99,7 +99,7 @@ gs_plugin_dummy_poll_cb (gpointer user_data)
 
        /* find the app in the per-plugin cache -- this assumes that we can
         * calculate the same key as used when calling gs_plugin_cache_add() */
-       app = gs_plugin_cache_lookup (plugin, "example:chiron");
+       app = gs_plugin_cache_lookup (plugin, "chiron");
        if (app == NULL) {
                g_warning ("app not found in cache!");
                return FALSE;
@@ -134,7 +134,7 @@ gs_plugin_add_search (GsPlugin *plugin,
                return TRUE;
 
        /* does the app already exist? */
-       app = gs_plugin_cache_lookup (plugin, "example:chiron");
+       app = gs_plugin_cache_lookup (plugin, "chiron");
        if (app != NULL) {
                g_debug ("using %s fom the cache", gs_app_get_id (app));
                gs_app_list_add (list, app);
@@ -163,7 +163,7 @@ gs_plugin_add_search (GsPlugin *plugin,
        gs_app_list_add (list, app);
 
        /* add to cache so it can be found by the flashing callback */
-       gs_plugin_cache_add (plugin, "example:chiron", app);
+       gs_plugin_cache_add (plugin, "chiron", app);
 
        return TRUE;
 }
@@ -456,6 +456,13 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
        as_icon_set_kind (ic, AS_ICON_KIND_STOCK);
        as_icon_set_name (ic, "application-x-addon");
 
+       /* get existing item from the cache */
+       app = gs_plugin_cache_lookup (plugin, "release-rawhide");
+       if (app != NULL) {
+               gs_app_list_add (list, app);
+               return TRUE;
+       }
+
        app = gs_app_new ("org.fedoraproject.release-rawhide.upgrade");
        gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE);
        gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
@@ -484,6 +491,9 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
                             "background-size: 100% 100%;");
        gs_app_set_icon (app, ic);
        gs_app_list_add (list, app);
+
+       gs_plugin_cache_add (plugin, "release-rawhide", app);
+
        return TRUE;
 }
 
diff --git a/src/plugins/gs-plugin-fedora-distro-upgrades.c b/src/plugins/gs-plugin-fedora-distro-upgrades.c
index daeed91..9af2cfc 100644
--- a/src/plugins/gs-plugin-fedora-distro-upgrades.c
+++ b/src/plugins/gs-plugin-fedora-distro-upgrades.c
@@ -64,6 +64,9 @@ gs_plugin_fedora_distro_upgrades_changed_cb (GFileMonitor *monitor,
 {
        GsPlugin *plugin = GS_PLUGIN (user_data);
 
+       /* cache no longer valid */
+       gs_plugin_cache_invalidate (plugin);
+
        /* only reload the update list if the plugin is NOT running itself
         * and the time since it ran is greater than 5 seconds (inotify FTW) */
        if (gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_RUNNING_SELF)) {
@@ -312,6 +315,7 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
                DistroInfo *distro_info = g_ptr_array_index (distros, i);
                g_autofree gchar *app_id = NULL;
                g_autofree gchar *app_version = NULL;
+               g_autofree gchar *cache_key = NULL;
                g_autofree gchar *url = NULL;
                g_autofree gchar *css = NULL;
                g_autoptr(GsApp) app = NULL;
@@ -329,6 +333,14 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
                if (distro_info->status == DISTRO_STATUS_DEVEL)
                        continue;
 
+               /* search in the cache */
+               cache_key = g_strdup_printf ("release-%d", distro_info->version);
+               app = gs_plugin_cache_lookup (plugin, cache_key);
+               if (app != NULL) {
+                       gs_app_list_add (list, app);
+                       continue;
+               }
+
                app_id = g_strdup_printf ("org.fedoraproject.release-%d.upgrade",
                                          distro_info->version);
                app_version = g_strdup_printf ("%d", distro_info->version);
@@ -378,6 +390,9 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
                gs_app_set_metadata (app, "GnomeSoftware::UpgradeBanner-css", css);
 
                gs_app_list_add (list, app);
+
+               /* save in the cache */
+               gs_plugin_cache_add (plugin, cache_key, app);
        }
 
        return TRUE;
diff --git a/src/plugins/gs-plugin-flatpak.c b/src/plugins/gs-plugin-flatpak.c
index bb7cf8d..cfe7a88 100644
--- a/src/plugins/gs-plugin-flatpak.c
+++ b/src/plugins/gs-plugin-flatpak.c
@@ -847,7 +847,8 @@ gs_plugin_refine_item_state (GsPlugin *plugin,
 }
 
 static gboolean
-gs_plugin_flatpak_set_app_metadata (GsApp *app,
+gs_plugin_flatpak_set_app_metadata (GsPlugin *plugin,
+                                   GsApp *app,
                                    const gchar *data,
                                    gsize length,
                                    GError **error)
@@ -871,7 +872,7 @@ gs_plugin_flatpak_set_app_metadata (GsApp *app,
        g_debug ("runtime for %s is %s", name, runtime);
 
        /* create runtime */
-       app_runtime = gs_appstream_create_runtime (app, runtime);
+       app_runtime = gs_appstream_create_runtime (plugin, app, runtime);
        if (app_runtime != NULL)
                gs_app_set_runtime (app, app_runtime);
 
@@ -934,7 +935,7 @@ gs_plugin_refine_item_runtime (GsPlugin *plugin,
        }
 
        /* parse key file */
-       if (!gs_plugin_flatpak_set_app_metadata (app, str, len, error))
+       if (!gs_plugin_flatpak_set_app_metadata (plugin, app, str, len, error))
                return FALSE;
        return TRUE;
 }
@@ -1323,7 +1324,8 @@ gs_plugin_file_to_app (GsPlugin *plugin,
        gs_app_set_size_installed (app, flatpak_bundle_ref_get_installed_size (xref_bundle));
        gs_plugin_flatpak_set_metadata (app, FLATPAK_REF (xref_bundle));
        metadata = flatpak_bundle_ref_get_metadata (xref_bundle);
-       if (!gs_plugin_flatpak_set_app_metadata (app,
+       if (!gs_plugin_flatpak_set_app_metadata (plugin,
+                                                app,
                                                 g_bytes_get_data (metadata, NULL),
                                                 g_bytes_get_size (metadata),
                                                 error))
diff --git a/src/plugins/gs-plugin-hardcoded-popular.c b/src/plugins/gs-plugin-hardcoded-popular.c
index f5577cb..3836501 100644
--- a/src/plugins/gs-plugin-hardcoded-popular.c
+++ b/src/plugins/gs-plugin-hardcoded-popular.c
@@ -57,9 +57,21 @@ gs_plugin_add_popular (GsPlugin *plugin,
        g_debug ("using hardcoded as only %i apps", gs_app_list_length (list));
        for (i = 0; apps[i] != NULL; i++) {
                g_autoptr(GsApp) app = NULL;
+
+               /* look in the cache */
+               app = gs_plugin_cache_lookup (plugin, apps[i]);
+               if (app != NULL) {
+                       gs_app_list_add (list, app);
+                       continue;
+               }
+
+               /* create new */
                app = gs_app_new (apps[i]);
                gs_app_add_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX);
                gs_app_list_add (list, app);
+
+               /* save in the cache */
+               gs_plugin_cache_add (plugin, apps[i], app);
        }
        return TRUE;
 }
diff --git a/src/plugins/gs-plugin-shell-extensions.c b/src/plugins/gs-plugin-shell-extensions.c
index 26751fe..cc7b721 100644
--- a/src/plugins/gs-plugin-shell-extensions.c
+++ b/src/plugins/gs-plugin-shell-extensions.c
@@ -207,6 +207,17 @@ gs_plugin_shell_extensions_add_app (const gchar *uuid,
        return g_steal_pointer (&app);
 }
 
+static void
+gs_plugin_shell_extensions_changed_cb (GDBusProxy *proxy,
+                                      const gchar *sender_name,
+                                      const gchar *signal_name,
+                                      GVariant *parameters,
+                                      GsPlugin *plugin)
+{
+       if (g_strcmp0 (signal_name, "ExtensionStatusChanged") == 0)
+               gs_plugin_cache_invalidate (plugin);
+}
+
 gboolean
 gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
 {
@@ -216,13 +227,17 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
        if (priv->proxy != NULL)
                return TRUE;
        priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
-                                                            G_DBUS_PROXY_FLAGS_NONE,
-                                                            NULL,
-                                                            "org.gnome.Shell",
-                                                            "/org/gnome/Shell",
-                                                            "org.gnome.Shell.Extensions",
-                                                            cancellable,
-                                                            error);
+                                                    G_DBUS_PROXY_FLAGS_NONE,
+                                                    NULL,
+                                                    "org.gnome.Shell",
+                                                    "/org/gnome/Shell",
+                                                    "org.gnome.Shell.Extensions",
+                                                    cancellable,
+                                                    error);
+       if (priv->proxy == NULL)
+               return FALSE;
+       g_signal_connect (priv->proxy, "g-signal",
+                         G_CALLBACK (gs_plugin_shell_extensions_changed_cb), plugin);
 
        /* get the GNOME Shell version */
        version = g_dbus_proxy_get_cached_property (priv->proxy,
@@ -260,6 +275,13 @@ gs_plugin_add_installed (GsPlugin *plugin,
        while (g_variant_iter_loop (iter, "{sa{sv}}", &ext_uuid, &ext_iter)) {
                g_autoptr(GsApp) app = NULL;
 
+               /* search in the cache */
+               app = gs_plugin_cache_lookup (plugin, ext_uuid);
+               if (app != NULL) {
+                       gs_app_list_add (list, app);
+                       continue;
+               }
+
                /* parse the data into an GsApp */
                app = gs_plugin_shell_extensions_add_app (ext_uuid,
                                                          ext_iter,
@@ -267,6 +289,9 @@ gs_plugin_add_installed (GsPlugin *plugin,
                if (app == NULL)
                        return FALSE;
 
+               /* save in the cache */
+               gs_plugin_cache_add (plugin, ext_uuid, app);
+
                /* add to results */
                gs_app_list_add (list, app);
        }
diff --git a/src/plugins/gs-plugin-systemd-updates.c b/src/plugins/gs-plugin-systemd-updates.c
index bfd3bb1..c23655f 100644
--- a/src/plugins/gs-plugin-systemd-updates.c
+++ b/src/plugins/gs-plugin-systemd-updates.c
@@ -57,6 +57,11 @@ gs_plugin_systemd_updates_changed_cb (GFileMonitor *monitor,
                                      gpointer user_data)
 {
        GsPlugin *plugin = GS_PLUGIN (user_data);
+
+       /* cache no longer valid */
+       gs_plugin_cache_invalidate (plugin);
+
+       /* update UI */
        gs_plugin_updates_changed (plugin);
 }
 
@@ -103,6 +108,15 @@ gs_plugin_add_updates (GsPlugin *plugin,
        for (i = 0; package_ids[i] != NULL; i++) {
                g_autoptr(GsApp) app = NULL;
                g_auto(GStrv) split = NULL;
+
+               /* search in the cache */
+               app = gs_plugin_cache_lookup (plugin, package_ids[i]);
+               if (app != NULL) {
+                       gs_app_list_add (list, app);
+                       continue;
+               }
+
+               /* create new app */
                app = gs_app_new (NULL);
                gs_app_add_quirk (app, AS_APP_QUIRK_NEEDS_REBOOT);
                gs_app_set_management_plugin (app, "packagekit");
@@ -113,6 +127,9 @@ gs_plugin_add_updates (GsPlugin *plugin,
                gs_app_set_state (app, AS_APP_STATE_UPDATABLE);
                gs_app_set_kind (app, AS_APP_KIND_GENERIC);
                gs_app_list_add (list, app);
+
+               /* save in the cache */
+               gs_plugin_cache_add (plugin, package_ids[i], app);
        }
        return TRUE;
 }


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