Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I want to propagate TraceId to all places where parallelStream() and CustomForkJoinPool is used. #138

Open
petercheon opened this issue Jun 28, 2023 · 7 comments
Labels
feedback-reminder question Further information is requested

Comments

@petercheon
Copy link

I would like to know how to propagate the TraceId within the Java Stream API in Spring Cloud Sleuth.

In the code below, the trace_id is not propagated, and each client ends up having an individual TraceId.

TestForkJoinPool testForkJoinPool = new TestForkJoinPool(10);
Span span = tracer.nextSpan(tracer.currentSpan());

testForkJoinPool.submit(() -> {
    try (SpanInScope ignored = tracer.withSpan(span)) {
        IntStream.range(1, 20).parallel().forEach(idx -> {
            httpClient.get(1000L);
        });
    } finally {
        span.end();
    }
}).get();

However, if we modify the above code as shown below, the TraceId is propagated.

TestForkJoinPool testForkJoinPool = new TestForkJoinPool(10);
Span span = tracer.nextSpan(tracer.currentSpan());

testForkJoinPool.submit(() -> {
    IntStream.range(1, 20).parallel().forEach(idx -> {
        try (SpanInScope ignored = tracer.withSpan(span)) {
            httpClient.get(1000L);
        } finally {
            span.end();
        }
    });
}).get();

Unfortunately, applying SpanInScope to all existing Stream API code as mentioned above has its limitations. Is there a way to inject SpanInScope with minimal modifications to the existing Stream API code?

Thank you.

@jonatan-ivanov
Copy link
Member

See connected issue in Sleuth: spring-cloud/spring-cloud-sleuth#2297
To me this seems like a new feature instrumenting the Fork Join API (or find a way to inject an executor/completion service).

@marcingrzejszczak marcingrzejszczak transferred this issue from micrometer-metrics/tracing Aug 22, 2023
@marcingrzejszczak marcingrzejszczak added the enhancement A general enhancement label Aug 22, 2023
@chemicL
Copy link
Collaborator

chemicL commented Nov 8, 2023

The classes from the tracing domain make it a bit hard for me to understand the suggestion. Consider providing an example with only classes from the JDK and the context-propagation library so that it is more comprehensible.

I'm skeptical we can do anything for the ForkJoinPool.commonPool(), which is implicitly used by the Stream API and there is no option to configure a different implementation. I suppose manual ContextSnapshot capturing and restoration is what's available at the moment.

If you have some suggestions, please update the issue.

@chemicL chemicL added question Further information is requested and removed enhancement A general enhancement labels Nov 8, 2023
Copy link

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@cah-renan-ferreira
Copy link

Any news on that?
Is is possible to do that manually at least?

@marcingrzejszczak
Copy link
Contributor

Have you tried using ContextExecutorService.wrap(ForkJoinPool.commonPool()) ?

@cah-renan-ferreira
Copy link

Not really.
Should I do it everytime before calling a parallelStream or just once on app startup?
Thanks for the support.

@marcingrzejszczak
Copy link
Contributor

The problem is that this will return the ExecutorService interface that will simply wrap the common pool. I don't think you'll be happy with the result cause you want to use the ForkJoinPool API 😬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feedback-reminder question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants