Search in sources :

Example 16 with CompositeCloseable

use of io.servicetalk.concurrent.api.CompositeCloseable in project servicetalk by apple.

the class PredicateRouterOffloadingTest method tearDown.

@AfterEach
void tearDown() throws Exception {
    if (client != null) {
        client.close();
    }
    final CompositeCloseable closeable = newCompositeCloseable();
    if (context != null) {
        closeable.append(context);
    }
    closeable.closeAsync().toFuture().get();
}
Also used : CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable) AsyncCloseables.newCompositeCloseable(io.servicetalk.concurrent.api.AsyncCloseables.newCompositeCloseable) AfterEach(org.junit.jupiter.api.AfterEach)

Example 17 with CompositeCloseable

use of io.servicetalk.concurrent.api.CompositeCloseable in project servicetalk by apple.

the class GatewayServer method main.

/**
 * Starts this server.
 *
 * @param args Program arguments, none supported yet.
 * @throws Exception If the server could not be started.
 */
public static void main(String[] args) throws Exception {
    // Create an AutoCloseable representing all resources used in this example.
    try (CompositeCloseable resources = newCompositeCloseable()) {
        // Shared IoExecutor for the application.
        IoExecutor ioExecutor = resources.prepend(createIoExecutor());
        // Create clients for the different backends we are going to use in the gateway.
        StreamingHttpClient recommendationsClient = newClient(ioExecutor, RECOMMENDATIONS_BACKEND_ADDRESS, resources, "recommendations backend");
        HttpClient metadataClient = newClient(ioExecutor, METADATA_BACKEND_ADDRESS, resources, "metadata backend").asClient();
        HttpClient userClient = newClient(ioExecutor, USER_BACKEND_ADDRESS, resources, "user backend").asClient();
        HttpClient ratingsClient = newClient(ioExecutor, RATINGS_BACKEND_ADDRESS, resources, "ratings backend").asClient();
        // Gateway supports different endpoints for blocking, streaming or aggregated implementations.
        // We create a router to express these endpoints.
        HttpPredicateRouterBuilder routerBuilder = new HttpPredicateRouterBuilder();
        final StreamingHttpService gatewayService = routerBuilder.whenPathStartsWith("/recommendations/stream").thenRouteTo(new StreamingGatewayService(recommendationsClient, metadataClient, ratingsClient, userClient)).whenPathStartsWith("/recommendations/aggregated").thenRouteTo(new GatewayService(recommendationsClient.asClient(), metadataClient, ratingsClient, userClient)).whenPathStartsWith("/recommendations/blocking").thenRouteTo(new BlockingGatewayService(recommendationsClient.asBlockingClient(), metadataClient.asBlockingClient(), ratingsClient.asBlockingClient(), userClient.asBlockingClient())).buildStreaming();
        // Create configurable starter for HTTP server.
        // Starting the server will start listening for incoming client requests.
        ServerContext serverContext = HttpServers.forPort(8080).ioExecutor(ioExecutor).appendServiceFilter(new BadResponseHandlingServiceFilter()).listenStreamingAndAwait(gatewayService);
        LOGGER.info("Listening on {}", serverContext.listenAddress());
        // Blocks and awaits shutdown of the server this ServerContext represents.
        serverContext.awaitShutdown();
    }
}
Also used : StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) IoExecutor(io.servicetalk.transport.api.IoExecutor) NettyIoExecutors.createIoExecutor(io.servicetalk.transport.netty.NettyIoExecutors.createIoExecutor) ServerContext(io.servicetalk.transport.api.ServerContext) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) HttpClient(io.servicetalk.http.api.HttpClient) CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable) AsyncCloseables.newCompositeCloseable(io.servicetalk.concurrent.api.AsyncCloseables.newCompositeCloseable) StreamingHttpService(io.servicetalk.http.api.StreamingHttpService) HttpPredicateRouterBuilder(io.servicetalk.http.router.predicate.HttpPredicateRouterBuilder)

Example 18 with CompositeCloseable

