Skip to content

Instantly share code, notes, and snippets.

@ochinchina
Created July 8, 2014 07:57
Show Gist options
  • Save ochinchina/38e70fc3d8fa457d5cd8 to your computer and use it in GitHub Desktop.
Save ochinchina/38e70fc3d8fa457d5cd8 to your computer and use it in GitHub Desktop.
Demostrate how to select a leader from zookeeper in C API, before doing make, set the ZK_DIR environment variable
CPP = g++
INCS = -I$(ZK_DIR)/src/c/include -I/home/ochinchina/zookeeper-3.4.6/src/c/generated
LIBS = -L$(ZK_DIR)/src/c/.libs -lzookeeper_mt -lpthread
CXX_FLAGS = -std=c++11
all: leader
leader: ZkLeaderElection.o
$(CPP) -o leader ZkLeaderElection.o $(LIBS)
.cpp.o:
$(CPP) -c $(CXX_FLAGS) $(INCS) $<
#include <zookeeper.h>
#include <string>
#include <iostream>
#include <unistd.h>
class ZkLeaderElection {
public:
ZkLeaderElection( const std::string& host, const std::string& root, const std::string& nodeName )
:host_( host ),
root_( root ),
nodeName_( nodeName )
{
handle_ = zookeeper_init( host_.c_str(), watch, 5*1000, 0, this, 0 );
}
private:
static void watch( zhandle_t *zh, int type, int state, const char *path,void *watcherCtx ) {
ZkLeaderElection* p = (ZkLeaderElection*)watcherCtx;
if( state == ZOO_CONNECTED_STATE ) {
if( type == ZOO_CHILD_EVENT ) {
p->checkChildrenChange();
} else {
p->createNodes();
}
}
}
void createNodes() {
Stat stat;
if( zoo_exists( handle_, root_.c_str(), false, &stat ) != ZOK ){
std::cout << root_ << " does not exist" << std::endl;
zoo_create( handle_, root_.c_str(), "data", 4, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0 );
}
std::string path = root_ + "/n_";
if( !nodeName_.empty() ) {
if( zoo_create( handle_, path.c_str(), nodeName_.data(), nodeName_.length(), &ZOO_OPEN_ACL_UNSAFE, ZOO_SEQUENCE|ZOO_EPHEMERAL, 0, 0 ) == ZOK) {
std::cout << "success to create " << path << std::endl;
}
}
checkChildrenChange();
}
void checkChildrenChange() {
String_vector children;
if( zoo_get_children( handle_, root_.c_str(), true, &children ) == ZOK ) {
if( children.count > 0 ) {
int min_seq = 0;
int j = 0;
//find the leader
for( int i = 0; i < children.count; i++ ) {
std::cout << children.data[i] << std::endl;
int t = ::atoi( &children.data[i][2] );
if( i == 0 || min_seq > t ) {
min_seq = t;
j = i;
}
}
//get the data
std::string path = root_ + "/" + children.data[j];
std::cout << "leader:" << getNodeData( path ) << std::endl;
}
deallocate_String_vector( &children );
}
}
std::string getNodeData( const std::string& path ) {
char* buf = new char[256];
int len = 256;
for( ; ; ) {
Stat stat;
if( zoo_get( handle_, path.c_str(), false, buf, &len, &stat ) == ZOK ) {
if( stat.dataLength > len ) {
delete []buf;
buf = new char[stat.dataLength ];
len = stat.dataLength;
} else {
std::string result( buf, len );
delete []buf;
return result;
}
} else {
delete []buf;
return "";
}
}
}
private:
std::string host_;
std::string root_;
std::string nodeName_;
zhandle_t* handle_;
};
int main( int argc, char** argv ) {
ZkLeaderElection leaderElection( "127.0.0.1:2181", "/election", argv[1] );
for( ; ; ) {
::sleep( 10 );
}
}
@Sherlockedb
Copy link

why I get the error 'zoo_exists was not declared in this scope'? The other api such as zoo_create and zoo_get meet the same error.

@ochinchina
Copy link
Author

ochinchina commented Aug 19, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment