Giter Site home page Giter Site logo

node-zookeeper-client's Introduction

node-zookeeper-client

A pure Javascript ZooKeeper client module for Node.js.

NPM

Build Status

This module is designed to resemble the ZooKeeper Java client API but with tweaks to follow the convention of Node.js modules. Developers that are familiar with the ZooKeeper Java client would be able to pick it up quickly.

This module has been tested to work with ZooKeeper version 3.4.*.


Installation

You can install it using npm:

$ npm install node-zookeeper-client

Example

1. Create a node using given path:

var zookeeper = require('node-zookeeper-client');

var client = zookeeper.createClient('localhost:2181');
var path = process.argv[2];

client.once('connected', function () {
    console.log('Connected to the server.');

    client.create(path, function (error) {
        if (error) {
            console.log('Failed to create node: %s due to: %s.', path, error);
        } else {
            console.log('Node: %s is successfully created.', path);
        }

        client.close();
    });
});

client.connect();

2. List and watch the children of given node:

var zookeeper = require('node-zookeeper-client');

var client = zookeeper.createClient('localhost:2181');
var path = process.argv[2];

function listChildren(client, path) {
    client.getChildren(
        path,
        function (event) {
            console.log('Got watcher event: %s', event);
            listChildren(client, path);
        },
        function (error, children, stat) {
            if (error) {
                console.log(
                    'Failed to list children of %s due to: %s.',
                    path,
                    error
                );
                return;
            }

            console.log('Children of %s are: %j.', path, children);
        }
    );
}

client.once('connected', function () {
    console.log('Connected to ZooKeeper.');
    listChildren(client, path);
});

client.connect();

More examples can be found here.

Documentation

Client createClient(connectionString, [options])

Factory method to create a new zookeeper client instance.

Arguments

  • connectionString String - Comma separated host:port pairs, each represents a ZooKeeper server. You can optionally append a chroot path, then the client would be rooted at the given path. e.g.

    'localhost:3000,locahost:3001,localhost:3002'
    'localhost:2181,localhost:2182/test'
  • options Object - An object to set the client options. Currently available options are:

    • sessionTimeout Session timeout in milliseconds, defaults to 30 seconds.
    • spinDelay The delay (in milliseconds) between each connection attempts.
    • retries The number of retry attempts for connection loss exception.

    Defaults options:

    {
        sessionTimeout: 30000,
        spinDelay : 1000,
        retries : 0
    }

Example

var client = zookeeper.createClient(
    'localhost:2181/test',
    { sessionTimeout: 10000 }
);

Client

This is the main class of ZooKeeper client module. An application must use createClient method to instantiate the client.

Once a connection from the client to the server is established, a session id is assigned to the client. The client will starts sending heart beats to the server periodically to keep the session valid.

If the client fails to send heart beats to the server for a prolonged period of time (exceeding the sessionTimeout value), the server will expire the session. The client object will no longer be usable.

If the ZooKeeper server the client currently connects to fails or otherwise does not respond, the client will automatically try to connect to another server before its session times out. If successful, the application can continue to use the client.

This class inherits from events.EventEmitter class, see Event for details.

void connect()

Initiate the connection to the provided server list (ensemble). The client will pick an arbitrary server from the list and attempt to connect to it. If the establishment of the connection fails, another server will be tried (picked randomly) until a connection is established or close method is invoked.


void close()

Close this client. Once the client is closed, its session becomes invalid. All the ephemeral nodes in the ZooKeeper server associated with the session will be removed. The watchers left on those nodes (and on their parents) will be triggered.


void create(path, [data], [acls], [mode], callback)

Create a node with given path, data, acls and mode.

Arguments

  • path String - Path of the node.
  • data Buffer - The data buffer, optional, defaults to null.
  • acls Array - An array of ACL objects, optional, defaults to ACL.OPEN_ACL_UNSAFE
  • mode CreateMode - The creation mode, optional, defaults to CreateMode.PERSISTENT
  • callback(error, path) Function - The callback function.

Example

zookeeper.create(
    '/test/demo',
    Buffer.from('data'),
    CreateMode.EPHEMERAL,
    function (error, path) {
        if (error) {
            console.log(error.stack);
            return;
        }

        console.log('Node: %s is created.', path);
    }
);

void remove(path, [version], callback)

Delete a node with the given path and version. If version is provided and not equal to -1, the request will fail when the provided version does not match the server version.

Arguments

  • path String - Path of the node.
  • version Number - The version of the node, optional, defaults to -1.
  • callback(error) Function - The callback function.

Example

zookeeper.remove('/test/demo', -1, function (error) {
    if (error) {
        console.log(error.stack);
        return;
    }

    console.log('Node is deleted.');
});

void removeRecursive(path, [version], callback)

Deletes a node and all its children with the given path and version.

Arguments

  • path String - Path of the node.
  • version Number - The version of the node, optional, defaults to -1.
  • callback(error) Function - The callback function.

Example

zookeeper.removeRecursive('/test/demo', -1, function (error) {
    if (error) {
        console.log(error.stack);
        return;
    }

    console.log('Nodes removed.');
});

void exists(path, [watcher], callback)

Check the existence of a node. The callback will be invoked with the stat of the given path, or null if no such node exists.

If the watcher function is provided and the operation is successful (no error), a watcher will be placed on the node with the given path. The watcher will be triggered by a successful operation that creates the node, deletes the node or sets the data on the node.

Arguments

  • path String - Path of the node.
  • watcher(event) Function - The watcher function, optional. The event is an instance of Event
  • callback(error, stat) Function - The callback function. The stat is an instance of Stat.

Example

zookeeper.exists('/test/demo', function (error, stat) {
    if (error) {
        console.log(error.stack);
        return;
    }

    if (stat) {
        console.log('Node exists.');
    } else {
        console.log('Node does not exist.');
    }
});

void getChildren(path, [watcher], callback)

For the given node path, retrieve the children list and the stat. The children will be an unordered list of strings.

If the watcher callback is provided and the operation is successfully, a watcher will be placed the given node. The watcher will be triggered when an operation successfully deletes the given node or creates/deletes the child under it.

Arguments

  • path String - Path of the node.
  • watcher(event) Function - The watcher function, optional. The event is an instance of Event
  • callback(error, children, stat) Function - The callback function. The children is an array of strings and the stat is an instance of Stat.

Example

zookeeper.getChildren('/test/demo', function (error, children, stats) {
    if (error) {
        console.log(error.stack);
        return;
    }

    console.log('Children are: %j.', children);
});

void listSubTreeBFS(path, callback)

Retrieve a list of all children including itself for the given node path.

Arguments

  • path String - Path of the node.
  • callback(error, children) Function - The callback function. The children is an array of strings.

Example

zookeeper.listSubTreeBFS('/test/demo', function (error, children) {
    if (error) {
        console.log(error.stack);
        return;
    }

    console.log('Children are: %j.', children);
});

void getData(path, [watcher], callback)

Retrieve the data and the stat of the node of the given path. If the watcher function is provided and the operation is successful (no error), a watcher will be placed on the node with the given path. The watch will be triggered by a successful operation which sets data on the node, or deletes the node.

