From bdb615a66ac1df020917d000adf2f73e49fd3a25 Mon Sep 17 00:00:00 2001 From: Nicolas Van Eenaeme Date: Wed, 20 Nov 2013 16:37:48 +0100 Subject: Added server_timeout_counter and behavior MEMCACHED_BEHAVIOR_SERVER_TIMEOUT_LIMIT. This feature works as follows: When a timeout occurs, retry MEMCACHED_BEHAVIOR_SERVER_TIMEOUT_LIMIT times before putting the server in MEMCACHED_SERVER_STATE_IN_TIMEOUT state. It makes sense to not fail from the 1st time but retry on the next calls before marking the server as timeout. --- libmemcached/behavior.cc | 7 +++++++ libmemcached/connect.cc | 1 + libmemcached/instance.cc | 2 ++ libmemcached/instance.hpp | 3 +++ libmemcached/memcached.cc | 2 ++ libmemcached/quit.cc | 1 + libmemcached/server.cc | 2 ++ libmemcached/server.hpp | 20 +++++++++++++------- 8 files changed, 31 insertions(+), 7 deletions(-) (limited to 'libmemcached') diff --git a/libmemcached/behavior.cc b/libmemcached/behavior.cc index 081f8082..40fb5fb6 100644 --- a/libmemcached/behavior.cc +++ b/libmemcached/behavior.cc @@ -116,6 +116,10 @@ memcached_return_t memcached_behavior_set(memcached_st *shell, ptr->server_failure_limit= uint32_t(data); break; + case MEMCACHED_BEHAVIOR_SERVER_TIMEOUT_LIMIT: + ptr->server_timeout_limit= uint32_t(data); + break; + case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL: send_quit(ptr); // We need t shutdown all of the connections to make sure we do the correct protocol if (data) @@ -374,6 +378,9 @@ uint64_t memcached_behavior_get(memcached_st *shell, case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT: return ptr->server_failure_limit; + case MEMCACHED_BEHAVIOR_SERVER_TIMEOUT_LIMIT: + return ptr->server_timeout_limit; + case MEMCACHED_BEHAVIOR_SORT_HOSTS: return ptr->flags.use_sort_hosts; diff --git a/libmemcached/connect.cc b/libmemcached/connect.cc index 3c82f641..52cd293a 100644 --- a/libmemcached/connect.cc +++ b/libmemcached/connect.cc @@ -713,6 +713,7 @@ static memcached_return_t backoff_handling(memcached_instance_st* server, bool& if (_gettime_success and server->next_retry < curr_time.tv_sec) { server->state= MEMCACHED_SERVER_STATE_NEW; + server->server_timeout_counter= 0; } else { diff --git a/libmemcached/instance.cc b/libmemcached/instance.cc index 82621f7a..53f74f79 100644 --- a/libmemcached/instance.cc +++ b/libmemcached/instance.cc @@ -54,6 +54,8 @@ static inline void _server_init(memcached_instance_st* self, Memcached *root, self->request_id= 0; self->server_failure_counter= 0; self->server_failure_counter_query_id= 0; + self->server_timeout_counter= 0; + self->server_timeout_counter_query_id= 0; self->weight= weight ? weight : 1; // 1 is the default weight value self->io_wait_count.read= 0; self->io_wait_count.write= 0; diff --git a/libmemcached/instance.hpp b/libmemcached/instance.hpp index c76dc7ee..73d74a66 100644 --- a/libmemcached/instance.hpp +++ b/libmemcached/instance.hpp @@ -73,6 +73,7 @@ struct memcached_instance_st { void mark_server_as_clean() { server_failure_counter= 0; + server_timeout_counter= 0; next_retry= 0; } @@ -147,6 +148,8 @@ struct memcached_instance_st { uint32_t request_id; uint32_t server_failure_counter; uint64_t server_failure_counter_query_id; + uint32_t server_timeout_counter; + uint32_t server_timeout_counter_query_id; uint32_t weight; uint32_t version; enum memcached_server_state_t state; diff --git a/libmemcached/memcached.cc b/libmemcached/memcached.cc index a3c6a679..337f918d 100644 --- a/libmemcached/memcached.cc +++ b/libmemcached/memcached.cc @@ -87,6 +87,7 @@ static inline bool _memcached_init(Memcached *self) self->snd_timeout= 0; self->rcv_timeout= 0; self->server_failure_limit= MEMCACHED_SERVER_FAILURE_LIMIT; + self->server_timeout_limit= MEMCACHED_SERVER_TIMEOUT_LIMIT; self->query_id= 1; // 0 is considered invalid /* TODO, Document why we picked these defaults */ @@ -362,6 +363,7 @@ memcached_st *memcached_clone(memcached_st *clone, const memcached_st *source) new_clone->get_key_failure= source->get_key_failure; new_clone->delete_trigger= source->delete_trigger; new_clone->server_failure_limit= source->server_failure_limit; + new_clone->server_timeout_limit= source->server_timeout_limit; new_clone->io_msg_watermark= source->io_msg_watermark; new_clone->io_bytes_watermark= source->io_bytes_watermark; new_clone->io_key_prefetch= source->io_key_prefetch; diff --git a/libmemcached/quit.cc b/libmemcached/quit.cc index 04b77cea..5d17b313 100644 --- a/libmemcached/quit.cc +++ b/libmemcached/quit.cc @@ -93,6 +93,7 @@ namespace { * sent to the server. */ instance->server_failure_counter= 0; + instance->server_timeout_counter= 0; } } diff --git a/libmemcached/server.cc b/libmemcached/server.cc index c4747ddc..e2837c7d 100644 --- a/libmemcached/server.cc +++ b/libmemcached/server.cc @@ -54,6 +54,8 @@ static inline void _server_init(memcached_server_st *self, Memcached *root, self->request_id= 0; self->server_failure_counter= 0; self->server_failure_counter_query_id= 0; + self->server_timeout_counter= 0; + self->server_timeout_counter_query_id= 0; self->weight= weight ? weight : 1; // 1 is the default weight value self->io_wait_count.read= 0; self->io_wait_count.write= 0; diff --git a/libmemcached/server.hpp b/libmemcached/server.hpp index 708e6460..6ea0b7f2 100644 --- a/libmemcached/server.hpp +++ b/libmemcached/server.hpp @@ -76,7 +76,13 @@ static inline void memcached_mark_server_for_timeout(memcached_instance_st* serv { if (server->state != MEMCACHED_SERVER_STATE_IN_TIMEOUT) { - if (server->root->retry_timeout != 0) + if (server->server_timeout_counter_query_id != server->root->query_id) + { + server->server_timeout_counter++; + server->server_timeout_counter_query_id= server->root->query_id; + } + + if (server->server_timeout_counter >= server->root->server_timeout_limit) { struct timeval next_time; if (gettimeofday(&next_time, NULL) == 0) @@ -89,12 +95,12 @@ static inline void memcached_mark_server_for_timeout(memcached_instance_st* serv } server->state= MEMCACHED_SERVER_STATE_IN_TIMEOUT; + if (server->server_failure_counter_query_id != server->root->query_id) + { + server->server_failure_counter++; + server->server_failure_counter_query_id= server->root->query_id; + } + set_last_disconnected_host(server); } - if (server->server_failure_counter_query_id != server->root->query_id) - { - server->server_failure_counter++; - server->server_failure_counter_query_id= server->root->query_id; - } - set_last_disconnected_host(server); } } -- cgit v1.2.1