use of io.servicetalk.transport.api.DefaultExecutionContext in project servicetalk by apple.
the class DefaultNettyConnection method initChannel.
/**
* Given a {@link Channel} this will initialize the {@link ChannelPipeline} and create a
* {@link DefaultNettyConnection}. The resulting single will complete after the TLS handshake has completed
* (if applicable) or otherwise after the channel is active and ready to use.
* @param channel A newly created {@link Channel}.
* @param allocator The {@link BufferAllocator} to use for the {@link DefaultNettyConnection}.
* @param executor The {@link Executor} to use for the {@link DefaultNettyConnection}.
* @param ioExecutor The {@link IoExecutor} to use for the {@link DefaultNettyConnection}.
* @param closeHandler Manages the half closure of the {@link DefaultNettyConnection}.
* @param flushStrategy Manages flushing of data for the {@link DefaultNettyConnection}.
* @param idleTimeoutMs Value for {@link ServiceTalkSocketOptions#IDLE_TIMEOUT IDLE_TIMEOUT} socket option.
* @param initializer Synchronously initializes the pipeline upon subscribe.
* @param executionStrategy {@link ExecutionStrategy} to use for this connection.
* @param protocol {@link Protocol} for the returned {@link DefaultNettyConnection}.
* @param observer {@link ConnectionObserver} to report network events.
* @param isClient tells if this {@link Channel} is for the client.
* @param shouldWait predicate that tells when request payload body should wait for continuation signal.
* @param <Read> Type of objects read from the {@link NettyConnection}.
* @param <Write> Type of objects written to the {@link NettyConnection}.
* @return A {@link Single} that completes with a {@link DefaultNettyConnection} after the channel is activated and
* ready to use.
*/
public static <Read, Write> Single<DefaultNettyConnection<Read, Write>> initChannel(Channel channel, BufferAllocator allocator, Executor executor, @Nullable IoExecutor ioExecutor, CloseHandler closeHandler, FlushStrategy flushStrategy, @Nullable Long idleTimeoutMs, ChannelInitializer initializer, ExecutionStrategy executionStrategy, Protocol protocol, ConnectionObserver observer, boolean isClient, Predicate<Object> shouldWait) {
return new SubscribableSingle<DefaultNettyConnection<Read, Write>>() {
@Override
protected void handleSubscribe(final SingleSource.Subscriber<? super DefaultNettyConnection<Read, Write>> subscriber) {
final NettyToStChannelInboundHandler<Read, Write> nettyInboundHandler;
final DelayedCancellable delayedCancellable;
try {
delayedCancellable = new DelayedCancellable();
boolean supportsIoThread = null != ioExecutor && ioExecutor.isIoThreadSupported();
DefaultExecutionContext<?> executionContext = new DefaultExecutionContext<>(allocator, fromNettyEventLoop(channel.eventLoop(), supportsIoThread), executor, executionStrategy);
DefaultNettyConnection<Read, Write> connection = new DefaultNettyConnection<>(channel, executionContext, closeHandler, flushStrategy, idleTimeoutMs, protocol, null, null, NoopDataObserver.INSTANCE, isClient, shouldWait, identity());
channel.attr(CHANNEL_CLOSEABLE_KEY).set(connection);
// We need the NettyToStChannelInboundHandler to be last in the pipeline. We accomplish that by
// calling the ChannelInitializer before we do addLast for the NettyToStChannelInboundHandler.
// This could mean if there are any synchronous events generated via ChannelInitializer handlers
// that NettyToStChannelInboundHandler will not see them. This is currently not an issue and would
// require some pipeline modifications if we wanted to insert NettyToStChannelInboundHandler first,
// but not allow any other handlers to be after it.
initializer.init(channel);
ChannelPipeline pipeline = connection.channel().pipeline();
nettyInboundHandler = new NettyToStChannelInboundHandler<>(connection, subscriber, delayedCancellable, NettyPipelineSslUtils.isSslEnabled(pipeline), observer);
} catch (Throwable cause) {
close(channel, cause);
deliverErrorFromSource(subscriber, cause);
return;
}
subscriber.onSubscribe(delayedCancellable);
// We have to add to the pipeline AFTER we call onSubscribe, because adding to the pipeline may invoke
// callbacks that interact with the subscriber.
channel.pipeline().addLast(nettyInboundHandler);
}
};
}
Aggregations