示例#1
0
    /**
     * Keeps processing the {@link PendingRequest}s in the pending {@link Queue} until a QUIT is
     * encountered in the pending queue. Thread will stop after processing the QUIT response (which
     * is expected to be a {@link VirtualResponse}.
     *
     * <p>TODO: not entirely clear what is the best way to handle exceptions.
     *
     * <p>TODO: socket Reconnect in the context of pipelining is non-trivial, and maybe not even
     * practically possible. (e.g. request n is sent but pipe breaks on some m (m!=n) response. non
     * trivial.
     */
    public void run() {
      Log.log("AsyncConnection processor thread <%s> started.", Thread.currentThread().getName());
      /** Response handler thread specific protocol handler -- optimize fencing */
      Protocol protocol =
          Assert.notNull(
              newProtocolHandler(), "the delegate protocol handler", ClientRuntimeException.class);
      PendingRequest pending = null;
      while (true) {
        try {
          pending = pendingQueue.take();
          try {
            Request request =
                Assert.notNull(
                    protocol.createRequest(pending.cmd, pending.args),
                    "request object from handler",
                    ProviderException.class);
            request.write(getOutputStream());

            pending.response = protocol.createResponse(pending.cmd);
            pending.response.read(getInputStream());

            pending.completion.signal();
            if (pending.response.getStatus().isError()) {
              Log.error(
                  "(Asynch) Error response for "
                      + pending.cmd.code
                      + " => "
                      + pending.response.getStatus().message());
            }

          } catch (ProviderException bug) {
            Log.error("ProviderException: " + bug.getLocalizedMessage());
            bug.printStackTrace();
            pending.setCRE(bug);
          } catch (ClientRuntimeException cre) {
            Log.error("ClientRuntimeException: " + cre.getLocalizedMessage());
            cre.printStackTrace();
            pending.setCRE(cre);
          } catch (RuntimeException e) {
            Log.error("Unexpected RuntimeException ", e);
            e.printStackTrace();
            pending.setCRE(
                new ProviderException("Unexpected runtime exception in response handler"));
            pending.setResponse(null);
            break;
          }

          // redis (1.00) simply shutsdown connection even if pending responses
          // are expected, so quit is NOT sent.  we simply close connection on this
          // end.
          if (pending.cmd == Command.QUIT) {
            AsyncConnection.this.disconnect();
            break;
          }
        } catch (InterruptedException e1) {
          e1.printStackTrace();
        }
      }
      Log.log("AsyncConnection processor thread <%s> stopped.", Thread.currentThread().getName());
    }