title: How to use Project Reactor's Scheduler with Executor based libraries?
body: <p>Project Reactor provides a great way to define which thread pool for code to run on, by defining a <code>Scheduler</code>. It also provides a bridge to libraries that use <code>CompletableFuture</code>'s though <code>Mono.fromFuture(..)</code>.</p>
  
  <p>AWS's <a href="https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/welcome.html" rel="noreferrer">async client for DyanmoDB</a>, executes the <code>CompletableFuture</code>'s it returns from the API calls on a <code>java.util.concurrent.Executor</code>. By default, it creates an <code>Executor</code> backed by a thread pool it also creates. The result is that even streams with a defined <code>Scheduler</code> like <code>Mono.fromFuture(..).subscribeOn(Schedulers.boundedElastic())</code> execute on a thread from the pool the library creates instead of one from the <code>Schedulers.boundedElastic()</code>. So we're seeing thread names like <code>sdk-async-response-0-2</code>, instead of names like <code>boundedElastic-1</code>.</p>
  
  <p>Fortunately, the library allows us to provide our own <code>Executor</code> as <a href="https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/basics-async.html#advanced-operations" rel="noreferrer">shown here</a>, so my question is:</p>
  
  <blockquote>
    <p>How do you build an <code>Executor</code> that uses a thread from the <code>Scheduler</code> <em>defined on that part of the stream</em> at runtime?</p>
  </blockquote>
  
  <p><em>Use Case</em></p>
  
  <p>We have a repository class, that has a <code>findById</code> method and we need the caller to be able to control which <code>Scheduler</code> to run on, because it's used in these distinctly different contexts:</p>
  
  <ol>
  <li>API responses that are run on the <code>Schedulers.boundedElastic()</code> scheduler.</li>
  <li>Handling Kafka messages that are executed in order, on a thread per partition, from a defined scheduler as shown in the <a href="https://projectreactor.io/docs/kafka/release/reference/#concurrent-ordered" rel="noreferrer">Reactor Kafka docs</a>.</li>
  </ol>
  
  <p><em>Attempts</em></p>
  
  <p>We've tried defining an <code>Executor</code> using both <code>Schedulers.immediate()</code> and <code>Runnable::run</code> as shown here, but both result in executing on the Netty event loop thread (example name: <code>aws-java-sdk-NettyEventLoop-0-2</code>), not a thread from the defined <code>Scheduler</code>.</p>
  
  <pre><code>DynamoDbAsyncClient.builder()
      .asyncConfiguration(builder -&gt; builder.advancedOption(
          SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR,
          runnable -&gt; Schedulers.immediate().schedule(runnable)
      ))
      .build();
  </code></pre>
  
  <pre><code>DynamoDbAsyncClient.builder()
      .asyncConfiguration(builder -&gt; builder.advancedOption(
          SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR,
          Runnable::run
      ))
      .build();
  </code></pre>