Skip to content

Conversation

@yhzdys
Copy link
Contributor

@yhzdys yhzdys commented Jan 16, 2026

Add ExchangeIdGenerator interface to allow users to customize exchange ID generation in HTTP clients.

This change introduces the ExchangeIdGenerator interface, which enables users to provide custom strategies for generating exchange identifiers. This is particularly useful in distributed systems where custom tracing and correlation mechanisms are required.

@yhzdys yhzdys force-pushed the master branch 2 times, most recently from d6326b4 to 5069736 Compare January 17, 2026 03:55
@yhzdys yhzdys changed the title Allow pre-set custom ExchangeId in HttpClientContext before request Add custom ExchangeId generator support Jan 17, 2026
ok2c
ok2c approved these changes Jan 17, 2026
@rschmitt
Copy link
Contributor

Just for curiosity, how do you plan to use this?

@yhzdys
Copy link
Contributor Author

yhzdys commented Jan 18, 2026

Just for curiosity, how do you plan to use this?

@rschmitt Thank you for the feedback. I understand your curiosity.
In my initial PR changes, I planned to implement custom exchangeId by setting it in advance, like this:

// My custom ExchangeId
final String exchangeId = "myexec-001";

final CloseableHttpAsyncClient client = HttpAsyncClientBuilder.create().build();
final SimpleHttpRequest request = new SimpleHttpRequest(Method.GET, URI.create("http://somehost"));
final HttpClientContext context = HttpClientContext.create();
// Sets my custom ExchangeId
context.setExchangeId(exchangeId);
client.execute(request, context, null);

Of course, although this approach is simple to use, it is not appropriate.


With the current changes, I will pass the custom exchangeId through a ThreadLocal, as shown below:
Although there is some performance overhead, it is still acceptable for my use case.

final class MyRequestProducer implements AsyncRequestProducer {

    private final String myExchangeId;

    private final HttpRequest httpRequest;
    private final AsyncEntityProducer entityProducer;

    @Override
    public void sendRequest(final RequestChannel channel, final HttpContext context) throws HttpException, IOException {
        // Sets my custom ExchangeId
        MyExchangeIdGenerator.set(this.myExchangeId);
        channel.sendRequest(this.httpRequest, this.entityProducer, context);
    }
}

final class MyExchangeIdGenerator implements Supplier<String> {

    static final ThreadLocal<String> THREADLOCAL = new ThreadLocal<>();

    static void set(final String exchangeId) {
        THREADLOCAL.set(exchangeId);
    }

    @Override
    public String get() {
        final String myExchangeId = THREADLOCAL.get();
        if (myExchangeId == null) {
            return ExecSupport.getNextExchangeId();
        }
        THREADLOCAL.remove();
        return myExchangeId;
    }
}
final String exchangeId = "myexec-001";
final Supplier<String> exchangeIdGenerator = new MyExchangeIdGenerator();

final CloseableHttpAsyncClient client = HttpAsyncClientBuilder.create().setExchangeIdGenerator(exchangeIdGenerator).build();
final SimpleHttpRequest request = new SimpleHttpRequest(Method.GET, URI.create("http://somehost"));
final MyRequestProducer producer = new MyRequestProducer(exchangeId, request, null);
client.execute(producer, null, null);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants