Search in sources :

Example 1 with InfluencerConnectionAcceptor

use of io.servicetalk.transport.netty.internal.InfluencerConnectionAcceptor in project servicetalk by apple.

the class DefaultHttpServerBuilder method listenForService.

/**
 * Starts this server and returns the {@link HttpServerContext} after the server has been successfully started.
 * <p>
 * If the underlying protocol (e.g. TCP) supports it this should result in a socket bind/listen on {@code address}.
 * <p>/p>
 * The execution path for a request will be offloaded from the IO thread as required to ensure safety. The
 * <dl>
 *     <dt>read side</dt>
 *     <dd>IO thread → request → non-offload filters → offload filters → raw service</dd>
 *     <dt>subscribe/request side</dt>
 *     <dd>IO thread → subscribe/request/cancel → non-offload filters → offload filters → raw service</dd>
 * </dl>
 *
 * @param rawService {@link StreamingHttpService} to use for the server.
 * @param strategy the {@link HttpExecutionStrategy} to use for the service.
 * @return A {@link Single} that completes when the server is successfully started or terminates with an error if
 * the server could not be started.
 */
private Single<HttpServerContext> listenForService(final StreamingHttpService rawService, final HttpExecutionStrategy strategy) {
    InfluencerConnectionAcceptor connectionAcceptor = connectionAcceptorFactory == null ? null : InfluencerConnectionAcceptor.withStrategy(connectionAcceptorFactory.create(ACCEPT_ALL), connectionAcceptorFactory.requiredOffloads());
    final StreamingHttpService filteredService;
    final HttpExecutionContext executionContext;
    if (noOffloadServiceFilters.isEmpty()) {
        filteredService = serviceFilters.isEmpty() ? rawService : buildService(serviceFilters.stream(), rawService);
        executionContext = buildExecutionContext(strategy);
    } else {
        Stream<StreamingHttpServiceFilterFactory> nonOffloadingFilters = noOffloadServiceFilters.stream();
        if (strategy.isRequestResponseOffloaded()) {
            executionContext = buildExecutionContext(REQRESP_OFFLOADS.missing(strategy));
            BooleanSupplier shouldOffload = executionContext.ioExecutor().shouldOffloadSupplier();
            // We are going to have to offload, even if just to the raw service
            OffloadingFilter offloadingFilter = new OffloadingFilter(strategy, buildFactory(serviceFilters), shouldOffload);
            nonOffloadingFilters = Stream.concat(nonOffloadingFilters, Stream.of(offloadingFilter));
        } else {
            // All the filters can be appended.
            nonOffloadingFilters = Stream.concat(nonOffloadingFilters, serviceFilters.stream());
            executionContext = buildExecutionContext(strategy);
        }
        filteredService = buildService(nonOffloadingFilters, rawService);
    }
    return doBind(executionContext, connectionAcceptor, filteredService).afterOnSuccess(serverContext -> LOGGER.debug("Server for address {} uses strategy {}", serverContext.listenAddress(), strategy));
}
Also used : HttpExecutionContext(io.servicetalk.http.api.HttpExecutionContext) InfluencerConnectionAcceptor(io.servicetalk.transport.netty.internal.InfluencerConnectionAcceptor) BlockingStreamingHttpService(io.servicetalk.http.api.BlockingStreamingHttpService) HttpApiConversions.toStreamingHttpService(io.servicetalk.http.api.HttpApiConversions.toStreamingHttpService) StreamingHttpService(io.servicetalk.http.api.StreamingHttpService) StreamingHttpServiceFilterFactory(io.servicetalk.http.api.StreamingHttpServiceFilterFactory) BooleanSupplier(java.util.function.BooleanSupplier)

Example 2 with InfluencerConnectionAcceptor

use of io.servicetalk.transport.netty.internal.InfluencerConnectionAcceptor in project servicetalk by apple.

the class DeferredServerChannelBinder method bind.