use of io.servicetalk.concurrent.api.CompositeCloseable in project servicetalk by apple.

the class NoOffloadsStrategyTest method tearDown.

@AfterEach
void tearDown() throws Exception {
    CompositeCloseable closeables = newCompositeCloseable();
    if (client != null) {
        client.close();
    }
    if (context != null) {
        closeables.append(context);
    }
    closeables.append(ioExecutor).closeAsync().toFuture().get();
}
Also used : CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable) AsyncCloseables.newCompositeCloseable(io.servicetalk.concurrent.api.AsyncCloseables.newCompositeCloseable) AfterEach(org.junit.jupiter.api.AfterEach)

Example 19 with CompositeCloseable

use of io.servicetalk.concurrent.api.CompositeCloseable in project servicetalk by apple.

the class DefaultSingleAddressHttpClientBuilder method buildStreaming.

private static <U, R> StreamingHttpClient buildStreaming(final HttpClientBuildContext<U, R> ctx) {
    final ReadOnlyHttpClientConfig roConfig = ctx.httpConfig().asReadOnly();
    final HttpExecutionContext executionContext = ctx.builder.executionContextBuilder.build();
    if (roConfig.h2Config() != null && roConfig.hasProxy()) {
        throw new IllegalStateException("Proxying is not yet supported with HTTP/2");
    }
    // Track resources that potentially need to be closed when an exception is thrown during buildStreaming
    final CompositeCloseable closeOnException = newCompositeCloseable();
    try {
        final Publisher<? extends Collection<? extends ServiceDiscovererEvent<R>>> sdEvents = ctx.serviceDiscoverer(executionContext).discover(ctx.address());
        ConnectionFactoryFilter<R, FilterableStreamingHttpConnection> connectionFactoryFilter = ctx.builder.connectionFactoryFilter;
        ExecutionStrategy connectionFactoryStrategy = ctx.builder.strategyComputation.buildForConnectionFactory();
        final SslContext sslContext = roConfig.tcpConfig().sslContext();
        if (roConfig.hasProxy() && sslContext != null) {
            assert roConfig.connectAddress() != null;
            ConnectionFactoryFilter<R, FilterableStreamingHttpConnection> proxy = new ProxyConnectConnectionFactoryFilter<>(roConfig.connectAddress());
            connectionFactoryFilter = proxy.append(connectionFactoryFilter);
            connectionFactoryStrategy = connectionFactoryStrategy.merge(proxy.requiredOffloads());
        }
        final HttpExecutionStrategy executionStrategy = executionContext.executionStrategy();
        // closed by the LoadBalancer
        final ConnectionFactory<R, LoadBalancedStreamingHttpConnection> connectionFactory;
        final StreamingHttpRequestResponseFactory reqRespFactory = defaultReqRespFactory(roConfig, executionContext.bufferAllocator());
        if (roConfig.isH2PriorKnowledge()) {
            H2ProtocolConfig h2Config = roConfig.h2Config();
            assert h2Config != null;
            connectionFactory = new H2LBHttpConnectionFactory<>(roConfig, executionContext, ctx.builder.connectionFilterFactory, reqRespFactory, connectionFactoryStrategy, connectionFactoryFilter, ctx.builder.loadBalancerFactory::toLoadBalancedConnection);
        } else if (roConfig.tcpConfig().preferredAlpnProtocol() != null) {
            H1ProtocolConfig h1Config = roConfig.h1Config();
            H2ProtocolConfig h2Config = roConfig.h2Config();
            connectionFactory = new AlpnLBHttpConnectionFactory<>(roConfig, executionContext, ctx.builder.connectionFilterFactory, new AlpnReqRespFactoryFunc(executionContext.bufferAllocator(), h1Config == null ? null : h1Config.headersFactory(), h2Config == null ? null : h2Config.headersFactory()), connectionFactoryStrategy, connectionFactoryFilter, ctx.builder.loadBalancerFactory::toLoadBalancedConnection);
        } else {
            H1ProtocolConfig h1Config = roConfig.h1Config();
            assert h1Config != null;
            connectionFactory = new PipelinedLBHttpConnectionFactory<>(roConfig, executionContext, ctx.builder.connectionFilterFactory, reqRespFactory, connectionFactoryStrategy, connectionFactoryFilter, ctx.builder.loadBalancerFactory::toLoadBalancedConnection);
        }
        final LoadBalancer<LoadBalancedStreamingHttpConnection> lb = closeOnException.prepend(ctx.builder.loadBalancerFactory.newLoadBalancer(targetAddress(ctx), sdEvents, connectionFactory));
        ContextAwareStreamingHttpClientFilterFactory currClientFilterFactory = ctx.builder.clientFilterFactory;
        if (roConfig.hasProxy() && sslContext == null) {
            // If we're talking to a proxy over http (not https), rewrite the request-target to absolute-form, as
            // specified by the RFC: https://tools.ietf.org/html/rfc7230#section-5.3.2
            currClientFilterFactory = appendFilter(currClientFilterFactory, ctx.builder.proxyAbsoluteAddressFilterFactory());
        }
        if (ctx.builder.addHostHeaderFallbackFilter) {
            currClientFilterFactory = appendFilter(currClientFilterFactory, new HostHeaderHttpRequesterFilter(ctx.builder.hostToCharSequenceFunction.apply(ctx.builder.address)));
        }
        FilterableStreamingHttpClient lbClient = closeOnException.prepend(new LoadBalancedStreamingHttpClient(executionContext, lb, reqRespFactory));
        if (ctx.builder.retryingHttpRequesterFilter == null) {
            ctx.builder.retryingHttpRequesterFilter = DEFAULT_AUTO_RETRIES;
            currClientFilterFactory = appendFilter(currClientFilterFactory, ctx.builder.retryingHttpRequesterFilter);
        }
        HttpExecutionStrategy computedStrategy = ctx.builder.strategyComputation.buildForClient(executionStrategy);
        LOGGER.debug("Client for {} created with base strategy {} → computed strategy {}", targetAddress(ctx), executionStrategy, computedStrategy);
        return new FilterableClientToClient(currClientFilterFactory != null ? currClientFilterFactory.create(lbClient, lb.eventStream(), ctx.sdStatus) : lbClient, computedStrategy);
    } catch (final Throwable t) {
        closeOnException.closeAsync().subscribe();
        throw t;
    }
}
Also used : CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable) AsyncCloseables.newCompositeCloseable(io.servicetalk.concurrent.api.AsyncCloseables.newCompositeCloseable) FilterableStreamingHttpClient(io.servicetalk.http.api.FilterableStreamingHttpClient) StreamingHttpRequestResponseFactory(io.servicetalk.http.api.StreamingHttpRequestResponseFactory) DefaultStreamingHttpRequestResponseFactory(io.servicetalk.http.api.DefaultStreamingHttpRequestResponseFactory) HttpExecutionStrategy(io.servicetalk.http.api.HttpExecutionStrategy) ExecutionStrategy(io.servicetalk.transport.api.ExecutionStrategy) HttpExecutionStrategy(io.servicetalk.http.api.HttpExecutionStrategy) SslContext(io.netty.handler.ssl.SslContext) FilterableStreamingHttpConnection(io.servicetalk.http.api.FilterableStreamingHttpConnection) HttpExecutionContext(io.servicetalk.http.api.HttpExecutionContext)

