[sheepdog] [PATCH 9/8] zookeeper: only write leave event when node is not in the tree
Liu Yuan
namei.unix at gmail.com
Mon Dec 24 06:24:44 CET 2012
From: Liu Yuan <tailai.ly at taobao.com>
This can mitigate the duplicate of leave events problem a bit.
Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
sheep/cluster/zookeeper.c | 40 +++++++++++++++++++++++++++++++++-------
1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/sheep/cluster/zookeeper.c b/sheep/cluster/zookeeper.c
index 1b45864..3efdde1 100644
--- a/sheep/cluster/zookeeper.c
+++ b/sheep/cluster/zookeeper.c
@@ -16,6 +16,7 @@
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <zookeeper/zookeeper.h>
+#include <pthread.h>
#include "cluster.h"
#include "event.h"
@@ -67,7 +68,8 @@ struct zk_event {
static struct sd_node sd_nodes[SD_MAX_NODES];
static size_t nr_sd_nodes;
-struct rb_root zk_node_root = RB_ROOT;
+static struct rb_root zk_node_root = RB_ROOT;
+static pthread_rwlock_t zk_tree_lock = PTHREAD_RWLOCK_INITIALIZER;
static LIST_HEAD(zk_block_list);
static bool joined;
@@ -97,7 +99,7 @@ static struct zk_node *zk_tree_insert(struct zk_node *new)
return NULL; /* insert successfully */
}
-static struct zk_node *zk_tree_search(const struct node_id *nid)
+static struct zk_node *zk_tree_search_nolock(const struct node_id *nid)
{
struct rb_node *n = zk_node_root.rb_node;
struct zk_node *t;
@@ -118,6 +120,17 @@ static struct zk_node *zk_tree_search(const struct node_id *nid)
return NULL;
}
+
+static inline struct zk_node *zk_tree_search(const struct node_id *nid)
+{
+ struct zk_node *n;
+
+ pthread_rwlock_rdlock(&zk_tree_lock);
+ n = zk_tree_search_nolock(nid);
+ pthread_rwlock_unlock(&zk_tree_lock);
+ return n;
+}
+
/* zookeeper API wrapper */
static zhandle_t *zhandle;
static struct zk_node this_node;
@@ -314,33 +327,45 @@ static inline void zk_tree_add(struct zk_node *node)
{
struct zk_node *zk = malloc(sizeof(*zk));
*zk = *node;
+ pthread_rwlock_wrlock(&zk_tree_lock);
if (zk_tree_insert(zk)) {
free(zk);
- return;
+ goto out;
}
/*
* Even node list will be built later, we need this because in master
* transfer case, we need this information to destroy the tree.
*/
sd_nodes[nr_sd_nodes++] = zk->node;
+out:
+ pthread_rwlock_unlock(&zk_tree_lock);
}
-static inline void zk_tree_del(struct zk_node *node)
+static inline void zk_tree_del_nolock(struct zk_node *node)
{
rb_erase(&node->rb, &zk_node_root);
free(node);
}
+static inline void zk_tree_del(struct zk_node *node)
+{
+ pthread_rwlock_wrlock(&zk_tree_lock);
+ zk_tree_del_nolock(node);
+ pthread_rwlock_unlock(&zk_tree_lock);
+}
+
static inline void zk_tree_destroy(void)
{
struct zk_node *zk;
int i;
+ pthread_rwlock_wrlock(&zk_tree_lock);
for (i = 0; i < nr_sd_nodes; i++) {
- zk = zk_tree_search(&sd_nodes[i].nid);
+ zk = zk_tree_search_nolock(&sd_nodes[i].nid);
if (zk)
- zk_tree_del(zk);
+ zk_tree_del_nolock(zk);
}
+ pthread_rwlock_unlock(&zk_tree_lock);
}
static inline void build_node_list(void)
@@ -424,7 +449,8 @@ static void zk_watcher(zhandle_t *zh, int type, int state, const char *path,
p++;
str_to_node(p, &znode.node);
/* FIXME: remove redundant leave events */
- add_event(EVENT_LEAVE, &znode, NULL, 0);
+ if (zk_tree_search(&znode.node.nid))
+ add_event(EVENT_LEAVE, &znode, NULL, 0);
}
}
--
1.7.9.5
More information about the sheepdog
mailing list