Skip to content

Commit

Permalink
Merge branch 'thiagoc01-timeout-keyval-zone'
Browse files Browse the repository at this point in the history
  • Loading branch information
kjdev committed Mar 31, 2024
2 parents a620e4c + d3f7992 commit 0adec5c
Show file tree
Hide file tree
Showing 7 changed files with 1,084 additions and 5 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,17 @@ The database is stored in shared memory or Redis as specified
by the zone parameter.

```
Syntax: keyval_zone zone=name:size;
Syntax: keyval_zone zone=name:size [timeout=time] [ttl=time];
Default: -
Context: http
```

Sets the `name` and `size` of the shared memory zone that
keeps the key-value database.

The optional `timeout` or `ttl` parameter sets the time to live
which key-value pairs are removed (default value is `0` seconds).

```
Syntax: keyval_zone_redis zone=name [hostname=name] [port=number] [database=number] [connect_timeout=time] [ttl=time];
Default: -
Expand Down Expand Up @@ -145,14 +148,16 @@ The database is stored in shared memory or Redis as specified
by the zone parameter.

```
Syntax: keyval_zone zone=name:size;
Syntax: keyval_zone zone=name:size [timeout=time] [ttl=time];
Default: -
Context: http
```

Sets the `name` and `size` of the shared memory zone that
keeps the key-value database.

The optional `timeout` or `ttl` parameter sets the time to live which key-value pairs are removed (default value is 0 seconds).

```
Syntax: keyval_zone_redis zone=name [hostname=name] [port=number] [database=number] [connect_timeout=time] [ttl=time];
Default: -
Expand Down Expand Up @@ -187,4 +192,4 @@ Example
TODO
----

- [ ] Support for `[state=file]`, `[timeout=time]` in `keyval_zone` directive
- [ ] Support for `[state=file]` in `keyval_zone` directive
2 changes: 1 addition & 1 deletion src/ngx_http_keyval_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ static ngx_command_t ngx_http_keyval_commands[] = {
0,
NULL },
{ ngx_string("keyval_zone"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
NGX_HTTP_MAIN_CONF|NGX_CONF_1MORE,
ngx_http_keyval_conf_set_zone,
0,
0,
Expand Down
80 changes: 80 additions & 0 deletions src/ngx_keyval.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <ngx_event.h>
#include "ngx_keyval.h"

static void
Expand Down Expand Up @@ -193,6 +194,7 @@ ngx_keyval_conf_set_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf,
ngx_keyval_conf_t *config, void *tag)
{
ssize_t size;
ngx_uint_t i;
ngx_shm_zone_t *shm_zone;
ngx_str_t name, *value;
ngx_keyval_shm_ctx_t *ctx;
Expand Down Expand Up @@ -267,6 +269,41 @@ ngx_keyval_conf_set_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf,
shm_zone->init = ngx_keyval_init_zone;
shm_zone->data = ctx;

ctx->ttl = 0;

for (i = 2; i < cf->args->nelts; i++) {
ngx_str_t s = ngx_null_string;

if (ngx_strncmp(value[i].data, "ttl=", 4) == 0 && value[i].len > 4) {
s.len = value[i].len - 4;
s.data = value[i].data + 4;
} else if (ngx_strncmp(value[i].data, "timeout=", 8) == 0
&& value[i].len > 8) {
s.len = value[i].len - 8;
s.data = value[i].data + 8;
} else {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%V\" invalid parameter \"%V\"",
&cmd->name, &value[i]);
return NGX_CONF_ERROR;
}

if (ctx->ttl != 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%V\" duplicate parameter \"%V\"",
&cmd->name, &value[i]);
return NGX_CONF_ERROR;
}

ctx->ttl = ngx_parse_time(&s, 1);
if (ctx->ttl == (time_t) NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%V\" invalid parameter \"%V\"",
&cmd->name, &value[2]);
return NGX_CONF_ERROR;
}
}

return NGX_CONF_OK;
}

Expand Down Expand Up @@ -550,6 +587,19 @@ ngx_keyval_shm_get_data(ngx_keyval_shm_ctx_t *ctx, ngx_shm_zone_t *shm,
return NGX_OK;
}

static void
ngx_keyval_delete_timeout_node_shm(ngx_event_t *node_status)
{
ngx_keyval_node_timeout_t *arg
= (ngx_keyval_node_timeout_t *) node_status->data;

if (arg->ctx->shpool != NULL && arg->node != NULL) {
ngx_rbtree_delete(&arg->ctx->sh->rbtree, arg->node);
ngx_slab_free(arg->ctx->shpool, arg->node);
ngx_slab_free(arg->ctx->shpool, arg);
}
}

ngx_int_t
ngx_keyval_shm_set_data(ngx_keyval_shm_ctx_t *ctx, ngx_shm_zone_t *shm,
ngx_str_t *key, ngx_str_t *val, ngx_log_t *log)
Expand Down Expand Up @@ -596,6 +646,36 @@ ngx_keyval_shm_set_data(ngx_keyval_shm_ctx_t *ctx, ngx_shm_zone_t *shm,
ngx_rbtree_insert(&ctx->sh->rbtree, node);

rc = NGX_OK;

if (ctx->ttl) {
ngx_event_t *timeout_node_event
= ngx_slab_alloc_locked(ctx->shpool, sizeof(ngx_event_t));

if (timeout_node_event == NULL) {
ngx_log_error(NGX_LOG_ERR, log, 0,
"keyval: failed to allocate timeout event");
rc = NGX_ERROR;
} else {
ngx_keyval_node_timeout_t *timeout_node
= ngx_slab_alloc_locked(ctx->shpool,
sizeof(ngx_keyval_node_timeout_t));

if (timeout_node == NULL) {
ngx_log_error(NGX_LOG_ERR, log, 0,
"keyval: failed to allocate timeout node");
rc = NGX_ERROR;
ngx_slab_free_locked(ctx->shpool, timeout_node_event);
} else {
timeout_node->node = node;
timeout_node->ctx = ctx;

timeout_node_event->data = (void *) timeout_node;
timeout_node_event->handler = ngx_keyval_delete_timeout_node_shm;
timeout_node_event->log = shm->shm.log;
ngx_add_timer(timeout_node_event, ctx->ttl * 1000);
}
}
}
}

ngx_shmtx_unlock(&ctx->shpool->mutex);
Expand Down
6 changes: 6 additions & 0 deletions src/ngx_keyval.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,14 @@ typedef struct {
typedef struct {
ngx_keyval_sh_t *sh;
ngx_slab_pool_t *shpool;
time_t ttl;
} ngx_keyval_shm_ctx_t;

typedef struct {
ngx_rbtree_node_t *node;
ngx_keyval_shm_ctx_t *ctx;
} ngx_keyval_node_timeout_t;

typedef struct {
u_char *hostname;
ngx_int_t port;
Expand Down
2 changes: 1 addition & 1 deletion src/ngx_stream_keyval_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ static ngx_command_t ngx_stream_keyval_commands[] = {
0,
NULL },
{ ngx_string("keyval_zone"),
NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1,
NGX_STREAM_MAIN_CONF|NGX_CONF_1MORE,
ngx_stream_keyval_conf_set_zone,
0,
0,
Expand Down
Loading

0 comments on commit 0adec5c

Please sign in to comment.