Example 20 with CompositeCloseable

use of io.servicetalk.concurrent.api.CompositeCloseable in project servicetalk by apple.

the class ExecutionStrategyServer method main.

public static void main(String... args) throws Exception {
    int port = 8080;
    try (CompositeCloseable closeEverything = AsyncCloseables.newCompositeCloseable()) {
        Executor executor = Executors.newCachedThreadExecutor(new DefaultThreadFactory("custom"));
        // executor will be closed last, servers are prepended before executor.
        closeEverything.append(executor);
        // Default server configuration.
        // -> route offloaded to global executor
        System.out.printf("\n%d : default server\n", port);
        ServerContext defaultServer = GrpcServers.forPort(port++).listenAndAwait((GreeterService) (ctx, request) -> getReplySingle(request, "default server"));
        closeEverything.prepend(defaultServer);
        // No offloads strategy specified on the server, async route does not override its strategy.
        // -> no offloading, route executed on IoExecutor
        System.out.printf("\n%d : no offloading server, async route\n", port);
        ServerContext asyncServer = GrpcServers.forPort(port++).initializeHttp(init -> init.executionStrategy(offloadNever())).listenAndAwait((GreeterService) (ctx, request) -> getReplySingle(request, "no offloading server, async route"));
        closeEverything.prepend(asyncServer);
        // No offloads strategy specified on the server, blocking route does not override its strategy.
        // -> no offloading, route executed on IoExecutor
        System.out.printf("\n%d : no offloading server, blocking route\n", port);
        ServerContext blockingServer = GrpcServers.forPort(port++).initializeHttp(init -> init.executionStrategy(offloadNever())).listenAndAwait((Greeter.BlockingGreeterService) (ctx, request) -> getReply(request, "no offloading server, blocking route"));
        closeEverything.prepend(blockingServer);
        // No offloads strategy specified on the server, route overrides it to use the default strategy.
        // -> route offloaded to global executor
        System.out.printf("\n%d : no offloading server, default offloading for the route\n", port);
        ServerContext noOffloadsServerRouteOffloads = GrpcServers.forPort(port++).initializeHttp(init -> init.executionStrategy(offloadNever())).listenAndAwait(new Greeter.ServiceFactory.Builder().sayHello(defaultStrategy(), (ctx, request) -> getReplySingle(request, "no offloading server, default offloading for the route")).build());
        closeEverything.prepend(noOffloadsServerRouteOffloads);
        // No offloads strategy specified on the server, route overrides it to use a custom strategy.
        // -> route offloaded to global executor
        System.out.printf("\n%d: no offloading server, custom offloading for the route\n", port);
        ServerContext noOffloadsServerRouteOffloadCustom = GrpcServers.forPort(port++).initializeHttp(init -> init.executionStrategy(offloadNever())).listenAndAwait(new Greeter.ServiceFactory.Builder().sayHello(CUSTOM_STRATEGY, (ctx, request) -> getReplySingle(request, "no offloading server, custom offloading for the route")).build());
        closeEverything.prepend(noOffloadsServerRouteOffloadCustom);
        // Server with a default strategy but a custom executor, route does not override its strategy.
        // -> route offloaded to custom executor
        System.out.printf("\n%d : server with a default offloading and a custom executor\n", port);
        ServerContext customExecutorServer = GrpcServers.forPort(port++).initializeHttp(init -> init.executor(executor)).listenAndAwait((GreeterService) (ctx, request) -> getReplySingle(request, "server with a default offloading and a custom executor"));
        closeEverything.prepend(customExecutorServer);
        // Server has default configuration, route attempts to use no offloads strategy, which is ignored.
        // (Too late, already offloaded at the server level)
        // -> route offloaded to global executor
        System.out.printf("\n%d : default server, no offloading route\n", port);
        ServerContext noOffloadsRoute = GrpcServers.forPort(port++).listenAndAwait(new Greeter.ServiceFactory.Builder().sayHello(offloadNever(), (ctx, request) -> getReplySingle(request, "default server, no offloading route")).build());
        closeEverything.prepend(noOffloadsRoute);
        // Server has default configuration, route attempts to use no offloads strategy via annotation, which is
        // ignored. (Too late, already offloaded at the server level)
        // -> route offloaded to global executor
        System.out.printf("\n%d : default server, no offloading (annotation) route\n", port);
        ServerContext noOffloadsAnnotation = GrpcServers.forPort(port++).listenAndAwait(new NoOffloadsGreeterService());
        closeEverything.prepend(noOffloadsAnnotation);
        // No offloads strategy specified on the server, route overrides it to also use no offloads strategy,
        // which is redundant.
        // -> no offloading, route executed on IoExecutor
        System.out.printf("\n%d : no offloading server, no offloading route\n", port);
        ServerContext noOffloadsServerRoute = GrpcServers.forPort(port++).initializeHttp(init -> init.executionStrategy(offloadNever())).listenAndAwait(new Greeter.ServiceFactory.Builder().sayHello(offloadNever(), (ctx, request) -> getReplySingle(request, "no offloading server, no offloading route")).build());
        closeEverything.prepend(noOffloadsServerRoute);
        noOffloadsServerRoute.awaitShutdown();
    }
}
Also used : DefaultThreadFactory(io.servicetalk.concurrent.api.DefaultThreadFactory) HelloReply(io.grpc.examples.strategies.HelloReply) ServerContext(io.servicetalk.transport.api.ServerContext) GrpcExecutionStrategies.offloadNever(io.servicetalk.grpc.api.GrpcExecutionStrategies.offloadNever) Single(io.servicetalk.concurrent.api.Single) NoOffloadsRouteExecutionStrategy(io.servicetalk.router.api.NoOffloadsRouteExecutionStrategy) CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable) Greeter(io.grpc.examples.strategies.Greeter) GrpcServiceContext(io.servicetalk.grpc.api.GrpcServiceContext) GreeterService(io.grpc.examples.strategies.Greeter.GreeterService) GrpcExecutionStrategies.defaultStrategy(io.servicetalk.grpc.api.GrpcExecutionStrategies.defaultStrategy) GrpcExecutionStrategies(io.servicetalk.grpc.api.GrpcExecutionStrategies) Single.succeeded(io.servicetalk.concurrent.api.Single.succeeded) GrpcExecutionStrategy(io.servicetalk.grpc.api.GrpcExecutionStrategy) Executor(io.servicetalk.concurrent.api.Executor) Executors(io.servicetalk.concurrent.api.Executors) AsyncCloseables(io.servicetalk.concurrent.api.AsyncCloseables) DefaultThreadFactory(io.servicetalk.concurrent.api.DefaultThreadFactory) GrpcServers(io.servicetalk.grpc.netty.GrpcServers) HelloRequest(io.grpc.examples.strategies.HelloRequest) Executor(io.servicetalk.concurrent.api.Executor) ServerContext(io.servicetalk.transport.api.ServerContext) Greeter(io.grpc.examples.strategies.Greeter) CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable)

