From beea99d53c96e7b6f7b87e2eb8a21034a0bb515a Mon Sep 17 00:00:00 2001 From: Jeff Lawson Date: Fri, 8 Sep 2017 07:31:53 +0000 Subject: [PATCH 1/9] Add support for "server clear" command. Issue #3 --- generic/tclMemcache.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/generic/tclMemcache.c b/generic/tclMemcache.c index 54c5ef7..ecc0d34 100644 --- a/generic/tclMemcache.c +++ b/generic/tclMemcache.c @@ -132,22 +132,31 @@ static int Memcache_Cmd(ClientData arg, Tcl_Interp * interp, int objc, Tcl_Obj * case cmdServer: /* * Server list manipulation: - * - server add hostname port - * - memcache server delete hostname port + * - memcache server add hostname port + * - memcache server clear */ - if (objc != 5) { - Tcl_WrongNumArgs(interp, 2, objv, "cmd server port"); + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "(add|clear) ..."); return TCL_ERROR; } if (!strcmp(Tcl_GetString(objv[2]), "add")) { + // adds a TCP memcache server + if (objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "add hostname port"); + return TCL_ERROR; + } result = memcached_server_add(get_memc(), Tcl_GetString(objv[3]), atoi(Tcl_GetString(objv[4]))); - } else if (!strcmp(Tcl_GetString(objv[2]), "delete")) { - // TODO: not supported - //mc_server_delete(mc, mc_server_find(mc, Tcl_GetString(objv[3]), 0)); - Tcl_AppendResult(interp, "server delete not supported.", NULL); - return TCL_ERROR; + } else if (!strcmp(Tcl_GetString(objv[2]), "clear")) { + // clear the entire memcache server list. + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "clear"); + return TCL_ERROR; + } + // unfortunately cannot use memcached_servers_set_count because it is internal. + get_memc()->number_of_hosts = 0; + result = 0; } else { - Tcl_AppendResult(interp, "server command not recognized.", NULL); + Tcl_AppendResult(interp, "server subcommand not recognized.", NULL); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewIntObj(result)); @@ -293,16 +302,16 @@ static int Memcache_Cmd(ClientData arg, Tcl_Interp * interp, int objc, Tcl_Obj * switch (cmd) { case cmdIncr: if (objc > 5) { - result = memcached_increment_with_initial(get_memc(), key, strlen(key), size, size64, expires, &size64); + result = memcached_increment_with_initial(get_memc(), key, strlen(key), size, size64, expires, &size64); } else { - result = memcached_increment(get_memc(), key, strlen(key), size, &size64); + result = memcached_increment(get_memc(), key, strlen(key), size, &size64); } break; case cmdDecr: if (objc > 5) { - result = memcached_decrement_with_initial(get_memc(), key, strlen(key), size, size64, expires, &size64); + result = memcached_decrement_with_initial(get_memc(), key, strlen(key), size, size64, expires, &size64); } else { - result = memcached_decrement(get_memc(), key, strlen(key), size, &size64); + result = memcached_decrement(get_memc(), key, strlen(key), size, &size64); } break; } From 973ad4f42cf2faac7e1c3fb033e118b11a443a39 Mon Sep 17 00:00:00 2001 From: Jeff Lawson Date: Fri, 8 Sep 2017 07:34:52 +0000 Subject: [PATCH 2/9] Document server clear command Issue #3 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c1cc662..549a035 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ Available Commands memcache server add hostname port + memcache server clear + memcache get key varname ?lengthVar? ?flagsVar? memcache add key value ?expires? ?flags? From 2397f7fede9e08cda92576ed3b0fa6fdb5161255 Mon Sep 17 00:00:00 2001 From: Peter da Silva Date: Wed, 15 Jun 2022 19:19:58 +0000 Subject: [PATCH 3/9] Call memcached_servers_reset --- generic/tclMemcache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/generic/tclMemcache.c b/generic/tclMemcache.c index ecc0d34..a0aaef8 100644 --- a/generic/tclMemcache.c +++ b/generic/tclMemcache.c @@ -152,8 +152,7 @@ static int Memcache_Cmd(ClientData arg, Tcl_Interp * interp, int objc, Tcl_Obj * Tcl_WrongNumArgs(interp, 2, objv, "clear"); return TCL_ERROR; } - // unfortunately cannot use memcached_servers_set_count because it is internal. - get_memc()->number_of_hosts = 0; + memcached_servers_reset(get_memc()); result = 0; } else { Tcl_AppendResult(interp, "server subcommand not recognized.", NULL); From a1c1e187768c79dec2c691bed16e700eb162ce78 Mon Sep 17 00:00:00 2001 From: Peter da Silva Date: Mon, 20 Jun 2022 15:55:57 +0000 Subject: [PATCH 4/9] Update doc to reference awesomized/libmemcached. Add comment to get human readable error texts. --- README.FreeBSD | 3 ++- README.md | 5 ++++- generic/tclMemcache.c | 19 ++++++++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/README.FreeBSD b/README.FreeBSD index 335882b..0455d3c 100644 --- a/README.FreeBSD +++ b/README.FreeBSD @@ -1,4 +1,5 @@ -pkg install databases/libmemcached +#pkg install databases/libmemcached +echo install git@github.com:awesomized/libmemcached.git env CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure --with-tcl=/usr/local/lib/tcl8.6 diff --git a/README.md b/README.md index 549a035..e96a64e 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,12 @@ The actual memcached server installation is independent of the installation of this client package and is not addressed by this document. +The underlying libmemcached installation recommended is awesomized/libmemcached +because the official libmemcached has not had a release since 2014 and there are +crashing bugs that have had fixes provided that haven't been rolled up into a release. On FreeBSD: -* pkg install databases/libmemcached +* install git@github.com:awesomized/libmemcached.git * env CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure --with-tcl=/usr/local/lib/tcl8.6 * make * make install diff --git a/generic/tclMemcache.c b/generic/tclMemcache.c index a0aaef8..19ccba2 100644 --- a/generic/tclMemcache.c +++ b/generic/tclMemcache.c @@ -61,17 +61,20 @@ static int Memcache_Cmd(ClientData arg, Tcl_Interp * interp, int objc, Tcl_Obj * uint32_t expires = 0; uint64_t size64; int cmd; + int errorcode; // list of supported commands that we expose. enum { cmdGet, cmdAdd, cmdAppend, cmdPrepend, cmdSet, cmdReplace, - cmdDelete, cmdFlush, cmdIncr, cmdDecr, cmdVersion, cmdServer, cmdBehavior + cmdDelete, cmdFlush, cmdIncr, cmdDecr, cmdVersion, cmdServer, cmdBehavior, + cmdStringError }; static CONST char *sCmd[] = { "get", "add", "append", "prepend", "set", "replace", "delete", "flush", "incr", "decr", "version", "server", "behavior", + "strerror", 0 }; @@ -349,6 +352,20 @@ static int Memcache_Cmd(ClientData arg, Tcl_Interp * interp, int objc, Tcl_Obj * uint64_t currentVal = memcached_behavior_get(get_memc(), cmd); Tcl_SetObjResult(interp, Tcl_NewWideIntObj(currentVal)); } + case cmdStringError: + /* + * Return the string associated with a libmemcached error code. + * + * - memcached strerror integer + */ + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "errorcode"); + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(interp, objv[2], &errorcode) != TCL_OK) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, memcached_strerror(get_memc(), errorcode)); } return TCL_OK; } From ecab8bfdfb587505d151600bdc44ef890ee33e94 Mon Sep 17 00:00:00 2001 From: Peter da Silva Date: Mon, 20 Jun 2022 15:58:22 +0000 Subject: [PATCH 5/9] Update LD_LIBRARY_PATH if it's empty so it doesn't get blown away. --- Makefile.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.in b/Makefile.in index 4f80ed2..beaca78 100644 --- a/Makefile.in +++ b/Makefile.in @@ -116,6 +116,9 @@ TCL_SRC_DIR = @TCL_SRC_DIR@ #TK_BIN_DIR = @TK_BIN_DIR@ #TK_SRC_DIR = @TK_SRC_DIR@ +# If this isn't set, resetting it later on will break things +@LD_LIBRARY_PATH_VAR@ ?= /usr/lib:/usr/local/lib + # Not used, but retained for reference of what libs Tcl required #TCL_LIBS = @TCL_LIBS@ From 0b9999a7270319dfeb5660b37ecc74a8882804d9 Mon Sep 17 00:00:00 2001 From: Peter da Silva Date: Mon, 20 Jun 2022 16:03:23 +0000 Subject: [PATCH 6/9] Fix call to Tcl_SetResult --- generic/tclMemcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclMemcache.c b/generic/tclMemcache.c index 19ccba2..ed4e2c5 100644 --- a/generic/tclMemcache.c +++ b/generic/tclMemcache.c @@ -365,7 +365,7 @@ static int Memcache_Cmd(ClientData arg, Tcl_Interp * interp, int objc, Tcl_Obj * if (Tcl_GetIntFromObj(interp, objv[2], &errorcode) != TCL_OK) { return TCL_ERROR; } - Tcl_SetObjResult(interp, memcached_strerror(get_memc(), errorcode)); + Tcl_SetResult(interp, memcached_strerror(get_memc(), errorcode), TCL_VOLATILE); } return TCL_OK; } From 0ab22e2bfd8d5fe6fa15a10ee60a46d08963ac67 Mon Sep 17 00:00:00 2001 From: Peter da Silva Date: Mon, 20 Jun 2022 16:09:23 +0000 Subject: [PATCH 7/9] Update tests to check results and use "memcache strerror" to report errors --- tests/all.tcl | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/tests/all.tcl b/tests/all.tcl index a2d9650..222bee4 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -2,9 +2,21 @@ package require Memcache #load ./memcache[info sharedlibextension] -memcache server add localhost 11211 -memcache set moo "cows go moo" -memcache get moo value +set result [memcache server add localhost 11211] +if {$result} { + puts "memcache server add: [memcache strerror $result]" + exit 1 +} +set result [memcache set moo "cows go moo"] +if {$result} { + puts "memcache set: [memcache strerror $result]" + exit 1 +} +set result [memcache get moo value] +if {$result} { + puts "memcache get: [memcache strerror $result]" + exit 1 +} if {$value != "cows go moo"} { puts "Error. value=$value!\n"; exit 1 @@ -12,11 +24,19 @@ if {$value != "cows go moo"} { set value "Boeing 777-200 (طائرة نفاثة ثنائية المحرك)" -memcache set unicodeTest $value -memcache get unicodeTest newvalue +set result [memcache set unicodeTest $value] +if {$result} { + puts "memcache set: [memcache strerror $result]" + exit 1 +} +set result [memcache get unicodeTest newvalue] +if {$result} { + puts "memcache set: [memcache strerror $result]" + exit 1 +} if {$value != $newvalue} { puts "Error. newvalue=$newvalue!\n"; - exit 1 + exit 1 } puts "Success" From f023f31d44c10426ac4e66b946e58d12add0794e Mon Sep 17 00:00:00 2001 From: Peter da Silva Date: Mon, 20 Jun 2022 16:16:03 +0000 Subject: [PATCH 8/9] test server clear. Not crashy. --- tests/all.tcl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/all.tcl b/tests/all.tcl index 222bee4..ce924d8 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -7,6 +7,22 @@ if {$result} { puts "memcache server add: [memcache strerror $result]" exit 1 } + +# Clear server list just to make sure. +set result [memcache server clear] +if {$result} { + puts "memcache server clear: [memcache strerror $result]" + exit 1 +} + +# add again +set result [memcache server add localhost 11211] +if {$result} { + puts "memcache server add: [memcache strerror $result]" + exit 1 +} + +# actually test something set result [memcache set moo "cows go moo"] if {$result} { puts "memcache set: [memcache strerror $result]" From c56e32db85c1ab22c98a85a2a987352736721aa6 Mon Sep 17 00:00:00 2001 From: Peter da Silva Date: Mon, 20 Jun 2022 16:25:54 +0000 Subject: [PATCH 9/9] Document strerror command. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index e96a64e..dfd4e53 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ on success or some other integer error. If the returned value is non-zero then the request failed, and you should not expect any varname arguments to have been modified. +Use `memcache strerror` to get a human readable version of the error code. + Available Commands ------------------ @@ -86,3 +88,5 @@ Available Commands memcache version memcache behavior flagname ?flagvalue? + + memcache strerror errorcode