Search in sources :

Example 1 with DefaultExecutionContext

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);
        }
    };
}
Also used : DefaultExecutionContext(io.servicetalk.transport.api.DefaultExecutionContext) SubscribableSingle(io.servicetalk.concurrent.api.internal.SubscribableSingle) DelayedCancellable(io.servicetalk.concurrent.internal.DelayedCancellable) ChannelPipeline(io.netty.channel.ChannelPipeline) Subscriber(io.servicetalk.concurrent.CompletableSource.Subscriber)

Aggregations

ChannelPipeline (io.netty.channel.ChannelPipeline)1 Subscriber (io.servicetalk.concurrent.CompletableSource.Subscriber)1 SubscribableSingle (io.servicetalk.concurrent.api.internal.SubscribableSingle)1 DelayedCancellable (io.servicetalk.concurrent.internal.DelayedCancellable)1 DefaultExecutionContext (io.servicetalk.transport.api.DefaultExecutionContext)1