Arguments

  • path String - Path of the node.
  • watcher(event) Function - The watcher function, optional. The event is an instance of Event
  • callback(error, data, stat) Function - The callback function. The data is an instance of Buffer and stat is an instance of Stat.

Example

zookeeper.getData(
    '/test/demo',
    function (event) {
        console.log('Got event: %s.', event);
    },
    function (error, data, stat) {
        if (error) {
            console.log(error.stack);
            return;
        }

        console.log('Got data: %s', data.toString('utf8'));
    }
);

void setData(path, data, [version], callback)

Set the data for the node of the given path if such a node exists and the optional given version matches the version of the node (if the given version is -1, it matches any node's versions). The stat of the node will be returned through the callback function.

Arguments

  • path String - Path of the node.
  • data Buffer - The data buffer.
  • version Number - The version of the node, optional, defaults to -1.
  • callback(error, stat) Function - The callback function. The stat is an instance of Stat.

Example

zookeeper.setData('/test/demo', null, 2, function (error, stat) {
    if (error) {
        console.log(error.stack);
        return;
    }

    console.log('Data is set.');
});

void getACL(path, callback)

Retrieve the list of ACL and stat of the node of the given path.

Arguments

  • path String - Path of the node.
  • callback(error, acls, stat) Function - The callback function. acls is an array of ACL instances. The stat is an instance of Stat.

Example

zookeeper.getACL('/test/demo', function (error, acls, stat) {
    if (error) {
        console.log(error.stack);
        return;
    }

    console.log('ACL(s) are: %j', acls);
});

void setACL(path, acls, [version], callback)

Set the ACL for the node of the given path if such a node exists and the given version (optional) matches the version of the node on the server. (if the given version is -1, it matches any versions).

Arguments

  • path String - Path of the node.
  • acls Array - An array of ACL instances.
  • version Number - The version of the node, optional, defaults to -1.
  • callback(error, stat) Function - The callback function. The stat is an instance of Stat.

Example

zookeeper.setACL(
    '/test/demo',
    [
        new zookeeper.ACL(
            zookeeeper.Permission.ADMIN,
            new zookeeper.Id('ip', '127.0.0.1')
        )
    ],
    function (error, acls, stat) {
        if (error) {
            console.log(error.stack);
            return;
        }

        console.log('New ACL is set.');
    }
);

Transaction transaction()

Create and return a new Transaction instance which provides a builder object that can be used to construct and commit a set of operations atomically.

See Transaction for details.

Example

var transaction = zookeeper.transaction();

void mkdirp(path, [data], [acls], [mode], callback)

Create given path in a way similar to mkdir -p.

Arguments

  • path String - Path of the node.
  • data Buffer - The data buffer, optional, defaults to null.
  • acls Array - An array of ACL objects, optional, defaults to ACL.OPEN_ACL_UNSAFE
  • mode CreateMode - The creation mode, optional, defaults to CreateMode.PERSISTENT
  • callback(error, path) Function - The callback function.

Example

zookeeper.mkdirp('/test/demo/1/2/3', function (error, path) {
    if (error) {
        console.log(error.stack);
        return;
    }

    console.log('Node: %s is created.', path);
});

void addAuthInfo(scheme, auth)

Add the specified scheme:auth information to this client.

Arguments

  • scheme String - The authentication scheme.
  • auth Buffer - The authentication data buffer.

Example

zookeeper.addAuthInfo('ip', Buffer.from('127.0.0.1'));

State getState()

Return the current client state.

Example

var client = zookeeper.createClient({...});
var state = client.getState();
console.log('Current state is: %s', state);

Buffer getSessionId()

Returns the session id of this client instance. The value returned is not valid until the client connects to a server and may change after a re-connect.

The id returned is a long integer stored into a 8 bytes Buffer since Javascript does not support long integer natively.

Example

var client = zookeeper.createClient({...});
var id = client.getSessionId();
console.log('Session id is: %s', id.toString('hex'));

Buffer getSessionPassword()

Returns the session password of this client instance. The value returned is not valid until the client connects to a server and may change after a re-connect.

The value returned is an instance of Buffer.

Example

var client = zookeeper.createClient({...});
var pwd = client.getSessionPassword();

Number getSessionTimeout()

Returns the negotiated session timeout (in milliseconds) for this client instance. The value returned is not valid until the client connects to a server and may change after a re-connect.

Example

var client = zookeeper.createClient({...});
var sessionTimeout = client.getSessionTimeout();

State

After the connect() method is invoked, the ZooKeeper client starts its life cycle and transitions its state as described in the following diagram.

state transition

There are two ways to watch the client state changes:

1. Node.js convention: Register event listener on the specific event which interests you. The following is the list of events that can be watched:

  • connected - Client is connected and ready.
  • connectedReadOnly - Client is connected to a readonly server.
  • disconnected - The connection between client and server is dropped.
  • expired - The client session is expired.
  • authenticationFailed - Failed to authenticate with the server.

Note: some events (e.g. connected or disconnected) maybe be emitted more than once during the client life cycle.

Example

client.on('connected', function () {
    console.log('Client state is changed to connected.');
});

2. Java client convention: Register one event listener on the state event to watch all state transitions. The listener callback will be called with an instance of the State class. The following is the list of exported state instances:

  • State.CONNECTED - Client is connected and ready.
  • State.CONNECTED_READ_ONLY - Client is connected to a readonly server.
  • State.DISCONNECTED - The connection between client and server is dropped.
  • State.EXPIRED - The client session is expired.
  • State.AUTH_FAILED - Failed to authenticate with the server.
client.on('state', function (state) {
    if (state === zookeeper.State.SYNC_CONNECTED) {
        console.log('Client state is changed to connected.');
    }
});

Event

Optionally, you can register watcher functions when calling exists, getChildren and getData methods. The watcher function will be called with an instance of Event.

Properties

There are four type of events are exposed as Event class properties.

  • NODE_CREATED - Watched node is created.
  • NODE_DELETED - watched node is deleted.
  • NODE_DATA_CHANGED - Data of watched node is changed.
  • NODE_CHILDREN_CHANGED - Children of watched node is changed.

Number getType()

Return the type of the event.


String getName()

Return the name of the event.


Number getPath()

Return the path of the event.


String toString()

Return a string representation of the event.


Transaction

Transaction provides a builder interface to construct and commit a set of operations atomically.

Example

var client = zookeeper.createClient(process.argv[2] || 'localhost:2181');

client.once('connected', function () {
    client.transaction().
        create('/txn').
        create('/txn/1', Buffer.from('transaction')).
        setData('/txn/1', Buffer.from('test'), -1).
        check('/txn/1').
        remove('/txn/1', -1).
        remove('/txn').
        commit(function (error, results) {
            if (error) {
                console.log(
                    'Failed to execute the transaction: %s, results: %j',
                    error,
                    results
                );

                return;
            }

            console.log('Transaction completed.');
            client.close();
        });
});

client.connect();

Transaction create(path, [data], [acls], [mode])

Add a create operation with given path, data, acls and mode.

Arguments

  • path String - Path of the node.
  • data Buffer - The data buffer, optional, defaults to null.
  • acls Array - An array of ACL objects, optional, defaults to ACL.OPEN_ACL_UNSAFE
  • mode CreateMode - The creation mode, optional, defaults to CreateMode.PERSISTENT

Transaction setData(path, data, [version])

Add a set-data operation with the given path, data and optional version.

Arguments

  • path String - Path of the node.
  • data Buffer - The data buffer, or null.
  • version Number - The version of the node, optional, defaults to -1.

Transaction check(path, [version])

Add a check (existence) operation with given path and optional version.

Arguments

  • path String - Path of the node.
  • version Number - The version of the node, optional, defaults to -1.

Transaction remove(path, data, version)

Add a delete operation with the given path and optional version.

Arguments

  • path String - Path of the node.
  • version Number - The version of the node, optional, defaults to -1.

void commit(callback)

Execute the transaction atomically.

Arguments

  • callback(error, results) Function - The callback function.

Exception

If the requested operation fails due to reason related to ZooKeeper, the error which is passed into callback function will be an instance of Exception class.

The exception can be identified through its error code, the following is the list of error codes that are exported through Exception class.

  • Exception.OK
  • Exception.SYSTEM_ERROR
  • Exception.RUNTIME_INCONSISTENCY
  • Exception.DATA_INCONSISTENCY
  • Exception.CONNECTION_LOSS
  • Exception.MARSHALLING_ERROR
  • Exception.UNIMPLEMENTED
  • Exception.OPERATION_TIMEOUT
  • Exception.BAD_ARGUMENTS
  • Exception.API_ERROR
  • Exception.NO_NODE
  • Exception.NO_AUTH
  • Exception.BAD_VERSION
  • Exception.NO_CHILDREN_FOR_EPHEMERALS
  • Exception.NODE_EXISTS
  • Exception.NOT_EMPTY
  • Exception.SESSION_EXPIRED
  • Exception.INVALID_CALLBACK
  • Exception.INVALID_ACL
  • Exception.AUTH_FAILED

Example

zookeeper.create('/test/demo', function (error, path) {
    if (error) {
        if (error.getCode() == zookeeper.Exception.NODE_EXISTS) {
            console.log('Node exists.');
        } else {
            console.log(error.stack);
        }
        return;
    }

    console.log('Node: %s is created.', path);
});

Number getCode()

Return the error code of the exception.


String getPath()

Return the associated node path of the exception. The path can be undefined if the exception is not related to node.

--

String getName()

Return the exception name as defined in aforementioned list.


String toString()

Return the exception in a readable string.


Dependency

This module depends on the following third-party libraries:

License

This module is licensed under MIT License

node-zookeeper-client's People

Contributors

adamschmidt avatar alexguan avatar dependabot[bot] avatar imalberto avatar jahqueel avatar jinchan-ck avatar lambertkuang avatar lightswitch05 avatar philipyoo avatar rramk avatar sudowork avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-zookeeper-client's Issues

Transaction.prototype.setData for verion set for 0 (zero) doesn't check version

version = version || -1;

If in transaction call Transaction.prototype.setData = function (path, data, version)
and version has value 0, but an output is internally evaluated as -1 but should be 0 otherwise this use case doesn't work:

I have znode in zookeeper with version e.i. 33 and I will call aforementioned function
Transaction.prototype.setData = function (path, data, 0) and everything will be updated even though this should throw an Exception.BAD_VERSION because version 0 and 33 is different.

Fail to close after calling zk.close() when catching error after stop zookeeper

I used kaka-node to connect to kafka. kafka-node use node-zookeeper-client to get connect to zookeeper to get brokers.
For abnormal testing, there will be two zookeeper connection after stop zookeeper and start zookeeper. If repeating these processes again and again, there will be so many connections even more than 100 which leads to zookeeper stuck.

zk.once('disconnected', function () { if (!zk.closed) { zk.close(); self.connect(); self.emit('zkReconnect'); } });

The problem I found is after zk.close(), the socket still does not closed and self.connect() will create another one.
So I tried to figure out the root problem in node-zookeeper-client.

`ConnectionManager.prototype.onSocketClosed = function (hasError) {
var retry = false,
errorCode,
pendingPacket;

switch (this.state) {
case STATES.CLOSING:
    errorCode = Exception.CONNECTION_LOSS;
    retry = false;
    break;
case STATES.SESSION_EXPIRED:
    errorCode = Exception.SESSION_EXPIRED;
    retry = false;
    break;
case STATES.AUTHENTICATION_FAILED:
    errorCode = Exception.AUTH_FAILED;
    retry = false;
    break;
default:
    errorCode = Exception.CONNECTION_LOSS;
    retry = true;
}

this.cleanupPendingQueue(errorCode);
this.setState(STATES.DISCONNECTED);

if (retry) {
    this.connect();
} else {
    this.setState(STATES.CLOSED);
}

};`

the socket will firstly catches error and closed event will be trigger. The 'retry' will be true. It will set state as 'disconnected' which invokes disconnected event for kaka-node to do zk.close(). Then state become 'closing' and then execute this.connect(), which will set state to 'connecting' and retry and retry.
The solution just add checking in the connect. to make sure if state == closing, just do not connect.

if (self.state === STATES.CLOSING) return;

`ConnectionManager.prototype.connect = function () {
var self = this;

if (self.state === STATES.CLOSING) return;

self.setState(STATES.CONNECTING);

self.findNextServer(function (server) {
    self.socket = net.connect(server);

    self.connectTimeoutHandler = setTimeout(
        self.onSocketConnectTimeout.bind(self),
        self.connectTimeout
    );

    // Disable the Nagle algorithm.
    self.socket.setNoDelay();

    self.socket.on('connect', self.onSocketConnected.bind(self));
    self.socket.on('data', self.onSocketData.bind(self));
    self.socket.on('drain', self.onSocketDrain.bind(self));
    self.socket.on('close', self.onSocketClosed.bind(self));
    self.socket.on('error', self.onSocketError.bind(self));
});

};`

I will send a pull request for it.
Thanks

client crashes my process on internal assertions

Hello,

I maintain zkplus, which several large(ish) consumers of Zookeeper use in node to interact with the ZK API. I recently made a side project to port to this library as opposed to the native one, since the native one is riddled with bugs, and exacerbated by poor interactions with libuv. However, upon testing with lots of states where Zookeeper is offline, I am able to reproduce crashes that resemble this (note that the specific error code is non-deterministic, leading me to believe you are either incorrectly parsing Jute or have parsing logic where your offset gets mangled):

/Users/mcavage/work/registrar/node_modules/zkplus/node_modules/node-zookeeper-client/lib/Exception.js:51
        throw new Error('Unknown code: ' + code);
              ^
Error: Unknown code: 935133184
    at validateCode (/Users/mcavage/work/registrar/node_modules/zkplus/node_modules/node-zookeeper-client/lib/Exception.js:51:15)
    at Function.create (/Users/mcavage/work/registrar/node_modules/zkplus/node_modules/node-zookeeper-client/lib/Exception.js:140:5)
    at ConnectionManager.onSocketData (/Users/mcavage/work/registrar/node_modules/zkplus/node_modules/node-zookeeper-client/lib/ConnectionManager.js:571:35)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:746:14)
    at Socket.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
    at readableAddChunk (_stream_readable.js:165:9)
    at Socket.Readable.push (_stream_readable.js:127:10)

