Skip to content

Commit

Permalink
implemented the new redis2_raw_queries directive which supports multi…
Browse files Browse the repository at this point in the history
…ple pipelined redis commands in a single TCP query.
  • Loading branch information
agentzh committed Apr 3, 2011
1 parent f80913b commit c832f9d
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 72 deletions.
24 changes: 24 additions & 0 deletions README
Expand Up @@ -108,6 +108,30 @@ Directives
Specify raw redis queries and nginx variables are recognized
in the CMD argument.

redis2_raw_queries N CMDS
Specify N commands in the CMDS argument. Both the N and CMDS
arguments can take nginx variables.

Here's some examples

location /pipelined {
redis2_raw_queries 3 "flushall\r\nget key1\r\nget key2\r\n";
redis2_pass 127.0.0.1:6379;
}

# GET /pipelined2?n=2&cmds=flushall%0D%0Aget%20key%0D%0A
location /pipelined2 {
set_unescape_uri $n $arg_n;
set_unescape_uri $cmds $arg_cmds;

redis2_raw_queries $n $cmds;

redis2_pass 127.0.0.1:6379;
}

Note that in the second sample above, the set_unescape_uri directive
is provided by the ngx_set_misc module.

redis2_literal_raw_query CMD
Specify raw redis queries but nginx variables are *not* recognized,
that is to say, you're free to use the dollar sign characters ($)
Expand Down
32 changes: 30 additions & 2 deletions src/ngx_http_redis2_handler.c
Expand Up @@ -114,8 +114,10 @@ ngx_http_redis2_create_request(ngx_http_request_t *r)
ngx_chain_t *cl;
ngx_http_redis2_loc_conf_t *rlcf;
ngx_str_t query;
ngx_str_t query_count;
ngx_int_t rc;
ngx_http_redis2_ctx_t *ctx;
ngx_int_t n;

ctx = ngx_http_get_module_ctx(r, ngx_http_redis2_module);

Expand Down Expand Up @@ -145,12 +147,38 @@ ngx_http_redis2_create_request(ngx_http_request_t *r)

if (query.len == 0) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"redis2_raw_query is empty.");
"the redis query is empty");

return NGX_ERROR;
}

ctx->query_count = 1;
if (rlcf->complex_query_count == NULL) {
ctx->query_count = 1;

} else {
if (ngx_http_complex_value(r, rlcf->complex_query_count, &query_count)
!= NGX_OK)
{
return NGX_ERROR;
}

if (query_count.len == 0) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"the N argument to redis2_raw_queries is empty");

return NGX_ERROR;
}

n = ngx_atoi(query_count.data, query_count.len);
if (n == NGX_ERROR || n == 0) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"the N argument to redis2_raw_queries is invalid");

return NGX_ERROR;
}

ctx->query_count = n;
}

b = ngx_create_temp_buf(r->pool, query.len);
if (b == NULL) {
Expand Down
62 changes: 61 additions & 1 deletion src/ngx_http_redis2_module.c
Expand Up @@ -9,7 +9,9 @@
static void *ngx_http_redis2_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_redis2_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
static char * ngx_http_redis2_query(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_http_redis2_raw_queries(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_redis2_query(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_redis2_pass(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
Expand Down Expand Up @@ -41,6 +43,13 @@ static ngx_command_t ngx_http_redis2_commands[] = {
offsetof(ngx_http_redis2_loc_conf_t, complex_query),
NULL },

{ ngx_string("redis2_raw_queries"),
NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE2,
ngx_http_redis2_raw_queries,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL },

{ ngx_string("redis2_literal_raw_query"),
NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
Expand Down Expand Up @@ -354,3 +363,54 @@ ngx_http_redis2_query(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}


static char *
ngx_http_redis2_raw_queries(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
{
ngx_http_redis2_loc_conf_t *rlcf = conf;
ngx_str_t *value;

ngx_http_compile_complex_value_t ccv;

value = cf->args->elts;

/* compile the N argument */

rlcf->complex_query_count = ngx_palloc(cf->pool,
sizeof(ngx_http_complex_value_t));

if (rlcf->complex_query_count == NULL) {
return NGX_CONF_ERROR;
}

ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
ccv.cf = cf;
ccv.value = &value[1];
ccv.complex_value = rlcf->complex_query_count;

if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
return NGX_CONF_ERROR;
}

/* compile the CMDS argument */

rlcf->complex_query = ngx_palloc(cf->pool,
sizeof(ngx_http_complex_value_t));

if (rlcf->complex_query == NULL) {
return NGX_CONF_ERROR;
}

ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
ccv.cf = cf;
ccv.value = &value[2];
ccv.complex_value = rlcf->complex_query;

if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
return NGX_CONF_ERROR;
}

return NGX_CONF_OK;
}

3 changes: 2 additions & 1 deletion src/ngx_http_redis2_module.h
Expand Up @@ -13,6 +13,7 @@ typedef struct {
ngx_http_upstream_conf_t upstream;
ngx_str_t literal_query; /* for redis2_literal_raw_query */
ngx_http_complex_value_t *complex_query; /* for redis2_raw_query */
ngx_http_complex_value_t *complex_query_count; /* for redis2_raw_query */
ngx_http_complex_value_t *complex_target; /* for redis2_pass */
ngx_array_t *queries; /* for redis2_query */

Expand All @@ -26,7 +27,7 @@ typedef ngx_int_t (*ngx_http_redis2_filter_handler_ptr)


struct ngx_http_redis2_ctx_s {
ngx_uint_t query_count;
ngx_int_t query_count;
ngx_http_request_t *request;
int state;
size_t chunk_size;
Expand Down

0 comments on commit c832f9d

Please sign in to comment.