public <T> T retryUntilConnected(Callable<T> callable) throws ZkInterruptedException, IllegalArgumentException,
                                                          ZkException, RuntimeException {
        if (_zookeeperEventThread != null && Thread.currentThread() == _zookeeperEventThread) {
            throw new IllegalArgumentException("Must not be done in the zookeeper event thread.");
        }
        while (true) {
            try {
                return callable.call();
            } catch (ConnectionLossException e) {
                // we give the event thread some time to update the status to 'Disconnected'
                Thread.yield();
                waitUntilConnected();
            } catch (SessionExpiredException e) {
                // we give the event thread some time to update the status to 'Expired'
                Thread.yield();
                waitUntilConnected();
            } catch (KeeperException e) {
                throw ZkException.create(e);
            } catch (InterruptedException e) {
                throw new ZkInterruptedException(e);
            } catch (Exception e) {
                throw ExceptionUtil.convertToRuntimeException(e);
            }
        }
    }
@param <T>
@param callable
@return result of Callable
@throws ZkInterruptedException if operation was interrupted, or a required reconnection got interrupted
@throws IllegalArgumentException if called from anything except the ZooKeeper event thread
@throws ZkException if any ZooKeeper exception occurred
@throws RuntimeException if any other exception occurs from invoking the Callable
shared/common/src/main/java/com/alibaba/otter/shared/common/utils/zookeeper/ZkClientx.java