summaryrefslogtreecommitdiff
path: root/proto_proxy.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2022-08-08 16:27:22 -0700
committerdormando <dormando@rydia.net>2022-08-24 22:32:40 -0700
commit6bcc5b8553d43f494e85ab3ec2ce789c38a3ca33 (patch)
treed49f62392b0b40419567014621877b5581885e72 /proto_proxy.c
parent2bdf0ec3c8d89d7b75cb8ba7f1290cd937595669 (diff)
downloadmemcached-6bcc5b8553d43f494e85ab3ec2ce789c38a3ca33.tar.gz
proxy: mcp.attach(CMD, r, "tag")
allows using tagged listeners (ex; `-l tag[test]:127.0.0.1:11212`) to select a top level route for a function. expects there to not be dozens of listeners, but for a handful will be faster than a hash table lookup.
Diffstat (limited to 'proto_proxy.c')
-rw-r--r--proto_proxy.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/proto_proxy.c b/proto_proxy.c
index 60c50d6..3ee8c07 100644
--- a/proto_proxy.c
+++ b/proto_proxy.c
@@ -644,8 +644,22 @@ static void proxy_process_command(conn *c, char *command, size_t cmdlen, bool mu
}
struct proxy_hook *hook = &hooks[pr.command];
+ int hook_ref = hook->lua_ref;
+ // if client came from a tagged listener, scan for a more specific hook.
+ // TODO: (v2) avoiding a hash table lookup here, but maybe some other
+ // datastructure would suffice. for 4-8 tags this is perfectly fast.
+ if (c->tag && hook->tagged) {
+ struct proxy_hook_tagged *pht = hook->tagged;
+ while (pht->lua_ref) {
+ if (c->tag == pht->tag) {
+ hook_ref = pht->lua_ref;
+ break;
+ }
+ pht++;
+ }
+ }
- if (!hook->is_lua) {
+ if (!hook_ref) {
// need to pass our command string into the internal handler.
// to minimize the code change, this means allowing it to tokenize the
// full command. The proxy's indirect parser should be built out to
@@ -754,12 +768,15 @@ static void proxy_process_command(conn *c, char *command, size_t cmdlen, bool mu
lua_State *Lc = lua_tothread(L, -1);
// leave the thread first on the stack, so we can reference it if needed.
// pull the lua hook function onto the stack.
- lua_rawgeti(Lc, LUA_REGISTRYINDEX, hook->lua_ref);
+ lua_rawgeti(Lc, LUA_REGISTRYINDEX, hook_ref);
mcp_request_t *rq = mcp_new_request(Lc, &pr, command, cmdlen);
if (multiget) {
rq->ascii_multiget = true;
}
+ // NOTE: option 1) copy c->tag into rq->tag here.
+ // add req:listen_tag() to retrieve in top level route.
+
// TODO (v2): lift this to a post-processor?
if (rq->pr.vlen != 0) {
// relying on temporary malloc's not succumbing as poorly to