feature: added new method "get_stale" to shared dict objects, which returns the value (if not freed yet) even if the key has already expired. thanks Matthieu Tourne for the patch in #249.

This commit is contained in:
Yichun Zhang (agentzh) 2013-08-01 17:56:35 -07:00
Родитель 2f5ebebcd3
Коммит 124f50fd46
3 изменённых файлов: 64 добавлений и 5 удалений

Просмотреть файл

@ -18,6 +18,8 @@
static int ngx_http_lua_shdict_set(lua_State *L);
static int ngx_http_lua_shdict_safe_set(lua_State *L);
static int ngx_http_lua_shdict_get(lua_State *L);
static int ngx_http_lua_shdict_get_stale(lua_State *L);
static int ngx_http_lua_shdict_get_helper(lua_State *L, int get_stale);
static int ngx_http_lua_shdict_expire(ngx_http_lua_shdict_ctx_t *ctx,
ngx_uint_t n);
static ngx_int_t ngx_http_lua_shdict_lookup(ngx_shm_zone_t *shm_zone,
@ -291,11 +293,14 @@ ngx_http_lua_inject_shdict_api(ngx_http_lua_main_conf_t *lmcf, lua_State *L)
lua_createtable(L, 0, lmcf->shm_zones->nelts /* nrec */);
/* ngx.shared */
lua_createtable(L, 0 /* narr */, 12 /* nrec */); /* shared mt */
lua_createtable(L, 0 /* narr */, 13 /* nrec */); /* shared mt */
lua_pushcfunction(L, ngx_http_lua_shdict_get);
lua_setfield(L, -2, "get");
lua_pushcfunction(L, ngx_http_lua_shdict_get_stale);
lua_setfield(L, -2, "get_stale");
lua_pushcfunction(L, ngx_http_lua_shdict_set);
lua_setfield(L, -2, "set");
@ -355,6 +360,20 @@ ngx_http_lua_inject_shdict_api(ngx_http_lua_main_conf_t *lmcf, lua_State *L)
static int
ngx_http_lua_shdict_get(lua_State *L)
{
return ngx_http_lua_shdict_get_helper(L, 0 /* stale */);
}
static int
ngx_http_lua_shdict_get_stale(lua_State *L)
{
return ngx_http_lua_shdict_get_helper(L, 1 /* stale */);
}
static int
ngx_http_lua_shdict_get_helper(lua_State *L, int get_stale)
{
int n;
ngx_str_t name;
@ -411,20 +430,22 @@ ngx_http_lua_shdict_get(lua_State *L)
ngx_shmtx_lock(&ctx->shpool->mutex);
#if 1
ngx_http_lua_shdict_expire(ctx, 1);
if (!get_stale) {
ngx_http_lua_shdict_expire(ctx, 1);
}
#endif
rc = ngx_http_lua_shdict_lookup(zone, hash, key.data, key.len, &sd);
dd("shdict lookup returns %d", (int) rc);
if (rc == NGX_DECLINED || rc == NGX_DONE) {
if (rc == NGX_DECLINED || (rc == NGX_DONE && !get_stale)) {
ngx_shmtx_unlock(&ctx->shpool->mutex);
lua_pushnil(L);
return 1;
}
/* rc == NGX_OK */
/* rc == NGX_OK || (rc == NGX_DONE && get_stale) */
value_type = sd->value_type;
@ -485,6 +506,21 @@ ngx_http_lua_shdict_get(lua_State *L)
ngx_shmtx_unlock(&ctx->shpool->mutex);
if (get_stale) {
/* always return value, flags, stale */
if (user_flags) {
lua_pushinteger(L, (lua_Integer) user_flags);
} else {
lua_pushnil(L);
}
lua_pushboolean(L, rc == NGX_DONE);
return 3;
}
if (user_flags) {
lua_pushinteger(L, (lua_Integer) user_flags);
return 2;

Просмотреть файл

@ -1452,3 +1452,26 @@ cur value: hello hello hello hello hello hello hello hello hello hello1
--- no_error_log
[error]
=== TEST 60: get_stale: expired entries can still be fetched
--- http_config
lua_shared_dict dogs 1m;
--- config
location = /test {
content_by_lua '
local dogs = ngx.shared.dogs
dogs:set("foo", 32, 0.01)
dogs:set("blah", 33, 0.1)
ngx.sleep(0.01)
local val, flags, stale = dogs:get_stale("foo")
ngx.say(val, ", ", flags, ", ", stale)
local val, flags, stale = dogs:get_stale("blah")
ngx.say(val, ", ", flags, ", ", stale)
';
}
--- request
GET /test
--- response_body
32, nil, true
33, nil, false

Просмотреть файл

@ -279,7 +279,7 @@ n = 4
--- request
GET /test
--- response_body
n = 12
n = 13
--- no_error_log
[error]