The stack trace is pretty much a simple application I was using to drive testing of ephemeral nodes. Note that this is not at all anything my process/application can act on, as your library is throwing an assertion on itself: https://github.com/alexguan/node-zookeeper-client/blob/master/lib/Exception.js#L51

I don't have a very good way of reproducing this behavior, other than to note that it only happens when I create a client and connect it with a down zookeeper, wait some number of seconds-minutes and start the Zookeeper.

In the absence of figuring out repro and/or root cause (which I will open as a separate issue), can you please change the various uses of throw in the library to emit('error') from the client? This would at least enable me to detect your client is in a bad state and move forward, short of relying on a process restart.

SASL/Kerberos support

Will this library support connections to Zookeeper using SASL and Kerberos/NTLM? I can't find any info on this.

If that's not currently possible, is it likely to be added soon? Or would love to hear your thoughts on how feasible it would be for us to add that kind of functionality in a PR, and what the best strategy to do so might be.

Thank you for the library, and your time!

how to bind diffrent client in client.on()

I want to use diffrent client in one file, and I first write as follow:

for (client in clients) {
   client.on(something, fucntion(){
         client.....
   });
}

i find evrytime the client in client.on is the same client, and

for (client in clients) {
   function test (){
      client.on(something, fucntion(){
            client.....
      });
   }
   test();
}

