Я установил Zookeeper
на мой Ubuntu
. Я запускаю его в кластерном режиме с тремя z1
, z2
и z3
экземплярами. Когда я подключаюсь к нему с bin/zkCli.sh -server 127.0.0.1:2181,127.0.0.1:2182,...
и делаю ls /
Я вижу список некоторых, скажем, узлов или данных (я не уверен в терминологии). Теперь я хочу загрузить некоторые данные программным путем, используя стандарт C++
client
. Чтобы реализовать это, у меня есть куча функций, в том числе init
, который, я думаю, запускает сеанс, create
функция, которая внутренне вызывает zoo_acreate
и пустую (для простоты на данный момент) функцию обратного вызова create_complete
.Невозможно загрузить данные в Zookeeper программно
последних двух упомянутых функций выглядит следующим образом:
void create(const char * path,
const char * value) {
zoo_acreate(zh,
path,
value,
0,
&ZOO_OPEN_ACL_UNSAFE,
0,
create_completion,
NULL);
}
void create_completion (int rc, const char *value, const void *data) {
// empty at this moment
}
Однако, когда я пытаюсь использовать эти функции для того, чтобы загрузить некоторые данные зоопарка, я не получаю никакого результата - на самом деле, без ошибок, но при в то же время нет данных. Способ я использую эти функции это одна:
int main(){
hostPort = (char *)("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183");
init(hostPort); // as a result of invoking this function
// I see in the console some logs, including this message:
// Initiating client connection, host=127.0.0.1:2181,....
create("/testworker", "");
return 0;
}
Я думал, этот код должен создать «папку» /testworker
внутри Zookeeper, однако, это не делает - ls /
команда не показывает никаких изменений. Одна интересная вещь, которую я должен отметить, заключается в том, что кажется, что моя программа никогда не вызывает обратный вызов create_completion
(я проверил его с помощью cout
). Таким образом, возможно, мне понадобятся некоторые специальные флаги и некоторые специальные компиляционные строки для моей программы. Как я скомпилировать его сейчас:
$ g++ -o test test.cpp -I /...path_to_include_folder/ -L /..path_to_lib_folder/ -lzookeeper_mt
EDIT
Я invastigated неполадку Лил немного, и обнаружил, что функции обратного вызова не вызывается вообще. Например, функция init
, которая запускает сеанс, не вызывает обратный вызов main_watcher
. Почему это?
EDIT
Я invastigated это немного больше. Оказалось, что zookeeper_init
(который вызывается внутри моей init
функции) возвращает 0
как значение errno
и к тому же он устанавливает zh
(который является Zookeeper обработчик типа static zhandle_t *
) до некоторого значения, так zh
не null
и так, по до documentation, init
функция должна быть в порядке (даже если она не вызывает процедуру обратного вызова). Поэтому действительно странно, что у меня нет сообщений об ошибках в консоли, и я не получаю флаги ошибок со стандартными методами zookeeper, но все же обратные вызовы и загрузка данных не работают. Что не так с этим и как я могу его отладить?
EDIT
Это полный исходный код моего крошечного примера:
#include <iostream>
#include "proto.h"
#include "zookeeper.h"
#include "zookeeper_log.h"
#include "recordio.h"
#include "zookeeper.jute.h"
#include "zookeeper_version.h"
#include "errno.h"
using namespace std;
static char *hostPort;
static zhandle_t * zh;
static int connected = 0;
static int expired = 0;
static int server_id;
static struct String_vector * workers = NULL;
static struct String_vector * tasks = NULL;
void create(const char *, const char *);
void create_completion(int, const char *, const void *);
void main_watcher(zhandle_t *zkh,
int type,
int state,
const char *path,
void* context)
{
// cout << "HELLO FROM WATCHER " << endl; // Not printed when I remove comment. Why???
if(type == ZOO_SESSION_EVENT){
if(state == ZOO_CONNECTED_STATE){
connected = 1;
}
else if(state == ZOO_AUTH_FAILED_STATE){
connected = 0;
}
else if(state == ZOO_EXPIRED_SESSION_STATE){
expired = 1;
connected = 0;
zookeeper_close(zkh);
}
}
}
int init(char* hostPort){
srand(time(NULL));
server_id = rand();
zoo_set_debug_level(ZOO_LOG_LEVEL_INFO);
zh = zookeeper_init(hostPort, main_watcher, 15000, 0, 0, 0);
return errno;
}
void create_completion(int rc, const char *value, const void * data){
// empty at this moment for simplicity
}
void create(const char * path, const char * value){
zoo_acreate(zh, path, value, 0, &ZOO_OPEN_ACL_UNSAFE, 0,
create_completion, NULL);
}
int main(){
hostPort = (char *)("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183");
init(hostPort);
create("/testworkers", ""); // Do not see this "folder" /testworkers in Zookeeper. Why???
return 0;
}
EDIT
Это действительно заставляет меня с ума.Я провел несколько дней, прочитав книгу по разъему C++
до Zookeeper
и не получил никакого результата, и я только что взял первый разъем Python
, потратив не более 1,5 минут и сделал это. Но это не то, что я хочу. Я хочу посмотреть, как я могу сделать эту тривиальную вещь в C++
- компилировать, подключать и создавать. Больше ничего.
EDIT
я составил свою программу с -DTHREADED
вариант, но безрезультатно. Тем не менее, zoo_acreate
ничего не создает. Он не создает сообщений об ошибках, он не создает предупреждений, он не возвращает флаги ошибок и не дает никакого результата. Действительно странная библиотека.
zoo_acreate() имеет возвращаемое значение. Возможно, это не удалось, и код возврата подскажет вам, почему. – nos
Спасибо! Я проверю этот код сейчас. – Jacobian
Я проверил его. 'zoo_acreate' возвращает' 0' в моем примере. – Jacobian