WS: Better reuse of the cmd struct for WS clients

For WS clients, reuse a persistent cmd struct attached to the
http_client object: take the cmd built from the WS frame, and copy it to
the persistent cmd.
master
Jessie Murray 3 years ago
parent b98116abc8
commit e26d6358e7
No known key found for this signature in database
GPG Key ID: E7E4D57EDDA744C5

@ -35,11 +35,22 @@ cmd_new(struct http_client *client, int count) {
return c;
}
void
cmd_free_argv(struct cmd *c) {
int i;
fprintf(stderr, "%s: %p\n", __func__, c);
for(i = 0; i < c->count; ++i) {
free((char*)c->argv[i]);
}
free(c->argv);
free(c->argv_len);
}
void
cmd_free(struct cmd *c) {
int i;
if(!c) return;
free(c->jsonp);
@ -53,12 +64,7 @@ cmd_free(struct cmd *c) {
pool_free_context(c->ac);
}
for(i = 0; i < c->count; ++i) {
free((char*)c->argv[i]);
}
free(c->argv);
free(c->argv_len);
cmd_free_argv(c);
free(c);
}

@ -57,6 +57,9 @@ struct subscription {
struct cmd *
cmd_new(struct http_client *c, int count);
void
cmd_free_argv(struct cmd *c);
void
cmd_free(struct cmd *c);

@ -216,16 +216,28 @@ ws_execute(struct http_client *c, const char *frame, size_t frame_len) {
struct cmd *cmd = fun_extract(c, frame, frame_len);
if(cmd) {
/* copy client info into cmd. */
cmd_setup(cmd, c);
cmd->is_websocket = 1;
if (c->self_cmd != NULL) {
/* This client already has its own connection
* to Redis from a previous command; use it from
* now on. */
cmd->ac = c->self_cmd->ac;
/* free args for the previous cmd */
cmd_free_argv(c->self_cmd);
/* copy args from what we just parsed to the persistent command */
c->self_cmd->count = cmd->count;
c->self_cmd->argv = cmd->argv;
c->self_cmd->argv_len = cmd->argv_len;
cmd->argv = NULL;
cmd->argv_len = NULL;
cmd->count = 0;
cmd_free(cmd);
cmd = c->self_cmd; /* replace pointer since we're about to pass it to cmd_send */
} else {
/* copy client info into cmd. */
cmd_setup(cmd, c);
/* First WS command; make new Redis context
* for this client */
cmd->ac = pool_connect(c->w->pool, cmd->database, 0);
@ -390,8 +402,8 @@ ws_frame_and_send_response(struct cmd *cmd, const char *p, size_t sz) {
/* mark as keep alive, otherwise we'll close the connection after the first reply */
int add_ret = evbuffer_add(cmd->http_client->ws_wbuf, frame, frame_sz);
free(frame); /* no longer needed once added to buffer */
if (add_ret < 0) {
free(frame);
slog(cmd->w->s, WEBDIS_ERROR, "Failed response allocation in ws_frame_and_send_response", 0);
return -1;
}

Loading…
Cancel
Save