So i can get diffrent client in clinet.on, but i don't know why it works, I have struggle for hours, so can u explain or just give me the way to bind diffrent client? thanks very much : )

When list children node, I add a watcher, it got error

(node:9452) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 notification listeners added. Use emitter.setMaxListeners() to increase limit;

function listChildren(path, callback) {
    client.getChildren(path, (event) => {
        logger.debug('Got watcher event: ' + event);
        if (event === Event.NODE_CHILDREN_CHANGED) {
            listChildren(path, callback);
        }
    }, (error, children, stat) => {
        let version = stat ? stat.version : 'UNKOWN';
        if (error) {
            logger.error('Failed to list children of node: ' + path + ' due to: ' + error + ' in version: ' + version);
            if (error.code === Exception.NO_NODE) callback(null);
            if (error.code === Exception.CONNECTION_LOSS) {
                client.connect();
                listChildren(path, callback);
            }
            callback([]);
        } else {
            logger.debug('Children of node: ' + path + ' in version ' + version + ' are: ' + children + ' .');
            callback(children);
        }
    });
}

make 'closed' event available to Client

Some times I want to make some cleanup after the client is closed but due to current code, Client.close() method is only push request to queue but there is no way for Client to know when the ConnectionManager just have done the work.

So I think 'closed' event is also interested by Client and should not ignored in code.

I have my own fork t to just do simple work to just emit 'closed' when the close job is done.

Please see in villadora/node-zookeeper-client@ae37fc7

ConnectionManager infinite connect retries

In case server is offline, ConnectionManager will try to reconnect infinite times without emitting errors or any other notifying. Because of that in node-kafka which uses ConnectionManager it's impossible to handle connection errors. It also goes 100% CPU (I guess because of retries frequency) with node 10.30 OS X. It doesn't consume all the CPU on 10.33, but connection loss is still unmanageable.

Can we have those errors emitted or fixed retries count or something else.

Unknown code: -1237188481

I've got this weird exception:

2017-12-24T14:15:37.021Z - error: uncaughtException Error: Unknown code: -1237188481
    at validateCode (project-folder/node_modules/node-zookeeper-client/lib/Exception.js:51:15)
    at Function.create (project-folder/node_modules/node-zookeeper-client/lib/Exception.js:140:5)
    at ConnectionManager.Object.<anonymous>.ConnectionManager.onSocketData (project-folder/node_modules/node-zookeeper-client/lib/ConnectionManager.js:570:35)

Not sure if it's related to this package since I'm using kafka-node.
I'm also not sure what causes it; I'm just sending a message and listen to the message (straightforward use case).

็ป“็‚นๆทปๅŠ ไธไธŠ

่‹ฑๆ–‡ๆฐดๅนณๅคชๆฌก๏ผŒๆ‹…ๅฟƒ่‹ฑ่ฏญๆ่ฟฐไธๆธ…ๆฅš๏ผŒ็”จๅ›ฝ่ฏญๅงใ€‚
ๆˆ‘็š„ไฝฟ็”จๆƒ…ๅ†ตๆ˜ฏ่ฟ™ๆ ท็š„๏ผŒๆœๅŠกๅฏๅŠจ็š„ๆ—ถๅ€™ไผšๅ‘zookeeper้‡ŒๆทปๅŠ ไธ€ไธช็ป“็‚น๏ผŒๅพˆๆ™ฎ้€šๅพˆๅนณๅธธ็š„ไธ€ไธช็ป“็‚นใ€‚็„ถๅŽๆˆ‘ๆœๅŠก้‡ŒๅˆๅฏๅŠจไบ†ไธ€ไธชๅฆๅค–ไธ€ไธชๆœๅŠก็š„็›‘ๅฌใ€‚ๅฝ“ๆŸ็งๅผ‚ๅธธๆƒ…ๅ†ตๆˆ‘ๅฆๅค–้‚ฃไธช็›‘ๅฌๆœๅŠก็š„่ฟžๆŽฅไผšๅคฑ่ดฅ๏ผŒ่ฟ™ไธชๆ—ถๅ€™ๆˆ‘่ฆ่‡ชๅŠจ้‡ๅฏ็›‘ๅฌ๏ผŒ่€ŒๅŒๆ—ถๅ‘ข๏ผŒๆˆ‘ไผšๅ†ๆฌกๆทปๅŠ ๅ‘zookeeperไธญๆทปๅŠ ็ป“็‚น๏ผŒๅฐฑๅœจ่ฟ™ไธชๆ—ถๅ€™๏ผˆ็œ‹ๆœๅŠกๆ—ฅๅฟ—ๆ˜ฏ่ฟ™ไธชๆ—ถๅ€™๏ผ‰๏ผŒ็ป“็‚นๆทปๅŠ ไธไธŠ๏ผŒไปŽzkuiไธญ็œ‹ไธๅˆฐ็ป“็‚น๏ผŒไฝ†ๆ˜ฏไปฃ็ ไธญๅนถๆฒกๆœ‰ๆŠฅๅˆ›ๅปบ็ป“็‚นๅคฑ่ดฅ็š„้”™่ฏฏใ€‚
ๅ› ไธบ่ฟ™็งๆƒ…ๅ†ตไธๅฎนๆ˜“้‡็Žฐ๏ผŒ็›ฎๅ‰ไนŸๆฒกๆœ‰ๆ‰พๅˆฐๅŠžๆณ•ๆจกๆ‹Ÿ๏ผŒไฝ†ๆ˜ฏ่ฟ™ไธช้—ฎ้ข˜็กฎๅฎžๅ‡บ็Žฐ่ฟ‡ๅ‡ ๆฌกใ€‚็Žฐๅœจๆˆ‘ๅˆ†ๆžไธๅ‡บๆฅๅŽŸๅ› ไบ†๏ผŒๅธŒๆœ›ๅ„ไฝ่€ๅคงๅธฎๅธฎๅฟ™๏ผŒไธ‡ๅˆ†ๆ„Ÿๆฟ€ใ€‚ @alexguan

