# HG changeset patch # User Jiří Setnička <jiri.setni...@cdn77.com> # Date 1643385660 -3600 # Fri Jan 28 17:01:00 2022 +0100 # Node ID 535e503156cf141bf9471895468423e82f68c8bb # Parent 64ff9068a0bd89712a0ae6fc589a881869663642 Cache: Shared memory for tempfile nodes New option for `proxy_cache_path`: `tf_zone=name:size` (defaults to key zone name with `_tf` suffix and 10M size). It creates a shared memory zone used to store tempfiles nodes.
Will be used to track updated state of multiple tempfiles of the same cache file. diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -156,10 +156,20 @@ typedef struct { } ngx_http_file_cache_sh_t; +typedef struct { + ngx_rbtree_t rbtree; + ngx_rbtree_node_t sentinel; + ngx_uint_t count; +} ngx_http_file_cache_tf_sh_t; + + struct ngx_http_file_cache_s { ngx_http_file_cache_sh_t *sh; ngx_slab_pool_t *shpool; + ngx_http_file_cache_tf_sh_t *tf_sh; + ngx_slab_pool_t *tf_shpool; + ngx_path_t *path; off_t min_free; @@ -181,6 +191,7 @@ struct ngx_http_file_cache_s { ngx_msec_t manager_threshold; ngx_shm_zone_t *shm_zone; + ngx_shm_zone_t *tf_shm_zone; ngx_uint_t use_temp_path; /* unsigned use_temp_path:1 */ diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -172,6 +172,61 @@ ngx_http_file_cache_init(ngx_shm_zone_t } +static ngx_int_t +ngx_http_file_cache_init_tf(ngx_shm_zone_t *shm_zone, void *data) +{ + ngx_http_file_cache_t *ocache = data; + + size_t len; + ngx_http_file_cache_t *cache; + + cache = shm_zone->data; + + if (ocache) { + /* cache path and level already checked by ngx_http_file_cache_init */ + + cache->tf_sh = ocache->tf_sh; + cache->tf_shpool = ocache->tf_shpool; + + return NGX_OK; + } + + cache->tf_shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; + + if (shm_zone->shm.exists) { + cache->tf_sh = cache->tf_shpool->data; + + return NGX_OK; + } + + cache->tf_sh = ngx_slab_alloc(cache->tf_shpool, sizeof(ngx_http_file_cache_tf_sh_t)); + if (cache->tf_sh == NULL) { + return NGX_ERROR; + } + + cache->tf_shpool->data = cache->tf_sh; + + ngx_rbtree_init(&cache->tf_sh->rbtree, &cache->tf_sh->sentinel, + ngx_http_file_cache_rbtree_insert_value); + + cache->tf_sh->count = 0; + + len = sizeof(" in cache tf zone \"\"") + shm_zone->shm.name.len; + + cache->tf_shpool->log_ctx = ngx_slab_alloc(cache->tf_shpool, len); + if (cache->tf_shpool->log_ctx == NULL) { + return NGX_ERROR; + } + + ngx_sprintf(cache->tf_shpool->log_ctx, " in cache tf zone \"%V\"%Z", + &shm_zone->shm.name); + + cache->tf_shpool->log_nomem = 0; + + return NGX_OK; +} + + ngx_int_t ngx_http_file_cache_new(ngx_http_request_t *r) { @@ -2322,8 +2377,8 @@ ngx_http_file_cache_set_slot(ngx_conf_t off_t max_size, min_free; u_char *last, *p; time_t inactive; - ssize_t size; - ngx_str_t s, name, *value; + ssize_t size, tf_size; + ngx_str_t s, name, tf_name, *value; ngx_int_t loader_files, manager_files; ngx_msec_t loader_sleep, manager_sleep, loader_threshold, manager_threshold; @@ -2354,7 +2409,9 @@ ngx_http_file_cache_set_slot(ngx_conf_t manager_threshold = 200; name.len = 0; + tf_name.len = 0; size = 0; + tf_size = 10000000; max_size = NGX_MAX_OFF_T_VALUE; min_free = 0; @@ -2462,6 +2519,40 @@ ngx_http_file_cache_set_slot(ngx_conf_t continue; } + if (ngx_strncmp(value[i].data, "tf_zone=", 8) == 0) { + + tf_name.data = value[i].data + 8; + + p = (u_char *) ngx_strchr(tf_name.data, ':'); + + if (p == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid tf_zone size \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + tf_name.len = p - tf_name.data; + + s.data = p + 1; + s.len = value[i].data + value[i].len - s.data; + + tf_size = ngx_parse_size(&s); + + if (tf_size == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid tf_zone size \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + if (tf_size < (ssize_t) (2 * ngx_pagesize)) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "tf_zone \"%V\" is too small", &value[i]); + return NGX_CONF_ERROR; + } + + continue; + } + if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) { s.len = value[i].len - 9; @@ -2611,6 +2702,17 @@ ngx_http_file_cache_set_slot(ngx_conf_t return NGX_CONF_ERROR; } + if (tf_name.len == 0) { + tf_name.len = name.len + 3; + tf_name.data = ngx_alloc(tf_name.len, cf->log); + if (tf_name.data == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "Cannot allocate tf_zone name"); + return NGX_CONF_ERROR; + } + ngx_sprintf(tf_name.data, "%V_tf", &name); + } + cache->path->manager = ngx_http_file_cache_manager; cache->path->loader = ngx_http_file_cache_loader; cache->path->data = cache; @@ -2642,6 +2744,21 @@ ngx_http_file_cache_set_slot(ngx_conf_t cache->shm_zone->init = ngx_http_file_cache_init; cache->shm_zone->data = cache; + cache->tf_shm_zone = ngx_shared_memory_add(cf, &tf_name, tf_size, cmd->post); + if (cache->tf_shm_zone == NULL) { + return NGX_CONF_ERROR; + } + + if (cache->tf_shm_zone->data) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "duplicate zone \"%V\"", &tf_name); + return NGX_CONF_ERROR; + } + + + cache->tf_shm_zone->init = ngx_http_file_cache_init_tf; + cache->tf_shm_zone->data = cache; + cache->use_temp_path = use_temp_path; cache->inactive = inactive; _______________________________________________ nginx-devel mailing list -- nginx-devel@nginx.org To unsubscribe send an email to nginx-devel-le...@nginx.org