Releases: flightaware/zookeepertcl
Update for compatibility with libzookeeper 2.6
Clean up zookeeper object creation and cleanup
Two fixes.
First, in some rare cases if you open and close a connection fast enough, synchronously, the close can happen before the callback gets through the zookeeper event queue and the Tcl event queue. This fix handles both ends of the problem:
-
Don't set up the callback if you're performing the init synchronously. The previous code put an event on the queue and exited the event handler early if there was no callback routine. This passes null as the event handler for zookeeper_init if there's no callback.
-
Don't zap the magic number in the zookeeper object until after calling zookeeper_close, because its cleanup may fire any pending handlers.
Second, only delete events where the event's zo element matches the clientData passed to Tcl_DeleteEvents.
Switch to synchronous zookeeper API for non-async calls.
Sync API
Currently, all sync API calls in zookeepertcl
actually use the async functions in the Zookeeper C client. To make these sync API calls appear to block to the Tcl caller, zookeepertcl
uses the function zootcl_wait
, which has the unfortunate side effect of manually calling Tcl_DoOneEvent(TCL_ALL_EVENTS)
, i.e., it enters the event loop. However, if the Tcl client code is already in the event loop, this could cause hard-to-track-down bugs because it requires that the client code is re-entrant. Moreover, having a sync API that is actually async violates expectations; if a client wants a sync-like API that actually uses async calls, this can be implemented on top of the async API. In order to avoid using zootcl_wait
, then, this PR uses the actual sync calls in the Zookeeper C client.
New Subcommands
A few new subcommands have been added to Zookeeper objects:
destroy
andclose
: these are synonyms and end up closing the connection to Zookeeper and deleting thezookeepertcl
handleserver
: this returns the hostname or IP of the Zookeeper server currently connected to. In a clustered environment, this allows for the client to figure out which node in the cluster is being used
API Changes
For the get
subcommand, this PR makes the following modification:
- When the
-data
option is provided for an extant znode but the data isNULL
,get
returns1
and unsets the variable specified by-data
In the current code, this scenario would return 0
, although the README states
If -data is specified, dataVar is the name of an array that the data is stored into, and get returns 1 if the znode exists and 0 if it doesn't.
Also, the above mentioned change to synchronous requests. Where (perhaps for performance reasons) code depended on the event loop continuing while waiting for responses from Zookeeper, code changes may be needed to move to the asynchronous API.
Unit Tests
This PR also adds a number of unit tests in the tests/
directory. These tests require a functioning Zookeeper server / cluster and test the Zookeeper object subcommands, watch callbacks and some of the Tcl procs in the zookeeper
namespace.
Bug fixes
This should fix Bug #1 by massively simplifying the code and removing the possibility of reentrant calls.
Closing the connection (either with the new API or by deleting the handle) could have caused an assert failure if there were pending events
Fix use-after-free bug
Fixes the use-after-free bug in Issue #1
Initial Release - Version 1.0.0
It's quite usable as is. It's gotten some fairly heavy use at FlightAware and seems to be rather stable.