public <SEND extends MessageLite, RECEIVE extends MessageLite> void send( RpcOutcomeListener<RECEIVE> listener, C connection, T rpcType, SEND protobufBody, Class<RECEIVE> clazz, boolean allowInEventLoop, ByteBuf... dataBodies) { Preconditions.checkArgument( allowInEventLoop || !connection.inEventLoop(), "You attempted to send while inside the rpc event thread. This isn't allowed because sending will block if the channel is backed up."); ByteBuf pBuffer = null; boolean completed = false; try { if (!allowInEventLoop && !connection.blockOnNotWritable(listener)) { // if we're in not in the event loop and we're interrupted while blocking, skip sending this // message. return; } assert !Arrays.asList(dataBodies).contains(null); assert rpcConfig.checkSend(rpcType, protobufBody.getClass(), clazz); Preconditions.checkNotNull(protobufBody); ChannelListenerWithCoordinationId futureListener = queue.get(listener, clazz, connection); OutboundRpcMessage m = new OutboundRpcMessage( RpcMode.REQUEST, rpcType, futureListener.getCoordinationId(), protobufBody, dataBodies); ChannelFuture channelFuture = connection.getChannel().writeAndFlush(m); channelFuture.addListener(futureListener); channelFuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); completed = true; } catch (Exception | AssertionError e) { listener.failed(new RpcException("Failure sending message.", e)); } finally { if (!completed) { if (pBuffer != null) { pBuffer.release(); } if (dataBodies != null) { for (ByteBuf b : dataBodies) { b.release(); } } } ; } }
@Override public void setException(Throwable t) { handler.failed(RpcException.mapException(t)); }
@SuppressWarnings("unchecked") @Override public void set(Object value) { assert clazz.isAssignableFrom(value.getClass()); handler.success((T) value); }