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));
}
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);
});
}
Aggregations