Ejemplo n.º 1
0
  private <T> Response<T> sendRequest(
      RequestType type,
      SlaveContext slaveContext,
      Serializer serializer,
      Deserializer<T> deserializer) {
    // TODO Refactor, break into smaller methods
    Triplet<Channel, ChannelBuffer, ByteBuffer> channelContext = null;
    try {
      // Send 'em over the wire
      channelContext = getChannel();
      Channel channel = channelContext.first();
      ChannelBuffer buffer = channelContext.second();
      buffer.clear();
      buffer = new ChunkingChannelBuffer(buffer, channel, MAX_FRAME_LENGTH);
      buffer.writeByte(type.ordinal());
      if (type.includesSlaveContext()) {
        writeSlaveContext(buffer, slaveContext);
      }
      serializer.write(buffer, channelContext.third());
      if (buffer.writerIndex() > 0) {
        channel.write(buffer);
      }

      // Read the response
      @SuppressWarnings("unchecked")
      BlockingReadHandler<ChannelBuffer> reader =
          (BlockingReadHandler<ChannelBuffer>) channel.getPipeline().get("blockingHandler");
      final Triplet<Channel, ChannelBuffer, ByteBuffer> finalChannelContext = channelContext;
      DechunkingChannelBuffer dechunkingBuffer =
          new DechunkingChannelBuffer(reader) {
            @Override
            protected ChannelBuffer readNext() {
              ChannelBuffer result = super.readNext();
              if (result == null) {
                channelPool.dispose(finalChannelContext);
                throw new HaCommunicationException("Channel has been closed");
              }
              return result;
            }
          };
      T response = deserializer.read(dechunkingBuffer);
      TransactionStream txStreams =
          type.includesSlaveContext()
              ? readTransactionStreams(dechunkingBuffer)
              : TransactionStream.EMPTY;
      return new Response<T>(response, txStreams);
    } catch (ClosedChannelException e) {
      channelPool.dispose(channelContext);
      throw new HaCommunicationException(e);
    } catch (IOException e) {
      throw new HaCommunicationException(e);
    } catch (InterruptedException e) {
      throw new HaCommunicationException(e);
    } catch (Exception e) {
      throw new HaCommunicationException(e);
    }
  }