aboutsummaryrefslogtreecommitdiff
path: root/src/http/ngx_http_file_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/ngx_http_file_cache.c')
-rw-r--r--src/http/ngx_http_file_cache.c103
1 files changed, 94 insertions, 9 deletions
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index 4bf0f7f20..199a901f5 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -1759,6 +1759,7 @@ ngx_http_file_cache_expire(ngx_http_file_cache_t *cache)
size_t len;
time_t now, wait;
ngx_path_t *path;
+ ngx_msec_t elapsed;
ngx_queue_t *q;
ngx_http_file_cache_node_t *fcn;
u_char key[2 * NGX_HTTP_CACHE_KEY_LEN];
@@ -1810,7 +1811,7 @@ ngx_http_file_cache_expire(ngx_http_file_cache_t *cache)
if (fcn->count == 0) {
ngx_http_file_cache_delete(cache, q, name);
- continue;
+ goto next;
}
if (fcn->deleting) {
@@ -1836,6 +1837,22 @@ ngx_http_file_cache_expire(ngx_http_file_cache_t *cache)
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
"ignore long locked inactive cache entry %*s, count:%d",
(size_t) 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count);
+
+next:
+
+ if (++cache->files >= cache->manager_files) {
+ wait = 0;
+ break;
+ }
+
+ ngx_time_update();
+
+ elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
+
+ if (elapsed >= cache->manager_threshold) {
+ wait = 0;
+ break;
+ }
}
ngx_shmtx_unlock(&cache->shpool->mutex);
@@ -1897,20 +1914,25 @@ ngx_http_file_cache_delete(ngx_http_file_cache_t *cache, ngx_queue_t *q,
}
-static time_t
+static ngx_msec_t
ngx_http_file_cache_manager(void *data)
{
ngx_http_file_cache_t *cache = data;
off_t size;
time_t next, wait;
+ ngx_msec_t elapsed;
ngx_uint_t count, watermark;
- next = ngx_http_file_cache_expire(cache);
-
cache->last = ngx_current_msec;
cache->files = 0;
+ next = ngx_http_file_cache_expire(cache);
+
+ if (next == 0) {
+ return cache->manager_sleep;
+ }
+
for ( ;; ) {
ngx_shmtx_lock(&cache->shpool->mutex);
@@ -1925,17 +1947,29 @@ ngx_http_file_cache_manager(void *data)
size, count, (ngx_int_t) watermark);
if (size < cache->max_size && count < watermark) {
- return next;
+ return (ngx_msec_t) next * 1000;
}
wait = ngx_http_file_cache_forced_expire(cache);
if (wait > 0) {
- return wait;
+ return (ngx_msec_t) wait * 1000;
}
if (ngx_quit || ngx_terminate) {
- return next;
+ return (ngx_msec_t) next * 1000;
+ }
+
+ if (++cache->files >= cache->manager_files) {
+ return cache->manager_sleep;
+ }
+
+ ngx_time_update();
+
+ elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
+
+ if (elapsed >= cache->manager_threshold) {
+ return cache->manager_sleep;
}
}
}
@@ -2211,8 +2245,9 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
size_t len;
ssize_t size;
ngx_str_t s, name, *value;
- ngx_int_t loader_files;
- ngx_msec_t loader_sleep, loader_threshold;
+ ngx_int_t loader_files, manager_files;
+ ngx_msec_t loader_sleep, manager_sleep, loader_threshold,
+ manager_threshold;
ngx_uint_t i, n, use_temp_path;
ngx_array_t *caches;
ngx_http_file_cache_t *cache, **ce;
@@ -2230,10 +2265,15 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
use_temp_path = 1;
inactive = 600;
+
loader_files = 100;
loader_sleep = 50;
loader_threshold = 200;
+ manager_files = 100;
+ manager_sleep = 50;
+ manager_threshold = 200;
+
name.len = 0;
size = 0;
max_size = NGX_MAX_OFF_T_VALUE;
@@ -2405,6 +2445,48 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
+ if (ngx_strncmp(value[i].data, "manager_files=", 14) == 0) {
+
+ manager_files = ngx_atoi(value[i].data + 14, value[i].len - 14);
+ if (manager_files == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid manager_files value \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "manager_sleep=", 14) == 0) {
+
+ s.len = value[i].len - 14;
+ s.data = value[i].data + 14;
+
+ manager_sleep = ngx_parse_time(&s, 0);
+ if (manager_sleep == (ngx_msec_t) NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid manager_sleep value \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "manager_threshold=", 18) == 0) {
+
+ s.len = value[i].len - 18;
+ s.data = value[i].data + 18;
+
+ manager_threshold = ngx_parse_time(&s, 0);
+ if (manager_threshold == (ngx_msec_t) NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid manager_threshold value \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[i]);
return NGX_CONF_ERROR;
@@ -2425,6 +2507,9 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
cache->loader_files = loader_files;
cache->loader_sleep = loader_sleep;
cache->loader_threshold = loader_threshold;
+ cache->manager_files = manager_files;
+ cache->manager_sleep = manager_sleep;
+ cache->manager_threshold = manager_threshold;
if (ngx_add_path(cf, &cache->path) != NGX_OK) {
return NGX_CONF_ERROR;