ngx.shared.DICT.expire 详解
ngx.shared.DICT.expire
原文链接: ngx.shared.DICT.expire
syntax: success, err = ngx.shared.DICT:expire(key, exptime)
context: init_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*,
header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*,
balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*,
ssl_session_store_by_lua*
requires: resty.core.shdict or resty.core
设置存储于共享内存 ngx.shared.DICT 中的键值对的过期时间(以秒为单位)。如果操作完成返回布尔值指示成功,否则返回 nil 和错误信息字符串。
如果 key 不存在,则该方法返回 nil 和错误信息字符串 "not found"。
exptime 过期参数的分辨率为 0.001 秒,如果 exptime 为 0,则该项将永不过期。如下:
require "resty.core"
local cats = ngx.shared.cats
local succ, err = cats:set("Marry", "a nice cat", 0.1)
succ, err = cats:expire("Marry", 0.5)
ngx.sleep(0.2)
local val, err = cats:get("Marry")
ngx.say(val) -- "a nice cat"
expire 源码实现
local function shdict_expire(zone, kye, exptime)
zone = check_zone(zone)
if not exptime then
error('bad "exptime" argument', 2)
end
if key == nil then
return nil, "nil key"
end
if (type(key) ~= "string") then
key = tostring(key)
end
local key_len = #key
if key_len == 0 then
return nil, "empty key"
end
if key_len > 65535 then
return nil, "key too long"
end
local rc = C.ngx_http_lua_ffi_shdict_set_expire(zone, key, key_len,
exptime * 1000)
if rc == FFI_ERROR then
return nil, "bad zone"
end
if rc == FFI_DECLINED then
return nil, "not found"
end
-- NGINX_OK/FFI_OK
return true
end
ngx_http_lua_ffi_shdict_set_expire
int
ngx_http_lua_ffi_shdict_set_exptire(ngx_shm_zone_t *zone, u_char *key,
size_t key_len, long exptime)
{
uint32_t hash;
ngx_int_t rc;
ngx_time_t *tp = NULL;
ngx_http_lua_shdict_ctx_t *ctx;
ngx_http_lua_shdict_node_t *sd;
if (zone == NULL) {
return NGX_ERROR;
}
if (exptime > 0) {
tp = ngx_timeofday();
}
ctx = zone->data;
hash = ngx_crc32_short(key, key_len);
ngx_shmtx_lock(&ctx->shpool->mutex);
rc = ngx_http_lua_shdict_peek(zone, hash, key, key_len, &sd);
if (rc == NGX_DECLINED) {
ngx_shmtx_unlock(&ctx->shpool->mutex);
return NGX_DECLINED;
}
/* rc == NGX_OK */
if (exptime > 0) {
sd->expires = (uint64_t) tp->sec * 1000 + tp->msec
+ (uint64_t) exptime;
} else {
sd->expires = 0;
}
ngx_shmtx_unlock(&ctx->shpool->mutex);
return NGX_OK;
}
ngx_http_lua_shdict_peek
static ngx_int_t
ngx_http_lua_shdict_peek(ngx_shm_zone_t *shm_zone, ngx_uint_t hash,
u_char *kdata, size_t klen, ngx_http_lua_shdict_node_t **sdp)
{
ngx_int_t rc;
ngx_rbtree_node_t *node, *sentinel;
ngx_http_lua_shdict_ctx_t *ctx;
ngx_http_lua_shdict_node_t *sd;
ctx = shm_zone->data;
node = ctx->sh->rbtree.root;
sentinel = ctx->sh->rbtree.sentinel;
while (node != sentinel) {
if (hash < node->key) {
node = node->left;
continue;
}
if (hash > node->key) {
node = node->right;
continue;
}
/* hash == node->key */
sd = (ngx_http_lua_shdict_node_t *) &node->color;
rc = ngx_memn2cmp(kdata, sd->data, klen, (size_t) sd->key_len);
if (rc == 0) {
*sdp = sd;
return NGX_OK;
}
node = (rc < 0) ? node->left : node->right;
}
*sdp = NULL;
return NGX_DECLINED;
}