summaryrefslogtreecommitdiff
path: root/proxy_await.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2022-03-01 12:51:47 -0800
committerdormando <dormando@rydia.net>2022-03-01 12:51:47 -0800
commitfa745db8fffe7d13438fe2437bdf8fcb1372bc96 (patch)
tree15bd7946d2d9ac6631c635f5c7ac12228e078f0b /proxy_await.c
parent2a903f04d1b395cd60c1b7357a9b733e19eb7973 (diff)
downloadmemcached-fa745db8fffe7d13438fe2437bdf8fcb1372bc96.tar.gz
proxy: hacky method of supporting noreply/quiet
avoids sending the response to the client, in most cases. works by stripping the noreply status from the request before sending it along, so the proxy itself knows when to move the request forward. has sharp edges: - only looking at the request object that's actually sent to the backend, instead of the request object that created the coroutine. - overriding tokens in lua to re-set the noreply mode would break the protocol. So this change helps us validate the feature but solidifying it requires moving it to the "edges" of processing; before the coroutine and after any command assembly (or within the command assembly).
Diffstat (limited to 'proxy_await.c')
-rw-r--r--proxy_await.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/proxy_await.c b/proxy_await.c
index f69e7df..c504b9a 100644
--- a/proxy_await.c
+++ b/proxy_await.c
@@ -91,6 +91,27 @@ static void mcp_queue_await_io(conn *c, lua_State *Lc, mcp_request_t *rq, int aw
mcp_resp_t *r = lua_newuserdatauv(Lc, sizeof(mcp_resp_t), 1);
memset(r, 0, sizeof(mcp_resp_t));
r->start = rq->start;
+ // Set noreply mode.
+ // TODO (v2): the response "inherits" the request's noreply mode, which isn't
+ // strictly correct; we should inherit based on the request that spawned
+ // the coroutine but the structure doesn't allow that yet.
+ // Should also be able to settle this exact mode from the parser so we
+ // don't have to re-branch here.
+ if (rq->pr.noreply) {
+ if (rq->pr.cmd_type == CMD_TYPE_META) {
+ r->mode = RESP_MODE_METAQUIET;
+ for (int x = 2; x < rq->pr.ntokens; x++) {
+ if (rq->request[rq->pr.tokens[x]] == 'q') {
+ rq->request[rq->pr.tokens[x]] = ' ';
+ }
+ }
+ } else {
+ r->mode = RESP_MODE_NOREPLY;
+ rq->request[rq->pr.reqlen - 3] = 'Y';
+ }
+ } else {
+ r->mode = RESP_MODE_NORMAL;
+ }
int x;
int end = rq->pr.reqlen-2 > RESP_CMD_MAX ? RESP_CMD_MAX : rq->pr.reqlen-2;