node crashes when zookeeper sends an empty message

I'm using node-zookeeper-client version 0.2.1. I've got the following stacktrace:

Error: offset: 4 is out of buffer range.
at Record.deserialize (/opt/Autonomy/shared/zookeeper-ext/node_modules/node-zookeeper-client/lib/jute/index.js:465:15)
at ConnectionManager.onSocketData (/opt/Autonomy/shared/zookeeper-ext/node_modules/node-zookeeper-client/lib/ConnectionManager.js:456:34)
at ConnectionManager.onSocketData (/opt/Autonomy/shared/zookeeper-ext/node_modules/node-zookeeper-client/lib/ConnectionManager.js:580:14)
at Socket.EventEmitter.emit (events.js:95:17)
at Socket. (stream_readable.js:745:14)
at Socket.EventEmitter.emit (events.js:92:17)
at emitReadable
(_stream_readable.js:407:10)
at emitReadable (_stream_readable.js:403:5)
at readableAddChunk (_stream_readable.js:165:9)
at Socket.Readable.push (_stream_readable.js:127:10)
at TCP.onread (net.js:528:21)

It seems zookeeper is sending an empty message which causes the client to throw. I don't think throwing an exception is the right thing to do just because a separate process gave you some data you didn't like. Especially since the exception is thrown from a handler and therefore can't be caught by the code that's calling node-zookeeper-client. And especially since (AFAICT) the interface with the server isn't documented.

This happened just after we briefly lost contact with the zookeeper server. I believe that https://issues.apache.org/jira/browse/ZOOKEEPER-1437 addresses the same server-side bug (but in a completely different client).

web app crash due to zookeeper server kept changing leader every 10 milli seconds

we are using "node-zookeeper-client" in our node.js server to watch backend zookeeper event change.
we are using getData like here https://github.com/alexguan/node-zookeeper-client/blob/master/examples/get.js

And recently, the backend zookeeper kept changing leader every 10 milliseconds(which is flapping, we will fix this issue on the backend for sure). however, in the meantime, our Web app is crashing due to page fault because the event change watcher continually process leadership change event on node.js.

is there a way to fix this?

socket could be null or undefined.

socket could be undefined or null
defense code needed

node-zookeeper-client/lib/ConnectionManager.js 625 line