Aggregations

CompositeCloseable (io.servicetalk.concurrent.api.CompositeCloseable)23 AsyncCloseables.newCompositeCloseable (io.servicetalk.concurrent.api.AsyncCloseables.newCompositeCloseable)16 AfterEach (org.junit.jupiter.api.AfterEach)10 ServerContext (io.servicetalk.transport.api.ServerContext)7 AsyncCloseables (io.servicetalk.concurrent.api.AsyncCloseables)3 Completable (io.servicetalk.concurrent.api.Completable)3 Single.succeeded (io.servicetalk.concurrent.api.Single.succeeded)3 HttpExecutionStrategies.defaultStrategy (io.servicetalk.http.api.HttpExecutionStrategies.defaultStrategy)3 StreamingHttpClient (io.servicetalk.http.api.StreamingHttpClient)3 StreamingHttpRequest (io.servicetalk.http.api.StreamingHttpRequest)3 StreamingHttpResponse (io.servicetalk.http.api.StreamingHttpResponse)3 StreamingHttpService (io.servicetalk.http.api.StreamingHttpService)3 AddressUtils.localAddress (io.servicetalk.transport.netty.internal.AddressUtils.localAddress)3 AddressUtils.serverHostAndPort (io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort)3 ExecutionContextExtension (io.servicetalk.transport.netty.internal.ExecutionContextExtension)3 Assertions.assertEquals (org.junit.jupiter.api.Assertions.assertEquals)3 Test (org.junit.jupiter.api.Test)3 RegisterExtension (org.junit.jupiter.api.extension.RegisterExtension)3 Channel (io.netty.channel.Channel)2 Buffer (io.servicetalk.buffer.api.Buffer)2