]> git.kaiwu.me - nginx.git/commitdiff
Cache: cache manager limits.
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 5 Oct 2016 11:22:30 +0000 (14:22 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Wed, 5 Oct 2016 11:22:30 +0000 (14:22 +0300)
The new parameters "manager_files", "manager_sleep"
and "manager_threshold" were added to proxy_cache_path
and friends.

Note that ngx_path_manager_pt was changed to return ngx_msec_t
instead of time_t (API change).

src/core/ngx_file.h
src/http/ngx_http_cache.h
src/http/ngx_http_file_cache.c
src/os/unix/ngx_process_cycle.c
src/os/win32/ngx_process_cycle.c

index 4240dc0742caa267f3fc6c4107b693d90261a6f5..5c4482193266cdf321947b3fed241829350c5f7b 100644 (file)
@@ -42,7 +42,7 @@ struct ngx_file_s {
 #define NGX_MAX_PATH_LEVEL  3
 
 
-typedef time_t (*ngx_path_manager_pt) (void *data);
+typedef ngx_msec_t (*ngx_path_manager_pt) (void *data);
 typedef ngx_msec_t (*ngx_path_purger_pt) (void *data);
 typedef void (*ngx_path_loader_pt) (void *data);
 
index 4aa947fbeb8995ecab1da788997cf41ceb3b701c..9c9ff6f6569ccc3c306dfb3647d8c6eddcf230e1 100644 (file)
@@ -166,6 +166,10 @@ struct ngx_http_file_cache_s {
     ngx_msec_t                       loader_sleep;
     ngx_msec_t                       loader_threshold;
 
+    ngx_uint_t                       manager_files;
+    ngx_msec_t                       manager_sleep;
+    ngx_msec_t                       manager_threshold;
+
     ngx_shm_zone_t                  *shm_zone;
 };
 
index 4bf0f7f20f1e2384f2446022149aef96212f6ee0..199a901f56b3e8d784cd1035940cbbe54567714a 100644 (file)
@@ -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;
index 83b04ee627430b916124f1936ecd7423d6e034ba..5c4e21dfd9e7f7cf85e2a5e49d89ddefe260cf1b 100644 (file)
@@ -1148,11 +1148,11 @@ ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data)
 static void
 ngx_cache_manager_process_handler(ngx_event_t *ev)
 {
-    time_t        next, n;
     ngx_uint_t    i;
+    ngx_msec_t    next, n;
     ngx_path_t  **path;
 
-    next = 60 * 60;
+    next = 60 * 60 * 1000;
 
     path = ngx_cycle->paths.elts;
     for (i = 0; i < ngx_cycle->paths.nelts; i++) {
@@ -1170,7 +1170,7 @@ ngx_cache_manager_process_handler(ngx_event_t *ev)
         next = 1;
     }
 
-    ngx_add_timer(ev, next * 1000);
+    ngx_add_timer(ev, next);
 }
 
 
index 8b9c5ef22c7e72cb3a76f7393d8c0f01ad7812ec..99fec54e36afa7da397614a83f5713c3530ab386 100644 (file)
@@ -921,11 +921,11 @@ static void
 ngx_cache_manager_process_handler(void)
 {
     u_long        ev;
-    time_t        next, n;
     ngx_uint_t    i;
+    ngx_msec_t    next, n;
     ngx_path_t  **path;
 
-    next = 60 * 60;
+    next = 60 * 60 * 1000;
 
     path = ngx_cycle->paths.elts;
     for (i = 0; i < ngx_cycle->paths.nelts; i++) {
@@ -943,7 +943,7 @@ ngx_cache_manager_process_handler(void)
         next = 1;
     }
 
-    ev = WaitForSingleObject(ngx_cache_manager_event, (u_long) next * 1000);
+    ev = WaitForSingleObject(ngx_cache_manager_event, (u_long) next);
 
     if (ev != WAIT_TIMEOUT) {