static Single<HttpServerContext> bind(final HttpExecutionContext executionContext, final ReadOnlyHttpServerConfig config, final SocketAddress listenAddress, @Nullable final InfluencerConnectionAcceptor connectionAcceptor, final StreamingHttpService service, final boolean drainRequestPayloadBody, final boolean sniOnly) {
    final ReadOnlyTcpServerConfig tcpConfig = config.tcpConfig();
    assert tcpConfig.sslContext() != null;
    final BiFunction<Channel, ConnectionObserver, Single<NettyConnectionContext>> channelInit = sniOnly ? (channel, connectionObserver) -> sniInitChannel(listenAddress, channel, config, executionContext, service, drainRequestPayloadBody, connectionObserver) : (channel, connectionObserver) -> alpnInitChannel(listenAddress, channel, config, executionContext, service, drainRequestPayloadBody, connectionObserver);
    // In case ALPN negotiates h2, h2 connection MUST enable auto read for its Channel.
    return TcpServerBinder.bind(listenAddress, tcpConfig, false, executionContext, connectionAcceptor, channelInit, serverConnection -> {
        // Start processing requests on http/1.1 connection:
        if (serverConnection instanceof NettyHttpServerConnection) {
            ((NettyHttpServerConnection) serverConnection).process(true);
        }
    // Nothing to do otherwise as h2 uses auto read on the parent channel
    }).map(delegate -> {
        LOGGER.debug("Started HTTP server with ALPN for address {}", delegate.listenAddress());
        // The ServerContext returned by TcpServerBinder takes care of closing the connectionAcceptor.
        return new NettyHttpServer.NettyHttpServerContext(delegate, service, executionContext);
    });
}
Also used : ConnectionObserver(io.servicetalk.transport.api.ConnectionObserver) NettyHttpServerConnection(io.servicetalk.http.netty.NettyHttpServer.NettyHttpServerConnection) Logger(org.slf4j.Logger) SocketAddress(java.net.SocketAddress) HTTP_2(io.servicetalk.http.netty.AlpnIds.HTTP_2) Single(io.servicetalk.concurrent.api.Single) BiFunction(java.util.function.BiFunction) LoggerFactory(org.slf4j.LoggerFactory) TcpServerChannelInitializer(io.servicetalk.tcp.netty.internal.TcpServerChannelInitializer) InfluencerConnectionAcceptor(io.servicetalk.transport.netty.internal.InfluencerConnectionAcceptor) TcpServerBinder(io.servicetalk.tcp.netty.internal.TcpServerBinder) ReadOnlyTcpServerConfig(io.servicetalk.tcp.netty.internal.ReadOnlyTcpServerConfig) Channel(io.netty.channel.Channel) ConnectionObserver(io.servicetalk.transport.api.ConnectionObserver) StreamingHttpService(io.servicetalk.http.api.StreamingHttpService) HTTP_1_1(io.servicetalk.http.netty.AlpnIds.HTTP_1_1) HttpServerContext(io.servicetalk.http.api.HttpServerContext) NoopChannelInitializer(io.servicetalk.http.netty.AlpnChannelSingle.NoopChannelInitializer) Single.failed(io.servicetalk.concurrent.api.Single.failed) NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) Nullable(javax.annotation.Nullable) HttpExecutionContext(io.servicetalk.http.api.HttpExecutionContext) NettyHttpServerConnection(io.servicetalk.http.netty.NettyHttpServer.NettyHttpServerConnection) Single(io.servicetalk.concurrent.api.Single) Channel(io.netty.channel.Channel) ReadOnlyTcpServerConfig(io.servicetalk.tcp.netty.internal.ReadOnlyTcpServerConfig)

Aggregations

HttpExecutionContext (io.servicetalk.http.api.HttpExecutionContext)2 StreamingHttpService (io.servicetalk.http.api.StreamingHttpService)2 InfluencerConnectionAcceptor (io.servicetalk.transport.netty.internal.InfluencerConnectionAcceptor)2 Channel (io.netty.channel.Channel)1 Single (io.servicetalk.concurrent.api.Single)1 Single.failed (io.servicetalk.concurrent.api.Single.failed)1 BlockingStreamingHttpService (io.servicetalk.http.api.BlockingStreamingHttpService)1 HttpApiConversions.toStreamingHttpService (io.servicetalk.http.api.HttpApiConversions.toStreamingHttpService)1 HttpServerContext (io.servicetalk.http.api.HttpServerContext)1 StreamingHttpServiceFilterFactory (io.servicetalk.http.api.StreamingHttpServiceFilterFactory)1 NoopChannelInitializer (io.servicetalk.http.netty.AlpnChannelSingle.NoopChannelInitializer)1 HTTP_1_1 (io.servicetalk.http.netty.AlpnIds.HTTP_1_1)1 HTTP_2 (io.servicetalk.http.netty.AlpnIds.HTTP_2)1 NettyHttpServerConnection (io.servicetalk.http.netty.NettyHttpServer.NettyHttpServerConnection)1 ReadOnlyTcpServerConfig (io.servicetalk.tcp.netty.internal.ReadOnlyTcpServerConfig)1 TcpServerBinder (io.servicetalk.tcp.netty.internal.TcpServerBinder)1 TcpServerChannelInitializer (io.servicetalk.tcp.netty.internal.TcpServerChannelInitializer)1 ConnectionObserver (io.servicetalk.transport.api.ConnectionObserver)1 NettyConnectionContext (io.servicetalk.transport.netty.internal.NettyConnectionContext)1 SocketAddress (java.net.SocketAddress)1