From 311bd0fafe1da7b5cc770a2ff4fac5472a801a40 Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Sat, 1 Dec 2007 03:43:52 -0800 Subject: [PATCH] Fix for Linux system for async protocol. Fix for reworked memcached_get() code. This should solve the known issues with the protocol going weird while using async. --- ChangeLog | 2 + configure.ac | 3 +- include/memcached.h | 1 + lib/common.h | 2 + lib/memcached.c | 7 ++- lib/memcached_do.c | 6 ++- lib/memcached_get.c | 102 ++++++++++++++++++++++----------------- lib/memcached_io.c | 31 ++++++------ lib/memcached_quit.c | 2 +- lib/memcached_response.c | 3 ++ lib/memcached_strerror.c | 2 + src/memslap.c | 63 ++++++++++++------------ tests/function.c | 15 +++--- tests/output.res | 15 ++++++ 14 files changed, 146 insertions(+), 108 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42273139..35814be1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,8 @@ * Fixed bug where in non-block mode all data might not have been sent on close(). * Refactor of memcached_get() to use common code. + * Change in value fetch, MEMCACHED_END is now returned when keys are no + longer in the pipe. 0.11 Mon Nov 26 01:05:52 PST 2007 diff --git a/configure.ac b/configure.ac index 0c8be6ff..76c28ede 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,7 @@ AC_INIT(src/memcat.c) AC_CONFIG_AUX_DIR(config) AM_CONFIG_HEADER(include/libmemcached_config.h) +AC_CANONICAL_SYSTEM MEMCACHED_LIBRARY_NAME=libmemcached @@ -14,7 +15,7 @@ MEMCACHED_API_VERSION=1.0 AC_SUBST(MEMCACHED_API_VERSION) #shared library versioning -MEMCACHED_LIBRARY_VERSION=1:1:0 +MEMCACHED_LIBRARY_VERSION=1:2:0 # | | | # +------+ | +---+ # | | | diff --git a/include/memcached.h b/include/memcached.h index c0b5a7cb..11c760d2 100644 --- a/include/memcached.h +++ b/include/memcached.h @@ -66,6 +66,7 @@ typedef enum { MEMCACHED_FAIL_UNIX_SOCKET, MEMCACHED_NOT_SUPPORTED, MEMCACHED_NO_KEY_PROVIDED, + MEMCACHED_FETCH_NOTFINISHED, MEMCACHED_MAXIMUM_RETURN, /* Always add new error code before */ } memcached_return; diff --git a/lib/common.h b/lib/common.h index 5c2d2682..2edd83e5 100644 --- a/lib/common.h +++ b/lib/common.h @@ -93,6 +93,8 @@ void memcached_string_free(memcached_string_st *string); memcached_return memcached_do(memcached_st *ptr, unsigned int server_key, char *commmand, size_t command_length, char with_flush); memcached_return memcached_version(memcached_st *ptr); +memcached_return memcached_finish_server(memcached_st *ptr, unsigned int server_key); +void memcached_finish(memcached_st *ptr); diff --git a/lib/memcached.c b/lib/memcached.c index 861bafda..a5be8e25 100644 --- a/lib/memcached.c +++ b/lib/memcached.c @@ -61,9 +61,12 @@ memcached_st *memcached_clone(memcached_st *clone, memcached_st *ptr) } new_clone= memcached_create(clone); + + if (new_clone == NULL) + return NULL; - - rc= memcached_server_push(new_clone, ptr->hosts); + if (ptr->hosts) + rc= memcached_server_push(new_clone, ptr->hosts); if (rc != MEMCACHED_SUCCESS) { diff --git a/lib/memcached_do.c b/lib/memcached_do.c index c6bc96c0..f310a5bc 100644 --- a/lib/memcached_do.c +++ b/lib/memcached_do.c @@ -10,7 +10,11 @@ memcached_return memcached_do(memcached_st *ptr, unsigned int server_key, char * WATCHPOINT_ASSERT(command); if (ptr->hosts[server_key].cursor_active) - memcached_quit_server(ptr, server_key); + { + memcached_return rc; + rc= memcached_finish_server(ptr, server_key); + ptr->hosts[server_key].cursor_active= 0; + } if ((rc= memcached_connect(ptr, server_key)) != MEMCACHED_SUCCESS) return rc; diff --git a/lib/memcached_get.c b/lib/memcached_get.c index 0ca40523..80423e6b 100644 --- a/lib/memcached_get.c +++ b/lib/memcached_get.c @@ -14,12 +14,14 @@ static memcached_return memcached_value_fetch(memcached_st *ptr, char *key, size end_ptr= buffer + MEMCACHED_DEFAULT_COMMAND_SIZE; - *flags= 0; + if (flags) + *flags= 0; memcached_string_reset(value); rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key); + if (rc == MEMCACHED_SUCCESS) { char *next_ptr; @@ -51,7 +53,8 @@ static memcached_return memcached_value_fetch(memcached_st *ptr, char *key, size if (end_ptr == string_ptr) goto read_error; for (next_ptr= string_ptr; isdigit(*string_ptr); string_ptr++); - *flags= (uint16_t)strtol(next_ptr, &string_ptr, 10); + if (flags) + *flags= (uint16_t)strtol(next_ptr, &string_ptr, 10); if (end_ptr == string_ptr) goto read_error; @@ -129,8 +132,6 @@ static memcached_return memcached_value_fetch(memcached_st *ptr, char *key, size return MEMCACHED_SUCCESS; } } - else if (rc == MEMCACHED_END) - rc= MEMCACHED_NOTFOUND; return rc; @@ -158,6 +159,9 @@ char *memcached_get(memcached_st *ptr, char *key, size_t key_length, value= memcached_fetch(ptr, NULL, NULL, value_length, flags, error); + if (*error == MEMCACHED_END) + *error= MEMCACHED_NOTFOUND; + if (value == NULL) return NULL; @@ -198,6 +202,8 @@ memcached_return memcached_mget(memcached_st *ptr, get_command_length= 5; } + memcached_finish(ptr); + for (x= 0; x < number_of_keys; x++) { unsigned int server_key; @@ -219,7 +225,7 @@ memcached_return memcached_mget(memcached_st *ptr, if ((memcached_io_write(ptr, server_key, keys[x], key_length[x], 0)) == -1) { - ptr->hosts[server_key].cursor_active = 0; + ptr->hosts[server_key].cursor_active= 0; memcached_quit_server(ptr, server_key); rc= MEMCACHED_SOME_ERRORS; continue; @@ -227,14 +233,13 @@ memcached_return memcached_mget(memcached_st *ptr, if ((memcached_io_write(ptr, server_key, " ", 1, 0)) == -1) { - ptr->hosts[server_key].cursor_active = 0; + ptr->hosts[server_key].cursor_active= 0; memcached_quit_server(ptr, server_key); rc= MEMCACHED_SOME_ERRORS; continue; } } - /* Should we muddle on if some servers are dead? */ @@ -275,32 +280,19 @@ char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length, flags, NULL, ptr->cursor_server); *value_length= memcached_string_length(result_buffer); - if (*error == MEMCACHED_NOTFOUND) + if (*error == MEMCACHED_END) /* END means that we move on to the next */ { - ptr->hosts[ptr->cursor_server].cursor_active = 0; + ptr->hosts[ptr->cursor_server].cursor_active= 0; ptr->cursor_server++; + continue; } - else if (*error == MEMCACHED_END && *value_length == 0) - { - return NULL; - } - else if (*error == MEMCACHED_END) - { - WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */ - *value_length= 0; - return NULL; - } - else if (*error != MEMCACHED_SUCCESS) - { - return NULL; - } - else - { + else if (*error == MEMCACHED_SUCCESS) return memcached_string_c_copy(result_buffer); - } - + else + return NULL; } + ptr->cursor_server= 0; *value_length= 0; return NULL; } @@ -329,28 +321,16 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, &result->cas, ptr->cursor_server); - if (*error == MEMCACHED_NOTFOUND) + if (*error == MEMCACHED_END) /* END means that we move on to the next */ { - ptr->hosts[ptr->cursor_server].cursor_active = 0; + ptr->hosts[ptr->cursor_server].cursor_active= 0; ptr->cursor_server++; + continue; } - else if (*error == MEMCACHED_END && memcached_string_length((memcached_string_st *)(&result->value)) == 0) - { - break; - } - else if (*error == MEMCACHED_END) - { - WATCHPOINT_ASSERT(0); /* If this happens we have somehow messed up the fetch */ - break; - } - else if (*error != MEMCACHED_SUCCESS) - { - break; - } - else - { + else if (*error == MEMCACHED_SUCCESS) return result; - } + else + return NULL; } /* An error has occurred */ @@ -359,5 +339,37 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr, else memcached_string_reset(&result->value); + ptr->cursor_server= 0; return NULL; } + +memcached_return memcached_finish_server(memcached_st *ptr, unsigned int server_key) +{ + memcached_return rc; + memcached_string_st *result_buffer; + + result_buffer= &ptr->result_buffer; + + rc= MEMCACHED_SUCCESS; + while (rc == MEMCACHED_SUCCESS) + { + rc= memcached_value_fetch(ptr, NULL, NULL, result_buffer, + NULL, NULL, server_key); + } + ptr->hosts[server_key].cursor_active= 0; + + return rc; +} + +void memcached_finish(memcached_st *ptr) +{ + unsigned int x; + + for (x= 0; x < ptr->number_of_hosts; x++) + { + if (ptr->hosts[x].cursor_active) + (void)memcached_finish_server(ptr, x); + } + + ptr->cursor_server= 0; +} diff --git a/lib/memcached_io.c b/lib/memcached_io.c index 0657dfd6..f9eae4db 100644 --- a/lib/memcached_io.c +++ b/lib/memcached_io.c @@ -11,10 +11,7 @@ static int io_wait(memcached_st *ptr, unsigned int server_key, unsigned read_or_ { struct pollfd fds[1]; short flags= 0; - struct timespec timer; - timer.tv_sec= 1; - timer.tv_nsec= 0; if (read_or_write) flags= POLLOUT | POLLERR; else @@ -126,24 +123,24 @@ ssize_t memcached_io_write(memcached_st *ptr, unsigned int server_key, memcached_return memcached_io_close(memcached_st *ptr, unsigned int server_key) { - struct pollfd fds[1]; - short flags= 0; - struct timespec timer; memcached_return rc; - timer.tv_sec= 1; - timer.tv_nsec= 0; - flags= POLLHUP | POLLERR; + rc= MEMCACHED_SUCCESS; + if (ptr->flags & MEM_NO_BLOCK) + { + struct pollfd fds[1]; + short flags= 0; - memset(&fds, 0, sizeof(struct pollfd)); - fds[0].fd= ptr->hosts[server_key].fd; - fds[0].events= flags; - fds[0].revents= flags; + flags= POLLHUP | POLLERR; - if (poll(fds, 1, ptr->poll_timeout) < 0) - rc= MEMCACHED_FAILURE; - else - rc= MEMCACHED_SUCCESS; + memset(&fds, 0, sizeof(struct pollfd)); + fds[0].fd= ptr->hosts[server_key].fd; + fds[0].events= flags; + fds[0].revents= 0; + + if (poll(fds, 1, ptr->poll_timeout == -1 ? 100 : ptr->poll_timeout) < 0) + rc= MEMCACHED_FAILURE; + } close(ptr->hosts[server_key].fd); diff --git a/lib/memcached_quit.c b/lib/memcached_quit.c index 483b1772..85a52861 100644 --- a/lib/memcached_quit.c +++ b/lib/memcached_quit.c @@ -20,7 +20,7 @@ void memcached_quit_server(memcached_st *ptr, unsigned int server_key) { memcached_return rc; rc= memcached_do(ptr, server_key, "quit\r\n", 6, 1); - WATCHPOINT_ASSERT(rc == MEMCACHED_SUCCESS); + WATCHPOINT_ASSERT(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_FETCH_NOTFINISHED); memcached_io_close(ptr, server_key); ptr->hosts[server_key].fd= -1; diff --git a/lib/memcached_response.c b/lib/memcached_response.c index 78b314f4..076b0a6f 100644 --- a/lib/memcached_response.c +++ b/lib/memcached_response.c @@ -43,6 +43,9 @@ memcached_return memcached_response(memcached_st *ptr, total_length++; WATCHPOINT_ASSERT(total_length < buffer_length); + + if (total_length >= buffer_length) + return MEMCACHED_PROTOCOL_ERROR; } buffer_ptr++; *buffer_ptr= 0; diff --git a/lib/memcached_strerror.c b/lib/memcached_strerror.c index 65e837e8..2deb4d5f 100644 --- a/lib/memcached_strerror.c +++ b/lib/memcached_strerror.c @@ -60,6 +60,8 @@ char *memcached_strerror(memcached_st *ptr, memcached_return rc) return "COULD NOT OPEN UNIX SOCKET"; case MEMCACHED_NOT_SUPPORTED: return "ACTION NOT SUPPORTED"; + case MEMCACHED_FETCH_NOTFINISHED: + return "FETCH WAS NOT COMPLETED"; case MEMCACHED_NO_KEY_PROVIDED: return "A KEY LENGTH OF ZERO WAS PROVIDED"; case MEMCACHED_MAXIMUM_RETURN: diff --git a/src/memslap.c b/src/memslap.c index 0dd7ebca..e25d0c03 100644 --- a/src/memslap.c +++ b/src/memslap.c @@ -50,7 +50,7 @@ struct thread_context_st { pairs_st *execute_pairs; unsigned int execute_number; test_type test; - memcached_server_st *servers; + memcached_st *memc; }; struct conclusions_st { @@ -64,9 +64,9 @@ struct conclusions_st { void options_parse(int argc, char *argv[]); void conclusions_print(conclusions_st *conclusion); void scheduler(memcached_server_st *servers, conclusions_st *conclusion); -pairs_st *load_create_data(memcached_server_st *servers, unsigned int number_of, - unsigned int *actual_loaded); -void flush_all(memcached_server_st *servers); +pairs_st *load_create_data(memcached_st *memc, unsigned int number_of, + unsigned int *actual_loaded); +void flush_all(memcached_st *memc); static int opt_verbose= 0; static int opt_flush= 0; @@ -124,6 +124,7 @@ void scheduler(memcached_server_st *servers, conclusions_st *conclusion) { unsigned int x; unsigned int actual_loaded; + memcached_st *memc; struct timeval start_time, end_time; pthread_t mainthread; /* Thread descriptor */ @@ -134,10 +135,23 @@ void scheduler(memcached_server_st *servers, conclusions_st *conclusion) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + memc= memcached_create(NULL); + memcached_server_push(memc, servers); + if (opt_flush) - flush_all(servers); + flush_all(memc); if (opt_createial_load) - pairs= load_create_data(servers, opt_createial_load, &actual_loaded); + pairs= load_create_data(memc, opt_createial_load, &actual_loaded); + + /* We set this after we have loaded */ + { + unsigned int value= 1; + if (opt_non_blocking_io) + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &value); + if (opt_tcp_nodelay) + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &value); + } + pthread_mutex_lock(&counter_mutex); thread_counter= 0; @@ -152,7 +166,7 @@ void scheduler(memcached_server_st *servers, conclusions_st *conclusion) context= (thread_context_st *)malloc(sizeof(thread_context_st)); memset(context, 0, sizeof(thread_context_st)); - context->servers= servers; + context->memc= memcached_clone(NULL, memc); context->test= opt_test; context->initial_pairs= pairs; @@ -312,16 +326,8 @@ void *run_task(void *p) { thread_context_st *context= (thread_context_st *)p; memcached_st *memc; - unsigned int value= 1; - memc= memcached_create(NULL); - WATCHPOINT_ASSERT(memc); - if (opt_non_blocking_io) - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &value); - if (opt_tcp_nodelay) - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &value); - - memcached_server_push(memc, context->servers); + memc= context->memc; pthread_mutex_lock(&sleeper_mutex); while (master_wakeup) @@ -355,34 +361,25 @@ void *run_task(void *p) return NULL; } -void flush_all(memcached_server_st *servers) +void flush_all(memcached_st *memc) { - memcached_st *memc; - - memc= memcached_create(NULL); - - memcached_server_push(memc, servers); - memcached_flush(memc, 0); - - memcached_free(memc); } -pairs_st *load_create_data(memcached_server_st *servers, unsigned int number_of, - unsigned int *actual_loaded) +pairs_st *load_create_data(memcached_st *memc, unsigned int number_of, + unsigned int *actual_loaded) { - memcached_st *memc; + memcached_st *clone; pairs_st *pairs; - memc= memcached_create(NULL); + clone= memcached_clone(NULL, memc); /* We always used non-blocking IO for load since it is faster */ - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL ); - memcached_server_push(memc, servers); + memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL ); pairs= pairs_generate(number_of); - *actual_loaded= execute_set(memc, pairs, number_of); + *actual_loaded= execute_set(clone, pairs, number_of); - memcached_free(memc); + memcached_free(clone); return pairs; } diff --git a/tests/function.c b/tests/function.c index 5ececc5f..fe4b2d86 100644 --- a/tests/function.c +++ b/tests/function.c @@ -112,7 +112,6 @@ uint8_t set_test(memcached_st *memc) rc= memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint16_t)0); - WATCHPOINT_ERROR(rc); assert(rc == MEMCACHED_SUCCESS); return 0; @@ -662,7 +661,7 @@ uint8_t mget_result_test(memcached_st *memc) while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL) assert(!results); - assert(rc == MEMCACHED_NOTFOUND); + assert(rc == MEMCACHED_END); for (x= 0; x < 3; x++) { @@ -712,7 +711,7 @@ uint8_t mget_result_alloc_test(memcached_st *memc) assert(results); } assert(!results); - assert(rc == MEMCACHED_NOTFOUND); + assert(rc == MEMCACHED_END); for (x= 0; x < 3; x++) { @@ -768,7 +767,7 @@ uint8_t mget_test(memcached_st *memc) } assert(!return_value); assert(return_value_length == 0); - assert(rc == MEMCACHED_NOTFOUND); + assert(rc == MEMCACHED_END); for (x= 0; x < 3; x++) { @@ -1234,7 +1233,7 @@ uint8_t user_supplied_bug6(memcached_st *memc) &value_length, &flags, &rc))) count++; assert(count == 0); - assert(rc == MEMCACHED_NOTFOUND); + assert(rc == MEMCACHED_END); for (x= 0; x < 4; x++) { @@ -1244,7 +1243,7 @@ uint8_t user_supplied_bug6(memcached_st *memc) assert(rc == MEMCACHED_SUCCESS); } - for (x= 0; x < 10; x++) + for (x= 0; x < 2; x++) { value= memcached_get(memc, keys[0], key_length[0], &value_length, &flags, &rc); @@ -1259,10 +1258,10 @@ uint8_t user_supplied_bug6(memcached_st *memc) { value= memcached_fetch(memc, return_key, &return_key_length, &value_length, &flags, &rc); - memcmp(value, insert_data, value_length); + assert(rc == MEMCACHED_SUCCESS); + assert(!(memcmp(value, insert_data, value_length))); assert(value_length); free(value); - assert(rc == MEMCACHED_SUCCESS); } } diff --git a/tests/output.res b/tests/output.res index 8d71e670..5338cf17 100644 --- a/tests/output.res +++ b/tests/output.res @@ -34,6 +34,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -107,6 +108,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -180,6 +182,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -253,6 +256,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -326,6 +330,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -399,6 +404,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -472,6 +478,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -545,6 +552,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -618,6 +626,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -691,6 +700,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -764,6 +774,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -837,6 +848,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -910,6 +922,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -983,6 +996,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time @@ -1056,6 +1070,7 @@ Error 25 -> SYSTEM ERROR Error 26 -> COULD NOT OPEN UNIX SOCKET Error 27 -> ACTION NOT SUPPORTED Error 28 -> A KEY LENGTH OF ZERO WAS PROVIDED +Error 29 -> FETCH WAS NOT COMPLETED Found key pid Found key uptime Found key time -- 2.30.2