commercetools-sdk-java-v2 icon indicating copy to clipboard operation
commercetools-sdk-java-v2 copied to clipboard

Add way to specify executorservice to be used when returning commercetools SDK result

Open ChristianMattarVT opened this issue 3 years ago • 3 comments

Is your feature request related to a problem? Please describe. Modern async Java applications need control on which Threadpool which tasks are running. Currently, by default, all responses returning from commercetools SDK will continue running in a thread managed by a threadpool from the SDK.

Describe the solution you'd like Add a way (potentially via Middleware?) to automatically return from any call to commercetools SDK running on a thread from a configurable threadpool AKA Executor

Describe alternatives you've considered Alternatively, we could manually do:

ctApi.<omitted>.execute().thenApplyAsync(e -> e, myExecutorService); on each call to commercetools. However, this would clutter the code and can be easily forgotten. Same for any explicit decorator that would be needed.

ChristianMattarVT avatar Jun 23 '22 09:06 ChristianMattarVT

It's already possible to define the executor for the underlying HTTP client. E.g. for OkHttp:

ApiRootBuilder.of(new CtOkHttp4Client(new ForkJoinPool(), 64, 64))
   .defaultClient()

As some middlewares use also executors e.g. RetryMiddleware or QueueMiddleware you will have to configure there the executor too (available in the builder since 8.10.0).

ApiRootBuilder.of().withRetryMiddleware(new ForkJoinPool(), 3)

For the OAuthMiddleware it's a bit more complicated as the token provider has to be instantiated before

ExecutorService executorService = new ForkJoinPool();

ClientCredentials credentials = ClientCredentials.of()
        .withClientId(CommercetoolsTestUtils.getClientId())
        .withClientSecret(CommercetoolsTestUtils.getClientSecret())
        .build();

TokenSupplier supplier = new InMemoryTokenSupplier(
        executorService,
        new ClientCredentialsTokenSupplier(
                executorService,
                credentials.getClientId(),
                credentials.getClientSecret(),
                credentials.getScopes(),
                tokenEndpoint,
                HttpClientSupplier.of().get()
        )
);

ApiRootBuilder.of().defaultClient(apiEndpoint).withOAuthMiddleware(
        OAuthMiddleware.of(
                executorService,
                new OAuthHandler(supplier)
        )
);

We will still investigate how to simplify this or use a centrally defined executor.

jenschude avatar Jun 23 '22 10:06 jenschude

Besides this you could always add a middleware specifying the executor:

ApiRootBuilder.of().addMiddleware((request, next) -> next.apply(request).thenApplyAsync(Function.identity(), executorService));

jenschude avatar Jun 23 '22 10:06 jenschude

FYI: In the more recent versions the Client & ApiRootBuilders have methods which allow to specify the ExecutorService to be used for each of the middlewares and handlers.

Still checking if a central defined executor may be useful

jenschude avatar Oct 24 '22 09:10 jenschude