[gnome-software/wip/kalev/autoupdates-feedback-loop] update monitor: Fix autoupdates triggering in a feedback loop
- From: Kalev Lember <klember src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/kalev/autoupdates-feedback-loop] update monitor: Fix autoupdates triggering in a feedback loop
- Date: Thu, 4 Oct 2018 10:42:54 +0000 (UTC)
commit 08ee051775710a61f27469fc83b504cc796e534d
Author: Kalev Lember <klember redhat com>
Date: Thu Oct 4 12:34:13 2018 +0200
update monitor: Fix autoupdates triggering in a feedback loop
Only trigger autoupdates once a day, and avoid accidentally triggering
them when a plugin emits updates-changed. Otherwise it can unexpectedly
happen that a user installs an app, which triggers updates-changed,
which in turn triggers autoupdates immediately.
Worse, a plugin might emit updates-changed when it ran into a failure,
which causes autoupdates to trigger, which in turn runs into another
failure, which causes updates-changed, and so on.
Instead, make sure autoupdates only get triggered once per day.
src/gs-application.c | 2 +-
src/gs-update-monitor.c | 42 ++++++++++++++++++++++++++++++++++--------
src/gs-update-monitor.h | 2 +-
3 files changed, 36 insertions(+), 10 deletions(-)
---
diff --git a/src/gs-application.c b/src/gs-application.c
index 707b0d9a..3d087703 100644
--- a/src/gs-application.c
+++ b/src/gs-application.c
@@ -759,7 +759,7 @@ autoupdate_activated (GSimpleAction *action, GVariant *parameter, gpointer data)
{
GsApplication *app = GS_APPLICATION (data);
gs_shell_set_mode (app->shell, GS_SHELL_MODE_UPDATES);
- gs_update_monitor_get_updates (app->update_monitor);
+ gs_update_monitor_autoupdate (app->update_monitor);
}
static void
diff --git a/src/gs-update-monitor.c b/src/gs-update-monitor.c
index 4a56eef2..2666713e 100644
--- a/src/gs-update-monitor.c
+++ b/src/gs-update-monitor.c
@@ -53,6 +53,20 @@ struct _GsUpdateMonitor {
G_DEFINE_TYPE (GsUpdateMonitor, gs_update_monitor, G_TYPE_OBJECT)
+typedef struct {
+ GsUpdateMonitor *monitor;
+ gboolean autoupdate;
+} DownloadUpdatesData;
+
+static void
+download_updates_data_free (DownloadUpdatesData *data)
+{
+ g_clear_object (&data->monitor);
+ g_slice_free (DownloadUpdatesData, data);
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(DownloadUpdatesData, download_updates_data_free);
+
static gboolean
reenable_offline_update_notification (gpointer data)
{
@@ -347,7 +361,8 @@ download_finished_cb (GObject *object, GAsyncResult *res, gpointer data)
static void
get_updates_finished_cb (GObject *object, GAsyncResult *res, gpointer data)
{
- GsUpdateMonitor *monitor = GS_UPDATE_MONITOR (data);
+ g_autoptr(DownloadUpdatesData) download_updates_data = (DownloadUpdatesData *) data;
+ GsUpdateMonitor *monitor = download_updates_data->monitor;
guint64 security_timestamp = 0;
guint64 security_timestamp_old = 0;
g_autoptr(GError) error = NULL;
@@ -387,7 +402,8 @@ get_updates_finished_cb (GObject *object, GAsyncResult *res, gpointer data)
g_debug ("got %u updates", gs_app_list_length (apps));
/* download any updates if auto-updates are turned on */
- if (g_settings_get_boolean (monitor->settings, "download-updates")) {
+ if (download_updates_data->autoupdate &&
+ g_settings_get_boolean (monitor->settings, "download-updates")) {
g_autoptr(GsPluginJob) plugin_job = NULL;
plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_DOWNLOAD,
"list", apps,
@@ -401,7 +417,6 @@ get_updates_finished_cb (GObject *object, GAsyncResult *res, gpointer data)
return;
}
-
if (has_important_updates (apps) ||
no_updates_for_a_week (monitor)) {
notify_offline_update_available (monitor);
@@ -528,10 +543,11 @@ get_upgrades_finished_cb (GObject *object,
g_application_send_notification (monitor->application, "upgrades-available", n);
}
-void
-gs_update_monitor_get_updates (GsUpdateMonitor *monitor)
+static void
+get_updates (GsUpdateMonitor *monitor, gboolean autoupdate)
{
g_autoptr(GsPluginJob) plugin_job = NULL;
+ g_autoptr(DownloadUpdatesData) download_updates_data = NULL;
/* disabled in gsettings or from a plugin */
if (!gs_plugin_loader_get_allow_updates (monitor->plugin_loader)) {
@@ -539,6 +555,10 @@ gs_update_monitor_get_updates (GsUpdateMonitor *monitor)
return;
}
+ download_updates_data = g_slice_new0 (DownloadUpdatesData);
+ download_updates_data->monitor = g_object_ref (monitor);
+ download_updates_data->autoupdate = autoupdate;
+
/* NOTE: this doesn't actually do any network access */
g_debug ("Getting updates");
plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_UPDATES,
@@ -549,7 +569,13 @@ gs_update_monitor_get_updates (GsUpdateMonitor *monitor)
plugin_job,
monitor->cancellable,
get_updates_finished_cb,
- monitor);
+ g_steal_pointer (&download_updates_data));
+}
+
+void
+gs_update_monitor_autoupdate (GsUpdateMonitor *monitor)
+{
+ get_updates (monitor, TRUE /* autoupdate */);
}
static void
@@ -613,7 +639,7 @@ refresh_cache_finished_cb (GObject *object,
g_settings_set (monitor->settings, "check-timestamp", "x",
g_date_time_to_unix (now));
- gs_update_monitor_get_updates (monitor);
+ get_updates (monitor, TRUE /* autoupdate */);
}
typedef enum {
@@ -797,7 +823,7 @@ updates_changed_cb (GsPluginLoader *plugin_loader, GsUpdateMonitor *monitor)
{
/* when the list of downloaded-and-ready-to-go updates changes get the
* new list and perhaps show/hide the notification */
- gs_update_monitor_get_updates (monitor);
+ get_updates (monitor, FALSE /* autoupdate */);
}
static void
diff --git a/src/gs-update-monitor.h b/src/gs-update-monitor.h
index 0a3c54b5..edc04bf1 100644
--- a/src/gs-update-monitor.h
+++ b/src/gs-update-monitor.h
@@ -35,7 +35,7 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GsUpdateMonitor, gs_update_monitor, GS, UPDATE_MONITOR, GObject)
GsUpdateMonitor *gs_update_monitor_new (GsApplication *app);
-void gs_update_monitor_get_updates (GsUpdateMonitor *monitor);
+void gs_update_monitor_autoupdate (GsUpdateMonitor *monitor);
void gs_update_monitor_show_error (GsUpdateMonitor *monitor,
GsShell *shell);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]