예제 #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());
    }
예제 #2
0
  /**
   * Creates a {@link Connection} with {@link Connection.Modality#Synchronous} semantics suitable
   * for use by synchronous (blocking) JRedis clients.
   *
   * <p>[TODO: this method should be using connection spec!]
   *
   * @param host
   * @param port
   * @param redisVersion
   * @return
   */
  protected Connection createSynchConnection(String host, int port, RedisVersion redisVersion) {
    InetAddress address = null;
    Connection synchConnection = null;
    try {

      address = InetAddress.getByName(host);
      synchConnection = new SynchConnection(address, port, redisVersion);
      Assert.notNull(synchConnection, "connection delegate", ClientRuntimeException.class);
    } catch (NotSupportedException e) {
      Log.log("Can not support redis protocol '%s'", redisVersion);
      throw e;
    } catch (ProviderException e) {
      Log.bug("Couldn't create the handler delegate.  => " + e.getLocalizedMessage());
      throw e;
    } catch (ClientRuntimeException e) {
      String msg = e.getMessage() + "\nMake sure your server is running.";
      Log.error("Error creating connection -> " + e.getLocalizedMessage());
      setConnection(new FaultedConnection(msg));
    } catch (UnknownHostException e) {
      String msg = "Couldn't obtain InetAddress for " + host;
      Log.problem(msg + "  => " + e.getLocalizedMessage());
      throw new ClientRuntimeException(msg, e);
    }
    return synchConnection;
  }
예제 #3
0
  public SynchConnection(
      InetAddress address,
      int port,
      //			ProtocolHandler protocolHandler,
      RedisVersion redisversion)
      throws ClientRuntimeException, ProviderException {
    super(address, port);
    //		protocolHandler = ProtocolManager.getFactory().createProtocolHandler
    // (Connection.Modality.Synchronous, redisversion.id);
    protocolHandler = new SynchProtocol();
    Assert.notNull(
        protocolHandler, "handlerDelegate from ProtocolManager", ProviderException.class);

    this.protocolHandler =
        Assert.notNull(
            protocolHandler, "the delegate protocol handler", ClientRuntimeException.class);
    Assert.isTrue(
        protocolHandler.isCompatibleWithVersion(redisversion.id),
        "handler delegate supports redis version " + redisversion,
        ClientRuntimeException.class);
  }
예제 #4
0
  public Response serviceRequest(Command cmd, byte[]... args) throws RedisException {
    /*
    	if(start ==-1) start = System.currentTimeMillis();
    */
    if (!isConnected()) throw new NotConnectedException("Not connected!");
    Request request = null;
    Response response = null;
    ResponseStatus status = null;

    try {
      // 1 - Request
      //
      try {
        request =
            Assert.notNull(
                protocolHandler.createRequest(cmd, args),
                "request object from handler",
                ProviderException.class);
        request.write(super.getOutputStream());
      } catch (ProviderException bug) {
        throw bug;
      } catch (ClientRuntimeException problem) {
        Throwable rootProblem = problem.getCause();
        if (null != rootProblem && rootProblem instanceof SocketException) {
          Log.log(
              "[TODO -- attempt reconnect] serviceRequest() -- "
                  + "unrecovered %s in Request phase <Cmd: %s>",
              rootProblem, cmd.code);
        }
        throw problem; // TODO: reconnect here ...
      } catch (RuntimeException everythingelse) {
        String msg =
            "For <Cmd: "
                + cmd.code
                + "> Possible bug in provider code: "
                + everythingelse.getClass().getSimpleName()
                + " => "
                + everythingelse.getLocalizedMessage();
        Log.error("serviceRequest() -- Request phase -- " + msg);
        throw new ProviderException(msg, everythingelse);
      }

      // 2 - Response
      //
      try {
        response =
            Assert.notNull(
                protocolHandler.createResponse(cmd),
                "response object from handler",
                ProviderException.class);
        response.read(super.getInputStream());
      } catch (ProviderException bug) {
        throw bug;
      } catch (ClientRuntimeException problem) {
        Throwable rootProblem = problem.getCause();
        if (null != rootProblem) {
          if (rootProblem instanceof SocketException) {
            Log.log(
                "[NET] [TODO (attempt reconnect?)] serviceRequest(%s) -- "
                    + "problem in Response phase <rootProblem: %s>",
                cmd.code, rootProblem);
          } else if (rootProblem instanceof IOException) {
            Log.log(
                "[IO] [TODO (attempt reconnect?)]  serviceRequest(%s) -- "
                    + "problem in Response phase <rootProblem: %s>",
                cmd.code, rootProblem);
          }
        }
        throw problem; // this is caught below under ClientR..
      }

      // 3 - Status
      //
      // sending response didn't cause any problems
      // check for redis errors
      //
      status =
          Assert.notNull(
              response.getStatus(), "status from response object", ProviderException.class);
      if (status.isError()) {
        //				Log.error ("Request resulted in error: cmd: " + cmd.code + " " + status.message());
        Log.error(cmd.code + " => " + status.message());
        throw new RedisException(cmd, status.message());
      } else if (status.code() == ResponseStatus.Code.CIAO) {
        //				Log.log ("serviceRequest() -- Response status is CIAO.");
        //				Log.log ("serviceRequest() -- closing connection ...");
        disconnect();
      }
    } catch (ProviderException bug) {
      Log.bug("serviceRequest() -- ProviderException: " + bug.getLocalizedMessage());
      Log.log("serviceRequest() -- closing connection ...");

      // now we must close the connection if we can
      disconnect();

      throw bug;
    } catch (ClientRuntimeException problem) {
      Log.problem(
          "serviceRequest() -- Unrecovered ClientRuntimeException: "
              + problem.getLocalizedMessage());
      Log.log("serviceRequest() -- closing connection ...");

      // now we must close the connection if we can
      disconnect();

      throw problem;
    } catch (RuntimeException surprise) {
      surprise.printStackTrace();
      // TODO: Log.log it ...
      Log.bug(
          "serviceRequest() -- *unexpected* RuntimeException: " + surprise.getLocalizedMessage());
      Log.log("serviceRequest() -- closing connection ...");

      // now we must close the connection if we can
      disconnect();

      throw new ClientRuntimeException(
          "unexpected runtime exeption: " + surprise.getLocalizedMessage(), surprise);
    } catch (Error disaster) {
      disaster.printStackTrace();
      // TODO: Log.log it ...
      Log.bug(
          "serviceRequest() -- *unforseen* Java System Error: " + disaster.getLocalizedMessage());
      Log.log("serviceRequest() -- closing connection ...");

      // now we must close the connection if we can
      disconnect();

      throw new ClientRuntimeException(
          "unexpected system error: " + disaster.getLocalizedMessage(), disaster);
    } finally {
    }

    /* - temp benchmarking request service throughput

    		serviceCount ++;
    		if(serviceCount > gate) {
    			delta = System.currentTimeMillis() - start;
    			start = System.currentTimeMillis();
    			throughput = (serviceCount * 1000) / (float) delta;
    			System.out.format ("<%s> - %8.2f /sec | serviced %d requests at %d msecs\n", Thread.currentThread().getName(), throughput, serviceCount, delta );
    			serviceCount = 0;
    		}
    */
    return response;
  }