ZooKeeper.close() doesn't force the client into a CLOSED state. While the closing flag ensures that the client will close, its state may end up in CLOSED, CONNECTING or CONNECTED.
I developed a patch and in the process cleaned up a few other things primarily to enable testing of state transitions.
- ClientCnxnState is new and enforces certain state transitions
- ZooKeeper.isExpired() is new
- ClientCnxn no longer refers to ZooKeeper, WatchManager is externalized, and ClientWatchManager includes 3 new methods
- The SendThread terminates the EventThread on a call to close() via the event-of-death
- Polymorphism is used to handle internal exceptions (SendIOExceptions)
- The patch incorporates ZOOKEEPER-126.patch and prevents close() from blocking