Skip to content

Instantly share code, notes, and snippets.

@ochinchina
Created July 8, 2014 07:57
Show Gist options
  • Select an option

  • Save ochinchina/38e70fc3d8fa457d5cd8 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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

ochinchina commented Aug 19, 2019 via email

Copy link
Copy Markdown
Author

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