[recipes/image-download: 12/13] Add negative cache entries



commit f093dc26c459543ebdffe5940d722b0f317c9552
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Apr 2 11:20:44 2017 -0400

    Add negative cache entries
    
    We don't want to keep asking for images that are just not
    present on the server.

 src/gr-image.c |   86 +++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 69 insertions(+), 17 deletions(-)
---
diff --git a/src/gr-image.c b/src/gr-image.c
index 7e7f7e8..030722b 100644
--- a/src/gr-image.c
+++ b/src/gr-image.c
@@ -204,6 +204,47 @@ get_thumbnail_cache_path (GrImage *ri)
         return filename;
 }
 
+static gboolean
+check_recent_failure (const char *path)
+{
+        g_autoptr(GFile) file = NULL;
+        g_autoptr(GFileInfo) info = NULL;
+
+        // We create negative cache entries as empty files, and we
+        // limit our requests to once per day
+
+        file = g_file_new_for_path (path);
+        info = g_file_query_info (file,
+                                  G_FILE_ATTRIBUTE_STANDARD_SIZE ","
+                                  G_FILE_ATTRIBUTE_TIME_MODIFIED,
+                                  G_FILE_QUERY_INFO_NONE,
+                                  NULL,
+                                  NULL);
+        if (info) {
+                goffset size;
+                GTimeVal tv;
+
+                size = g_file_info_get_size (info);
+                g_file_info_get_modification_time (info, &tv);
+
+                if (size == 6) {
+                        g_autoptr(GDateTime) now = g_date_time_new_now_utc ();
+                        g_autoptr(GDateTime) mtime = g_date_time_new_from_timeval_utc (&tv);
+
+                        return g_date_time_difference (now, mtime) < G_TIME_SPAN_DAY;
+                }
+        }
+
+        return FALSE;
+}
+
+static void
+write_negative_cache_entry (const char *path)
+{
+        if (!g_file_set_contents (path, "failed", 6, NULL))
+                g_warning ("Failed to write a negative cache entry for %s", path);
+}
+
 static void
 set_image (SoupSession *session,
            SoupMessage *msg,
@@ -231,18 +272,20 @@ set_image (SoupSession *session,
                 goto error;
         }
 
+        if (msg == ri->thumbnail_message)
+                cache_path = get_thumbnail_cache_path (ri);
+        else
+                cache_path = get_image_cache_path (ri);
+
         if (msg->status_code != SOUP_STATUS_OK) {
-                g_debug ("Status not ok: %d", msg->status_code);
+                g_autofree char *url = get_image_url (ri);
+                g_debug ("Got status %d, record failure to load %s", msg->status_code, url);
+                write_negative_cache_entry (cache_path);
                 goto out;
         }
 
-        if (msg == ri->thumbnail_message) {
-                if (ri->image_message == NULL) // already got the image, ignore the thumbnail
-                        goto out;
-                cache_path = get_thumbnail_cache_path (ri);
-        }
-        else {
-                cache_path = get_image_cache_path (ri);
+        if (msg == ri->thumbnail_message && ri->image_message == NULL) {
+                goto out; // already got the image, ignore the thumbnail
         }
 
         g_debug ("Saving image to %s", cache_path);
@@ -313,13 +356,18 @@ gr_image_load (GrImage         *ri,
         }
 
         cache_path = get_image_cache_path (ri);
-        pixbuf = load_pixbuf (cache_path, width, height, fit);
 
+        pixbuf = load_pixbuf (cache_path, width, height, fit);
         if (pixbuf) {
                 g_debug ("Use cached image for %s", ri->path);
                 callback (ri, pixbuf, data);
                 return;
         }
+        if (check_recent_failure (cache_path)) {
+                g_autofree char *url = get_image_url (ri);
+                g_debug ("Recently failed to load %s, skipping", url);
+                return;
+        }
 
         td = g_new0 (TaskData, 1);
         td->width = width;
@@ -341,15 +389,19 @@ gr_image_load (GrImage         *ri,
                 pixbuf_blur (blurred, 5, 3);
                 callback (ri, blurred, data);
         }
+        else if (check_recent_failure (thumbnail_cache_path)) {
+                g_autofree char *url = get_thumbnail_url (ri);
+                g_debug ("Recently failed to load %s, skipping", url);
+        }
         else if (width > 240 && ri->thumbnail_message == NULL) {
-                g_autofree char *url = NULL;
-                g_autoptr(SoupURI) base_uri = NULL;
-
-                url = get_thumbnail_url (ri);
-                base_uri = soup_uri_new (url);
-                ri->thumbnail_message = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri);
-                g_debug ("Load thumbnail for %s from %s", ri->path, url);
-                soup_session_queue_message (ri->session, g_object_ref (ri->thumbnail_message), set_image, 
ri);
+                        g_autofree char *url = NULL;
+                        g_autoptr(SoupURI) base_uri = NULL;
+
+                        url = get_thumbnail_url (ri);
+                        base_uri = soup_uri_new (url);
+                        ri->thumbnail_message = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri);
+                        g_debug ("Load thumbnail for %s from %s", ri->path, url);
+                        soup_session_queue_message (ri->session, g_object_ref (ri->thumbnail_message), 
set_image, ri);
         }
 
         if (ri->image_message == NULL) {


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