def value
      time_to_stop = Time.now + OPERATION_TIMEOUT
      now = nil

      @mutex.synchronize do
        while true
          now = Time.now
          break if @rval or @error or (now > time_to_stop)

          deadline = time_to_stop.to_f - now.to_f
          @cond.wait(deadline)
        end

        if (now > time_to_stop) and !@rval and !@error
          raise Exceptions::ContinuationTimeoutError, "response for meth: #{meth.inspect}, args: #{@args.inspect}, not received within #{OPERATION_TIMEOUT} seconds"
        end

        case @error
        when nil
          # ok, nothing to see here, carry on
        when :shutdown
          raise Exceptions::NotConnected, "the connection is shutting down"
        when ZOO_EXPIRED_SESSION_STATE
          raise Exceptions::SessionExpired, "connection has expired"
        else
          raise Exceptions::NotConnected, "connection state is #{STATE_NAMES[@error]}"
        end

        case @rval.length
        when 1
          return @rval.first
        else
          return @rval
        end
      end
    end
def value
      time_to_stop = Time.now + OPERATION_TIMEOUT
      now = nil

      @mutex.synchronize do
        while true
          now = Time.now
          break if @rval or @error or (now > time_to_stop)

          deadline = time_to_stop.to_f - now.to_f
          @cond.wait(deadline)
        end

        if (now > time_to_stop) and !@rval and !@error
          raise Exceptions::ContinuationTimeoutError, "response for meth: #{meth.inspect}, args: #{@args.inspect}, not received within #{OPERATION_TIMEOUT} seconds"
        end

        case @error
        when nil
          # ok, nothing to see here, carry on
        when :shutdown
          raise Exceptions::NotConnected, "the connection is shutting down"
        when ZOO_EXPIRED_SESSION_STATE
          raise Exceptions::SessionExpired, "connection has expired"
        else
          raise Exceptions::NotConnected, "connection state is #{STATE_NAMES[@error]}"
        end

        case @rval.length
        when 1
          return @rval.first
        else
          return @rval
        end
      end
    end
the caller calls this method and receives the response from the async loop
 this method has a hard-coded 30 second timeout as a safety feature. No
 call should take more than 20s (as the session timeout is set to 20s)
 so if any call takes longer than that, something has gone horribly wrong.

 @raise [ContinuationTimeoutError] if a response is not received within 30s