Permalink
Browse files

CCBC-104 Reconnect config listener

Change-Id: If28b6939c025d1d3ceb205930106ef3827515bec
Reviewed-on: http://review.couchbase.org/22686
Tested-by: Sergey Avseyev <sergey.avseyev@gmail.com>
Reviewed-by: Trond Norbye <trond.norbye@gmail.com>
  • Loading branch information...
1 parent 16b3687 commit 6e44bfd9dfab9b80fc7602795d87ceae82ca3ca2 @avsej avsej committed with trondn Nov 20, 2012
Showing with 51 additions and 0 deletions.
  1. +12 −0 include/libcouchbase/behavior.h
  2. +12 −0 src/behavior.c
  3. +2 −0 src/instance.c
  4. +11 −0 src/internal.h
  5. +14 −0 src/server.c
View
12 include/libcouchbase/behavior.h
@@ -38,6 +38,18 @@ extern "C" {
LIBCOUCHBASE_API
lcb_ipv6_t lcb_behavior_get_ipv6(lcb_t instance);
+ /**
+ * Set the maximum number of error events allowed on the data socket
+ * paired with config port, to consider node suspicious and to force
+ * reconnection. This feature is solving issues when node is gone
+ * without proper socket close.
+ */
+ LIBCOUCHBASE_API
+ void lcb_behavior_set_config_errors_threshold(lcb_t instance, lcb_size_t num_events);
+
+ LIBCOUCHBASE_API
+ lcb_size_t lcb_behavior_get_config_errors_threshold(lcb_t instance);
+
#ifdef __cplusplus
}
#endif
View
12 src/behavior.c
@@ -39,3 +39,15 @@ lcb_ipv6_t lcb_behavior_get_ipv6(lcb_t instance)
{
return instance->ipv6;
}
+
+LIBCOUCHBASE_API
+void lcb_behavior_set_config_errors_threshold(lcb_t instance, lcb_size_t num_events)
+{
+ instance->weird_things_threshold = num_events;
+}
+
+LIBCOUCHBASE_API
+lcb_size_t lcb_behavior_get_config_errors_threshold(lcb_t instance)
+{
+ return instance->weird_things_threshold;
+}
View
2 src/instance.c
@@ -249,6 +249,7 @@ lcb_error_t lcb_create(lcb_t *instance,
lcb_behavior_set_syncmode(obj, LCB_ASYNCHRONOUS);
lcb_behavior_set_ipv6(obj, LCB_IPV6_DISABLED);
lcb_set_timeout(obj, LCB_DEFAULT_TIMEOUT);
+ lcb_behavior_set_config_errors_threshold(obj, LCB_DEFAULT_CONFIG_ERRORS_THRESHOLD);
if (setup_boostrap_hosts(obj, host) == -1) {
lcb_destroy(obj);
@@ -427,6 +428,7 @@ lcb_error_t lcb_apply_vbucket_config(lcb_t instance, VBUCKET_CONFIG_HANDLE confi
};
instance->vbucket_config = config;
+ instance->weird_things = 0;
num = (lcb_size_t)vbucket_config_get_num_servers(config);
/* servers array should be freed in the caller */
instance->servers = calloc(num, sizeof(lcb_server_t));
View
11 src/internal.h
@@ -56,6 +56,7 @@
#endif
#define LCB_DEFAULT_TIMEOUT 2500000
+#define LCB_DEFAULT_CONFIG_ERRORS_THRESHOLD 100
#ifdef __cplusplus
extern "C" {
@@ -159,6 +160,14 @@ extern "C" {
struct lcb_io_opt_st *io;
+ /** The number of weird things happened with config node
+ * This counter reflects event on memcached port (default 11210),
+ * but used to make decisions about healthiness of the
+ * configuration port (default 8091).
+ */
+ lcb_size_t weird_things;
+ lcb_size_t weird_things_threshold;
+
/* The current synchronous mode */
lcb_syncmode_t syncmode;
@@ -246,6 +255,8 @@ extern "C" {
struct lcb_server_st {
/** The server index in the list */
int index;
+ /** Non-zero for node is using for configuration */
+ int is_config_node;
/** The name of the server */
char *hostname;
/** The servers port */
View
14 src/server.c
@@ -41,6 +41,7 @@ void lcb_purge_single_server(lcb_server_t *server,
lcb_size_t send_size = ringbuffer_get_nbytes(&server->output);
lcb_size_t stream_size = ringbuffer_get_nbytes(stream);
hrtime_t now = gethrtime();
+ int should_switch_to_backup_node = 0;
if (server->connected) {
cookies = &server->output_cookies;
@@ -261,6 +262,12 @@ void lcb_purge_single_server(lcb_server_t *server,
if (mirror) {
ringbuffer_consumed(mirror, packetsize);
}
+ if (server->is_config_node) {
+ root->weird_things++;
+ if (root->weird_things >= root->weird_things_threshold) {
+ should_switch_to_backup_node = 1;
+ }
+ }
} while (1); /* CONSTCOND */
if (server->connected) {
@@ -279,6 +286,11 @@ void lcb_purge_single_server(lcb_server_t *server,
}
ringbuffer_destruct(&rest);
+ if (should_switch_to_backup_node) {
+ lcb_switch_to_backup_node(root, LCB_NETWORK_ERROR,
+ "Config connection considered stale. "
+ "Reconnection forced");
+ }
lcb_maybe_breakout(server->instance);
}
@@ -597,6 +609,8 @@ void lcb_server_initialize(lcb_server_t *server, int servernum)
*p = '\0';
server->port = p + 1;
+ server->is_config_node = vbucket_config_is_config_node(server->instance->vbucket_config,
+ servernum);
n = vbucket_config_get_couch_api_base(server->instance->vbucket_config,
servernum);
server->couch_api_base = (n != NULL) ? strdup(n) : NULL;

0 comments on commit 6e44bfd

Please sign in to comment.