[epiphany/wip/google-safe-browsing: 5/6] gsb-service: Run database updates in a separate thread



commit 0d8b5497c0feead8ec3d0fd73162766805890036
Author: Gabriel Ivascu <gabrielivascu gnome org>
Date:   Wed Sep 13 18:21:32 2017 +0300

    gsb-service: Run database updates in a separate thread

 lib/safe-browsing/ephy-gsb-service.c |  134 +++++++++++++++++++---------------
 1 files changed, 76 insertions(+), 58 deletions(-)
---
diff --git a/lib/safe-browsing/ephy-gsb-service.c b/lib/safe-browsing/ephy-gsb-service.c
index 04e6fcb..6f7b14f 100644
--- a/lib/safe-browsing/ephy-gsb-service.c
+++ b/lib/safe-browsing/ephy-gsb-service.c
@@ -39,6 +39,7 @@ struct _EphyGSBService {
 
   char           *api_key;
   EphyGSBStorage *storage;
+  gboolean        is_updating;
   SoupSession    *session;
 };
 
@@ -70,36 +71,70 @@ json_object_has_non_null_array_member (JsonObject *object,
 }
 
 static void
-update_threat_lists_cb (SoupSession *session,
-                        SoupMessage *msg,
-                        gpointer     user_data)
+ephy_gsb_service_update_thread (GTask          *task,
+                                EphyGSBService *self,
+                                gpointer        task_data,
+                                GCancellable   *cancellable)
 {
-  EphyGSBService *self = EPHY_GSB_SERVICE (user_data);
   GError *error = NULL;
-  JsonNode *node;
-  JsonObject *object;
-  JsonArray *responses;
+  JsonNode *body_node;
+  JsonObject *body_obj;
+  JsonArray *array;
+  SoupMessage *msg;
+  GList *threat_lists;
   gint64 next_update_time;
+  char *url;
+  char *body;
+
+  g_assert (EPHY_IS_GSB_SERVICE (self));
+  g_assert (ephy_gsb_storage_is_operable (self->storage));
+
+  threat_lists = ephy_gsb_storage_get_threat_lists (self->storage);
+  if (!threat_lists)
+    return;
+
+  array = json_array_new ();
+  for (GList *l = threat_lists; l && l->data; l = l->next) {
+    JsonObject *lur = ephy_gsb_utils_make_list_update_request (l->data);
+    json_array_add_object_element (array, lur);
+  }
+
+  body_obj = json_object_new ();
+  json_object_set_object_member (body_obj, "client", ephy_gsb_utils_make_client_info ());
+  json_object_set_array_member (body_obj, "listUpdateRequests", array);
+
+  body_node = json_node_new (JSON_NODE_OBJECT);
+  json_node_set_object (body_node, body_obj);
+  body = json_to_string (body_node, FALSE);
+
+  url = g_strdup_printf ("%sthreatListUpdates:fetch?key=%s", API_PREFIX, self->api_key);
+  msg = soup_message_new (SOUP_METHOD_POST, url);
+  soup_message_set_request (msg, "application/json", SOUP_MEMORY_TAKE, body, strlen (body));
+  soup_session_send_message (self->session, msg);
+
+  /* Reuse these for the response. */
+  json_object_unref (body_obj);
+  json_node_unref (body_node);
 
   if (msg->status_code != 200) {
     LOG ("Cannot update GSB threat lists. Server responded: %u, %s",
          msg->status_code, msg->response_body->data);
-    return;
+    goto out;
   }
 
-  node = json_from_string (msg->response_body->data, &error);
+  body_node = json_from_string (msg->response_body->data, &error);
   if (error) {
-    g_warning ("Cannot update GSB threat lists. Response is not a valid JSON: %s", error->message);
+    LOG ("Cannot update GSB threat lists. Response is not a valid JSON: %s", error->message);
     g_error_free (error);
-    return;
+    goto out;
   }
 
-  object = json_node_get_object (node);
-  responses = json_object_get_array_member (object, "listUpdateResponses");
+  body_obj = json_node_get_object (body_node);
+  array = json_object_get_array_member (body_obj, "listUpdateResponses");
 
-  for (guint i = 0; i < json_array_get_length (responses); i++) {
+  for (guint i = 0; i < json_array_get_length (array); i++) {
     EphyGSBThreatList *list;
-    JsonObject *lur = json_array_get_object_element (responses, i);
+    JsonObject *lur = json_array_get_object_element (array, i);
     const char *type = json_object_get_string_member (lur, "responseType");
     JsonObject *checksum = json_object_get_object_member (lur, "checksum");
     const char *remote_checksum = json_object_get_string_member (checksum, "sha256");
@@ -157,11 +192,11 @@ update_threat_lists_cb (SoupSession *session,
   }
 
   /* Update next update time. */
-  if (json_object_has_non_null_string_member (object, "minimumWaitDuration")) {
+  if (json_object_has_non_null_string_member (body_obj, "minimumWaitDuration")) {
     const char *duration_str;
     double duration;
 
-    duration_str = json_object_get_string_member (object, "minimumWaitDuration");
+    duration_str = json_object_get_string_member (body_obj, "minimumWaitDuration");
     /* Handle the trailing 's' character. */
     sscanf (duration_str, "%lfs", &duration);
     next_update_time = CURRENT_TIME + (gint64)ceil (duration);
@@ -170,52 +205,37 @@ update_threat_lists_cb (SoupSession *session,
   }
 
   ephy_gsb_storage_set_next_update_time (self->storage, next_update_time);
-  /* TODO: Schedule a next update in (next_update_time - CURRENT_TIME) seconds. */
 
-  json_node_unref (node);
+  json_node_unref (body_node);
+out:
+  g_free (url);
+  g_object_unref (msg);
+  g_list_free_full (threat_lists, (GDestroyNotify)ephy_gsb_threat_list_free);
+}
+
+static void
+ephy_gsb_service_update_finished_cb (EphyGSBService *self,
+                                     GAsyncResult   *result,
+                                     gpointer        user_data)
+{
+  /* TODO: Schedule a next update in (next_update_time - CURRENT_TIME) seconds. */
+  self->is_updating = FALSE;
 }
 
 static void
-ephy_gsb_service_update_threat_lists (EphyGSBService *self)
+ephy_gsb_service_update (EphyGSBService *self)
 {
-  SoupMessage *msg;
-  JsonNode *body_node;
-  JsonObject *body_obj;
-  JsonArray *requests;
-  GList *threat_lists;
-  char *url;
-  char *body;
+  GTask *task;
 
   g_assert (EPHY_IS_GSB_SERVICE (self));
   g_assert (ephy_gsb_storage_is_operable (self->storage));
 
-  threat_lists = ephy_gsb_storage_get_threat_lists (self->storage);
-  if (!threat_lists)
-    return;
-
-  requests = json_array_new ();
-  for (GList *l = threat_lists; l && l->data; l = l->next) {
-    JsonObject *lur = ephy_gsb_utils_make_list_update_request (l->data);
-    json_array_add_object_element (requests, lur);
-  }
-
-  body_obj = json_object_new ();
-  json_object_set_object_member (body_obj, "client", ephy_gsb_utils_make_client_info ());
-  json_object_set_array_member (body_obj, "listUpdateRequests", requests);
-
-  body_node = json_node_new (JSON_NODE_OBJECT);
-  json_node_set_object (body_node, body_obj);
-  body = json_to_string (body_node, FALSE);
-
-  url = g_strdup_printf ("%sthreatListUpdates:fetch?key=%s", API_PREFIX, self->api_key);
-  msg = soup_message_new (SOUP_METHOD_POST, url);
-  soup_message_set_request (msg, "application/json", SOUP_MEMORY_TAKE, body, strlen (body));
-  soup_session_queue_message (self->session, msg, update_threat_lists_cb, self);
-
-  g_free (url);
-  json_object_unref (body_obj);
-  json_node_unref (body_node);
-  g_list_free_full (threat_lists, (GDestroyNotify)ephy_gsb_threat_list_free);
+  self->is_updating = TRUE;
+  task = g_task_new (self, NULL,
+                     (GAsyncReadyCallback)ephy_gsb_service_update_finished_cb,
+                     NULL);
+  g_task_run_in_thread (task, (GTaskThreadFunc)ephy_gsb_service_update_thread);
+  g_object_unref (task);
 }
 
 static void
@@ -294,10 +314,8 @@ ephy_gsb_service_constructed (GObject *object)
     return;
 
   next_update_time = ephy_gsb_storage_get_next_update_time (self->storage);
-  if (CURRENT_TIME >= next_update_time) {
-    /* TODO: This takes too long, needs to run in a separate thread. */
-    ephy_gsb_service_update_threat_lists (self);
-  }
+  if (CURRENT_TIME >= next_update_time)
+    ephy_gsb_service_update (self);
 }
 
 static void


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