From: Jaroslav Kysela Date: Mon, 26 Nov 2018 16:09:17 +0000 (+0100) Subject: imagecache: add 'expire' time for the cached files, fixes #4304 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c73e4248a9072be57d5ede3a510773ba06bebc09;p=thirdparty%2Ftvheadend.git imagecache: add 'expire' time for the cached files, fixes #4304 --- diff --git a/src/imagecache.c b/src/imagecache.c index 7eafa677a..9b3efae89 100644 --- a/src/imagecache.c +++ b/src/imagecache.c @@ -46,6 +46,7 @@ typedef struct imagecache_image int id; ///< Internal ID const char *url; ///< Upstream URL int failed; ///< Last update failed + time_t accessed; ///< Last time the file was accessed time_t updated; ///< Last time the file was checked uint8_t sha1[20]; ///< Contents hash enum { @@ -69,7 +70,8 @@ struct imagecache_config imagecache_conf = { .idnode.in_class = &imagecache_class, }; -static htsmsg_t *imagecache_save(idnode_t *self, char *filename, size_t fsize); +static htsmsg_t *imagecache_class_save(idnode_t *self, char *filename, size_t fsize); +static void imagecache_destroy(imagecache_image_t *img, int delconf); CLASS_DOC(imagecache) @@ -80,7 +82,7 @@ const idclass_t imagecache_class = { .ic_event = "imagecache", .ic_perm_def = ACCESS_ADMIN, .ic_doc = tvh_doc_imagecache_class, - .ic_save = imagecache_save, + .ic_save = imagecache_class_save, .ic_properties = (const property_t[]){ { .type = PT_BOOL, @@ -100,6 +102,16 @@ const idclass_t imagecache_class = { "self-certified, etc.) certificates"), .off = offsetof(struct imagecache_config, ignore_sslcert), }, + { + .type = PT_U32, + .id = "", + .name = N_("Expire time"), + .desc = N_("The time in hours after the cached URL will " + "be removed. The time starts when the URL was " + "lastly requested. Zero means unlimited cache " + "(not recommended)."), + .off = offsetof(struct imagecache_config, expire), + }, { .type = PT_U32, .id = "ok_period", @@ -153,6 +165,8 @@ imagecache_image_save ( imagecache_image_t *img ) char hex[41]; htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "url", img->url); + if (img->accessed) + htsmsg_add_s64(m, "accessed", img->accessed); if (img->updated) htsmsg_add_s64(m, "updated", img->updated); if (!sha1_empty(img->sha1)) { @@ -262,8 +276,6 @@ imagecache_image_fetch ( imagecache_image_t *img ) if (img->url == NULL || img->url[0] == '\0') return res; - urlinit(&url); - /* Open file */ if (hts_settings_buildpath(path, sizeof(path), "imagecache/data/%d", img->id)) @@ -275,6 +287,8 @@ imagecache_image_fetch ( imagecache_image_t *img ) /* Fetch (release lock, incase of delays) */ pthread_mutex_unlock(&global_lock); + urlinit(&url); + /* Build command */ tvhdebug(LS_IMAGECACHE, "fetch %s", img->url); memset(&url, 0, sizeof(url)); @@ -373,10 +387,17 @@ imagecache_thread ( void *p ) static void imagecache_timer_cb ( void *p ) { - time_t now, when; - imagecache_image_t *img; - time(&now); - RB_FOREACH(img, &imagecache_by_url, url_link) { + time_t now = gclk(), when; + imagecache_image_t *img, *img_next; + for (img = RB_FIRST(&imagecache_by_url); img; img = img_next) { + img_next = RB_NEXT(img, url_link); + if (imagecache_conf.expire > 0 && img->accessed > 0) { + when = img->accessed + imagecache_conf.expire * 24 * 3600; + if (when < now) { + tvhdebug(LS_IMAGECACHE, "expired: %s", img->url); + imagecache_destroy(img, 1); + } + } if (img->state != IDLE) continue; when = img->failed ? imagecache_conf.fail_period : imagecache_conf.ok_period; @@ -408,6 +429,7 @@ imagecache_init ( void ) imagecache_id = 0; #if ENABLE_IMAGECACHE imagecache_conf.enabled = 0; + imagecache_conf.expire = 7; // 7 days imagecache_conf.ok_period = 24 * 7; // weekly imagecache_conf.fail_period = 24; // daily imagecache_conf.ignore_sslcert = 0; @@ -509,10 +531,10 @@ imagecache_done ( void ) #if ENABLE_IMAGECACHE /* - * Save + * Class save */ static htsmsg_t * -imagecache_save ( idnode_t *self, char *filename, size_t fsize ) +imagecache_class_save ( idnode_t *self, char *filename, size_t fsize ) { htsmsg_t *c = htsmsg_create_map(); idnode_save(&imagecache_conf.idnode, c); @@ -595,7 +617,8 @@ imagecache_trigger( void ) int imagecache_get_id ( const char *url ) { - int id = 0; + int id = 0, save = 0; + time_t clk; imagecache_image_t *i; lock_assert(&global_lock); @@ -624,7 +647,7 @@ imagecache_get_id ( const char *url ) imagecache_new_id(i); imagecache_image_add(i); #endif - imagecache_image_save(i); + save = 1; } #if ENABLE_IMAGECACHE if (!strncasecmp(url, "file://", 7) || imagecache_conf.enabled) @@ -633,7 +656,14 @@ imagecache_get_id ( const char *url ) if (!strncasecmp(url, "file://", 7)) id = i->id; #endif - + + clk = gclk(); + if (clk != i->accessed) { + i->accessed = clk; + save = 1; + } + if (save && i->state != IDLE) + imagecache_image_save(i); return id; } diff --git a/src/imagecache.h b/src/imagecache.h index 0bbc85297..edb8f9529 100644 --- a/src/imagecache.h +++ b/src/imagecache.h @@ -26,6 +26,7 @@ struct imagecache_config { idnode_t idnode; int enabled; int ignore_sslcert; + uint32_t expire; uint32_t ok_period; uint32_t fail_period; };