if ( this.socket && !this.socket.write(packet.request.toBuffer())) { // Back pressure is handled here, when the socket emit // drain event, this method will be invoked again. break; }

How to read ctime and mtime from Stat object?

I am trying to read ctime and mtime from the Stat object but I am unable to do that.
When I print Stat object I see below output. But I am unable to convert ctime buffer to meaningful value.

I tried stat.mtime.toString('utf8') and other buffer functions, but nothing helped.
Have anyone has tried converting mtime buffer to String, something like Tue Mar 28 22:53:39 PDT 2017 ? Any pointers will be appreciated.

Record {
  specification:
   [ { name: 'czxid', type: 'long' },
     { name: 'mzxid', type: 'long' },
     { name: 'ctime', type: 'long' },
     { name: 'mtime', type: 'long' },
     { name: 'version', type: 'int' },
     { name: 'cversion', type: 'int' },
     { name: 'aversion', type: 'int' },
     { name: 'ephemeralOwner', type: 'long' },
     { name: 'dataLength', type: 'int' },
     { name: 'numChildren', type: 'int' },
     { name: 'pzxid', type: 'long' } ],
  chrootPath: undefined,
  czxid: <Buffer 00 00 00 43 02 23 af 4f>,
  mzxid: <Buffer 00 00 00 43 02 23 af 4f>,
  ctime: <Buffer 00 00 01 5b 18 bc d3 f8>,
  mtime: <Buffer 00 00 01 5b 18 bc d3 f8>,
  version: 0,
  cversion: 0,
  aversion: 0,
  ephemeralOwner: <Buffer 00 00 00 00 00 00 00 00>,
  dataLength: 748,
  numChildren: 0,
  pzxid: <Buffer 00 00 00 43 02 23 af 4f> }

client SYNC_CONNECTED despite being disconnected from the server for longer than session timeout

Client stays in SYNC_CONNECTED state when disconnected from the server for longer than its session timeout. I expected DISCONNECTED state after second 3 or 5 below:

$ node watch.js 127.0.0.1:2181 /blah/eph3 bomb& sleep 1; sudo disable_port 2181 10;
[1] 29292
[ '127.0.0.1:2181', '/blah/eph3' ]
0: client is DISCONNECTED[0]
"connected" to the server.
[ 'client state', { name: 'SYNC_CONNECTED', code: 3 } ]
Node: /blah/eph3 is successfully created.
zk.exists@/blah/eph3 [path, result, error, stat] ["/blah/eph3",0,null,{"specification":[{"name":"czxid","type":"long"},{"name":"mzxid","type":"long"},{"name":"ctime","type":"long"},{"name":"mtime","type":"long"},{"name":"version","type":"int"},{"name":"cversion","type":"int"},{"name":"aversion","type":"int"},{"name":"ephemeralOwner","type":"long"},{"name":"dataLength","type":"int"},{"name":"numChildren","type":"int"},{"name":"pzxid","type":"long"}],"czxid":[0,0,0,0,0,0,10,41],"mzxid":[0,0,0,0,0,0,10,41],"ctime":[0,0,1,65,127,31,233,184],"mtime":[0,0,1,65,127,31,233,184],"version":0,"cversion":0,"aversion":0,"ephemeralOwner":[1,65,96,50,23,73,0,51],"dataLength":4,"numChildren":0,"pzxid":[0,0,0,0,0,0,10,41]}]
1: client is SYNC_CONNECTED[3]
2: client is SYNC_CONNECTED[3]
3: client is SYNC_CONNECTED[3]
4: client is SYNC_CONNECTED[3]
5: client is SYNC_CONNECTED[3]
6: client is SYNC_CONNECTED[3]
7: client is SYNC_CONNECTED[3]
8: client is SYNC_CONNECTED[3]
9: client is SYNC_CONNECTED[3]
10: client is SYNC_CONNECTED[3]
11: client is SYNC_CONNECTED[3]
12: client is SYNC_CONNECTED[3]
zk watcher@/blah/eph3: NODE_DELETED[2]@/blah/eph3 state SYNC_CONNECTED[3]
zk.exists@/blah/eph3 [path, result, error, stat] ["/blah/eph3",-4,"Exception: CONNECTION_LOSS[-4]",null]
[ 'client state', { name: 'DISCONNECTED', code: 0 } ]
[ 'client state', { name: 'EXPIRED', code: -122 } ]
close1
[ 'client state', { name: 'DISCONNECTED', code: 0 } ]
13: client is DISCONNECTED[0]
14: client is DISCONNECTED[0]
15: client is DISCONNECTED[0]
$ cat watch.js
var zookeeper = require('node-zookeeper-client');
function inspect(o) { return require('util').inspect(o, false, null); }

console.dir([process.argv[2], process.argv[3]]);
var client = zookeeper.createClient(process.argv[2], {retries: 0, sessionTimeout: 5000});
var path = process.argv[3];
var data = new Buffer(process.argv[4]);

function exceptionObjectToCode(exceptionObject) { return exceptionObject ? exceptionObject.getCode() : zookeeper.Exception.OK; }
function exceptionObjectToString(exceptionObject) { return exceptionObject ? exceptionObject.toString() : null; }

client.on('state', function (s) {
   console.dir(['client state', s]);
   if (client.getState() === zookeeper.State.EXPIRED) {
     console.log('close1');
     client.close();
   }
});

function curryExistsHandler(path, next) {
  return function (exceptionObject, stat) {
    var rc = exceptionObjectToCode(exceptionObject); 
    var error = exceptionObjectToString(exceptionObject);
    console.log("zk.exists@" + path + " [path, result, error, stat] " + JSON.stringify([path, rc, error, stat]));
    return next(null);
  };
}
function watcherCallback(watcherEvent) {
  var type = watcherEvent.getType();
  var path = watcherEvent.getPath();
  console.log('zk watcher@' + path + ': ' + watcherEvent.toString() + ' state ' + client.getState());
  client.exists(path, watcherCallback,
    curryExistsHandler(path,
      function(nextError) {
        if (nextError) {
          console.log('exists callback throwing ' + inspect(nextError));
          throw nextError;
        }
      }));
}

client.once('connected', function () {
    console.log('"connected" to the server.');
    client.create(path,  new Buffer('blah'), zookeeper.ACL.OPEN_ACL_UNSAFE, 
      zookeeper.CreateMode.EPHEMERAL,
      function (error) {
        if (error) {
            console.log('Failed to create node: %s due to: %s.', path, error);
        } else {
            console.log('Node: %s is successfully created.', path);
        }

        client.exists(path, watcherCallback, curryExistsHandler(path,
              function(nextError) {
                if (nextError) {
                  console.log('exists (top) callback throwing ' + inspect(nextError));
                  throw nextError;
                }
              }));
    });
});
client.connect();

var startTime = Date.now();
function reportClientStateLoop() {
  console.log(Math.round((Date.now()-startTime)/1000) + ': client is ' + client.getState());
  setTimeout(reportClientStateLoop, 1000);
}
reportClientStateLoop();

$ cat disable_port
/bin/bash -c "/sbin/iptables -I INPUT 1 -p tcp --sport ${1} -j DROP; /sbin/iptables -I INPUT 2 -p tcp --dport ${1} -j DROP; sleep ${2}; /sbin/iptables -D INPUT 1; /sbin/iptables -D INPUT 1"

ConnectionManager.findNextServer hangs with 100% cpu usage on Windows

ConnectionManager.prototype.findNextServer() hangs with 100% cpu on Windows when it calls setTimeout() with a fractional delay:

ConnectionManager.prototype.findNextServer = function (callback) {
...
if (self.serverAttempts === self.servers.length) {
setTimeout(function () {
...
}, Math.random() * self.spinDelay); <<<<<<<<<<<<<<<
} else {
...
}

This was observed with node v0.10.30 on a Windows Server 2008 system with version 0.2.0 of node-zookeeper-client. It is easily reproducible by specifying a single zookeeper server that is not responsive (down or is the ensemble leader and leaderServes is true). The bug is actually in the Windows version of node (I've not observed it on Linux), but is easily avoided by using

Math.floor(Math.random() * self.spinDelay)

instead. Other timeouts in ConnectionManager.js are already computed with Math.floor()

Cannot trigger 'disconnected' event when client connect fails

The default state of the client is 'DISCONNECTED'. When the client has failed to connect, the state has not changed and the 'state' event cannot be triggered. As a result, the corresponding operation cannot be performed when the client is disconnected.

zookeeper connect not working

I have written a script:

      var zookeeper = require('node-zookeeper-client');
      let zk_addr = "localhost:2182" 
      var client = zookeeper.createClient(zk_addr, { sessionTimeout: 1000, retries: 0 });
      client.connect()

In this example the zookeeper address is incorrect. So the script tries to reconnect and doesn't timeout.
I want my script to timeout after some time.

Help would be appreciated

Thanks

WatcherManager leaks memory on un-rewatched nodes

When a watch fires, the WatcherManager keeps the node's path in its re-watch dictionaries instead of clearing it out like the Java client does.

This example will print out the watchManager dictionary after watching and triggering for 100 different nodes:

util = require('util');
zk = require('node-zookeeper-client');

server = process.env.ZOOKEEPER_ADDRESS
testBasePath = '/test';
watchesToLeak = 100;

client = zk.createClient(server);
client.once('connected', function() {
  client.mkdirp(testBasePath, function(err, path) {
    asplode(watchesToLeak);
  });
});
client.connect();

function asplode(i) {
  client.create(testBasePath + '/i-', zk.CreateMode.EPHEMERAL_SEQUENTIAL, function(err, path) {
    client.exists(path, function(ev) {
      console.log(path + " " + ev.getName());
    }, function(err, stat) {
      client.remove(path, function(err) {
        if(i > 0) asplode(i - 1);
        else {
          console.log(util.inspect(client.connectionManager.watcherManager));
          client.close();
        }
      });
    });
  });
}

zookeeper-client method issue

Hello everyone,
The code given below connects to zookeeper. But the issue is that if the connection is unsuccessful then the code stucks. Is there a way to check weather connection successful or not

              var zookeeper = require('node-zookeeper-client'); 
              var client = zookeeper.createClient("localhost:2182", { sessionTimeout: 1000, retries: 0 });
              let timeoutTimeperiod = 10000 
              client.connect();

Code stucks in the codes below:

               client.setData(path, buffer, defaultVersion, function (error, stat) {
		// failure
		if (error) {
			client.close();
			response['message'] = 'Failed to set data on node : ' + path;
			response['path'] = path;
			response['error'] = error;
			reject(response);
		}
		// success
		client.close();
		response['message'] = 'Data has been set on node : ' + path;
		response['error'] = 'NIL';
		response['status'] = true;
		resolve(response);
	  });

Need help, thanks in advance

SESSION_EXPIRED event never fires on server disconnect

Hey, really great module.

If a client has connected to a server, and then later on, there is a network partition and the client is unable to reconnect -- no SESSION_EXPIRED event is ever emitted by the client.

From my testing all the client emits is a DISCONNECTED event -- even if the client never reconnects to another server (which means that from the server point of view our session has expired since we couldn't reconnect to it). This is because the only time we emit SESSION_EXPIRED is when we get data from the socket: https://github.com/alexguan/node-zookeeper-client/blob/master/lib/ConnectionManager.js#L432

But if the socket was already closed and no data events will be emitted. In our case when there is a network partition, we'll never emit the SESSION_EXPIRED event. This means that if downstream consumers are only listening for SESSION_EXPIRED, they'll never get it on a network partition and hang forever. Specifically, if I've got a watch set on a znode, I won't get any more watch events or SESSION_EXPIRED events and I'll hang forever.

[bug] Error: Cannot find module './path.js'

When I use [email protected] on npm, there is a require error on WatcherManager.js. Does the code on npm is the same on github?

module.js:340
    throw err;
          ^
Error: Cannot find module './path.js'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:362:17)
    at require (module.js:378:17)
    at Object.<anonymous> (node-hbase-client/node_modules/zookeeper-watcher/node_modules/node-zookeeper-client/lib/WatcherManager.js:10:12)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:362:17)
``

NO_NODE exception when using connect string with multiple chroot'd servers

So, as the title says, I'm seeing an exception when I attempt to use a client instance that has successfully connected when it includes multiple servers. These servers all contain a chroot path, but I'm not sure if that makes a difference in the issue or not. I assume that you have tried this module out with multiple servers, but maybe not multiple servers chroot'd? The chroot path is the same for all servers, so that doesn't matter.

The connection succeeds, I handle the 'connected' event, but when I attempt to do anything after that, for example I try to do a mkdirp in the 'connected' handler to initialize things, it fails with NO_NODE exception. I tried following things down through the jute code, but I couldn't find anything that would send back a NO_NODE error.

I don't know what 'node' the error is referring to and I don't know why things work with one server in the connect string, but not with multiple servers. Can anyone help me out? Thanks.

Error when using from react

I see the error message Error: Cannot find module "." when trying to run a react app which includes node-zookeeper-client. The error occurs on line 776 when trying to require the specification file, ./specification.json. This file doesn't exist in the code bundled by webpack. I'm using node-zookeeper-client as a transitive dependency of zoologist.

A potential fix: if specification.json was specification.js and exported the json as a var then the import would work. I've tried this. Happy to put in a PR if you'd like me to. I could probably work around this with some webpack changes but: 1) at the moment the dependency fails when used from react and you probably don't want this and 2) I might have to 'eject' the app from the cradle of create-react-app and I'd rather not do that for this reason.

Steps to reproduce (I'm using yarn here but the steps could easily be npm):

  1. $ create-react-app node-zookeeper-client_react_test
    1. I'm using create-react-app version 1.3.1.
  2. $ cd node-zookeeper-client
  3. $ yarn add node-zookeeper-client
  4. Edit src/App.js and add var zookeeper = require('node-zookeeper-client'); below the imports. (Using an import produces the same error).
  5. $ yarn start and let it open the app's root page

events generated during watch on connection loss differ for persistent and ephemeral znodes

Loosing zookeper connection while watching a persistent znode emits DISCONNECTED and EXPIRED state events, which makes it easy to decide to re-establish the connection.

Loosing zookeper connection while watching an EPHEMERAL znode returns NODE_DELETED inside the watch callback prior to emitting DISCONNECTED and EXPIRED state events, which makes it hard to decide if connection needs to be re-established. Not sure if this is working as designed, but it would be nice if persistent and ephemeral znodes behaved consistently.

$ cat disable_port
/bin/bash -c "/sbin/iptables -I INPUT 1 -p tcp --sport ${1} -j DROP; /sbin/iptables -I INPUT 2 -p tcp --dport ${1} -j DROP; sleep ${2}; /sbin/iptables -D INPUT 1; /sbin/iptables -D INPUT 1"

$ cat watcher.js
var zookeeper = require('node-zookeeper-client');
function inspect(o) { return require('util').inspect(o, false, null); }

console.dir([process.argv[2], process.argv[3]]);
var client = zookeeper.createClient(process.argv[2], { retries : 0,     sessionTimeout: 5000});
var path = process.argv[3];
var data = new Buffer(process.argv[4]);

var ZOK = zookeeper.Exception.OK;
var ZNONODE = zookeeper.Exception.NO_NODE;

function exceptionObjectToCode(exceptionObject) { return exceptionObject ? exceptionObject.getCode() : ZOK; }
function exceptionObjectToString(exceptionObject) { return exceptionObject ? exceptionObject.toString() : null; }

client.on('state', function (s) {
   console.dir(['client state', s]);
   if (client.getState() === zookeeper.State.EXPIRED) {
     console.log('close1');
     client.close();
   }
});

function curryExistsHandler(path, next) {
  return function (exceptionObject, stat) {
    var rc = exceptionObjectToCode(exceptionObject); 
    var error = exceptionObjectToString(exceptionObject);
    console.log("zk.exists@" + path + " [path, result, error, stat] " + JSON.stringify([path, rc, error, stat]));
    if (rc === ZOK || rc === ZNONODE || rc === zookeeper.Exception.SESSION_EXPIRED) {
      return next(null);
    } else {
      return next(new Error('zk.exists ' + path + ' returned [rc, error, stat, state] of ' + JSON.stringify([rc, error, stat, client.getState()])));
    }
  };
}
function watcherCallback(watcherEvent) {
  var type = watcherEvent.getType();
  var path = watcherEvent.getPath();
  console.log('zk watcher@' + path + ': ' + watcherEvent.toString() + ' state ' + client.getState());
  client.exists(path, watcherCallback,
    curryExistsHandler(path,
      function(nextError) {
        if (nextError) {
          console.log('exists callback throwing ' + inspect(nextError));
          throw nextError;
        }
      }));
}

client.once('connected', function () {
    console.log('"connected" to the server.');
    client.create(path,  new Buffer('blah'), zookeeper.ACL.OPEN_ACL_UNSAFE, 
      //zookeeper.CreateMode.EPHEMERAL,
      zookeeper.CreateMode.PERSISTENT,
      function (error) {
        if (error) {
            console.log('Failed to create node: %s due to: %s.', path, error);
        } else {
            console.log('Node: %s is successfully created.', path);
        }

        client.exists(path, watcherCallback, curryExistsHandler(path,
              function(nextError) {
                if (nextError) {
                  console.log('exists (top) callback throwing ' + inspect(nextError));
                  throw nextError;
                }
              }));
    });
});
client.connect();
//////////////////////////// PERSISTENT:
$ node watch.js 127.0.0.1:2181 /blah/eph3 bomb& sleep 1; sudo disable_port 2181 4.6;
[2] 24023
[ '127.0.0.1:2181', '/blah/eph3' ]
"connected" to the server.
[ 'client state', { name: 'SYNC_CONNECTED', code: 3 } ]
Node: /blah/eph3 is successfully created.
zk.exists@/blah/eph3 [path, result, error, stat] ["/blah/eph3",0,null,{"specification":[{"name":"czxid","type":"long"},{"name":"mzxid","type":"long"},{"name":"ctime","type":"long"},{"name":"mtime","type":"long"},{"name":"version","type":"int"},{"name":"cversion","type":"int"},{"name":"aversion","type":"int"},{"name":"ephemeralOwner","type":"long"},{"name":"dataLength","type":"int"},{"name":"numChildren","type":"int"},{"name":"pzxid","type":"long"}],"czxid":[0,0,0,0,0,0,9,232],"mzxid":[0,0,0,0,0,0,9,232],"ctime":[0,0,1,65,118,183,110,173],"mtime":[0,0,1,65,118,183,110,173],"version":0,"cversion":0,"aversion":0,"ephemeralOwner":[0,0,0,0,0,0,0,0],"dataLength":4,"numChildren":0,"pzxid":[0,0,0,0,0,0,9,232]}]

$ [ 'client state', { name: 'DISCONNECTED', code: 0 } ]
[ 'client state', { name: 'EXPIRED', code: -122 } ]
close1
[ 'client state', { name: 'DISCONNECTED', code: 0 } ]
[2]-  Done                    node watch.js 127.0.0.1:2181 /blah/eph3 bomb

//////////////////////////// EPHEMERAL: 
// after interrupting connection for 4.6 seconds we get watch callback is called with NODE_DELETED, 
// then exists returns CONNECTION_LOSS.  I don't want to introduce the complexity of tracking this state to see if
// connection gets re-established, and would prefer if client threw DISCONNECTED, and EXPIRED as in the PERSISTENT example
$ node watch.js 127.0.0.1:2181 /blah/eph3 bomb& sleep 1; sudo disable_port 2181 4.6;
[2] 24002
[ '127.0.0.1:2181', '/blah/eph3' ]
"connected" to the server.
[ 'client state', { name: 'SYNC_CONNECTED', code: 3 } ]
Node: /blah/eph3 is successfully created.
zk.exists@/blah/eph3 [path, result, error, stat] ["/blah/eph3",0,null,{"specification":[{"name":"czxid","type":"long"},{"name":"mzxid","type":"long"},{"name":"ctime","type":"long"},{"name":"mtime","type":"long"},{"name":"version","type":"int"},{"name":"cversion","type":"int"},{"name":"aversion","type":"int"},{"name":"ephemeralOwner","type":"long"},{"name":"dataLength","type":"int"},{"name":"numChildren","type":"int"},{"name":"pzxid","type":"long"}],"czxid":[0,0,0,0,0,0,9,229],"mzxid":[0,0,0,0,0,0,9,229],"ctime":[0,0,1,65,118,182,135,112],"mtime":[0,0,1,65,118,182,135,112],"version":0,"cversion":0,"aversion":0,"ephemeralOwner":[1,65,96,50,23,73,0,29],"dataLength":4,"numChildren":0,"pzxid":[0,0,0,0,0,0,9,229]}]

$ zk watcher@/blah/eph3: NODE_DELETED[2]@/blah/eph3 state SYNC_CONNECTED[3]
zk.exists@/blah/eph3 [path, result, error, stat] ["/blah/eph3",-4,"Exception: CONNECTION_LOSS[-4]",null]
exists callback throwing [Error: zk.exists /blah/eph3 returned [rc, error, stat, state] of [-4,"Exception: CONNECTION_LOSS[-4]",null,{"name":"SYNC_CONNECTED","code":3}]]

/home/x/src/nucleus/node_modules/watch.js:44
          throw nextError;
                ^
Error: zk.exists /blah/eph3 returned [rc, error, stat, state] of [-4,"Exception: CONNECTION_LOSS[-4]",null,{"name":"SYNC_CONNECTED","code":3}]
    at /home/x/src/nucleus/node_modules/watch.js:31:19
    at /home/x/src/nucleus/node_modules/node-zookeeper-client/index.js:165:26
    at Object.async.whilst (/home/x/src/nucleus/node_modules/node-zookeeper-client/node_modules/async/lib/async.js:624:13)
    at /home/x/src/nucleus/node_modules/node-zookeeper-client/node_modules/async/lib/async.js:620:23
    at /home/x/src/nucleus/node_modules/node-zookeeper-client/index.js:145:21
    at Object.callback (/home/x/src/nucleus/node_modules/node-zookeeper-client/index.js:732:21)
    at ConnectionManager.cleanupPendingQueue (/home/x/src/nucleus/node_modules/node-zookeeper-client/lib/ConnectionManager.js:189:27)
    at ConnectionManager.onSocketClosed (/home/x/src/nucleus/node_modules/node-zookeeper-client/lib/ConnectionManager.js:274:10)
    at Socket.EventEmitter.emit (events.js:95:17)
    at TCP.close (net.js:466:12)

Recursive delete not supported

Hi, i am attempting to support deleting a large node tree in my ZK. Is it possible to recursively delete? I see this available in ZK 3.4.0+.

Thanks,
Matt

SYNC_CONNECTED or CONNECTED, which is it?

The readme section at https://github.com/alexguan/node-zookeeper-client/blob/master/README.md#state explains the various states.

I had a bug in my code where I called close() before I was connected, causing a weird error in node-zookeeper-client. While not particularly graceful, my bad. But it's not documented during which states I am allowed to call close. This is the first problem.

The next problem is that the readme describes State.CONNECTED in the little bullet list, but in the example right below, it refers to State.SYNC_CONNECTED. So which is it? Should I expect both? Something needs to be fixed in the documentation here.

NO_NODE error on kafka consumer init.

var kafka = require('kafka-node'),
Consumer = kafka.Consumer,
client = new kafka.Client(),
consumer = new Consumer(
  client,
  [
    { topic: '1234', partition: 0 }
  ]
);
consumer.on('message', function (message) {
  console.log(message);
});

Kafka consumer created using the above code crashes with NO_NODE[-101] error.

Exception: NO_NODE[-101]
    at ConnectionManager.onSocketData (/home/sk/ws/kafka/node_modules/kafka-node/node_modules/node-zookeeper-client/lib/ConnectionManager.js:570:23)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:746:14)
    at Socket.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
    at readableAddChunk (_stream_readable.js:165:9)
    at Socket.Readable.push (_stream_readable.js:127:10)
    at TCP.onread (net.js:526:21)

More information on the node path that is not found will help a lot....

Exception in setData method

Hello everyone,

I wan to set a dictionary on a node

                              node path = "/test/testNode1/"
                              node data = {
                                      "a":"b",
                                      "b":"c"
                              }

So I converted the dictionary to buffer in this way:

                              let buffer = Buffer.from(JSON.stringify(node_data));

But when I set a value to a node, i get this exception

                                client.setData(path, buffer, 19, function (error, stat) {
                                               if (error) {
                                                         console.log(error.stack);
                                                         client.close()
                                                         return;
                                               }
                                               console.log('Data is set.');
                                 });    

Let me know if I have done something wrong.

Thanks in advance

bundle types?

I'm going to write types definition file of this lib to make the lib easier to be used in typescript.
There are 2 ways: ]

  1. bundle the types with the lib
  2. put in: https://github.com/DefinitelyTyped/DefinitelyTyped , installed with @types/node-zookeeper-client

so, will this lib be willing to bundle the types?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.