Skip to content

Commit

Permalink
Fix broken span ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
Mateusz Rzeszutek committed May 18, 2023
1 parent 0806a6a commit 51014a1
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 57 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ public final class HttpResponseReceiverInstrumenter {
// this method adds several stateful listeners that execute the instrumenter lifecycle during HTTP
// request processing
// it should be used just before one of the response*() methods is called - after this point the
// HTTP
// request is no longer modifiable by the user
// HTTP request is no longer modifiable by the user
@Nullable
public static HttpClient.ResponseReceiver<?> instrument(HttpClient.ResponseReceiver<?> receiver) {
// receiver should always be an HttpClientFinalizer, which both extends HttpClient and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,23 @@

import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientResend;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import reactor.netty.http.client.HttpClientRequest;
import reactor.netty.http.client.HttpClientResponse;

final class InstrumentationContexts {

static final Logger logger = Logger.getLogger(InstrumentationContexts.class.getName());

private volatile Context parentContext;
// on retries, reactor-netty starts the next resend attempt before it ends the previous one (i.e.
// it calls the callback functions in that order); thus for a short moment there can be 2
// coexisting HTTP client spans
private final ConstantSizeStack<RequestAndContext> clientContexts = new ConstantSizeStack<>(2);
private final Queue<RequestAndContext> clientContexts = new ArrayBlockingQueue<>(2, true);

void initialize(Context parentContext) {
this.parentContext = HttpClientResend.initialize(parentContext);
Expand All @@ -41,13 +47,19 @@ Context startClientSpan(HttpClientRequest request) {
Context context = null;
if (instrumenter().shouldStart(parentContext, request)) {
context = instrumenter().start(parentContext, request);
clientContexts.push(new RequestAndContext(request, context));
if (!clientContexts.offer(new RequestAndContext(request, context))) {
// should not ever happen in reality
String message =
"Could not instrument HTTP client request; not enough space in the request queue";
logger.log(Level.FINE, message);
instrumenter().end(context, request, null, new IllegalStateException(message));
}
}
return context;
}

void endClientSpan(@Nullable HttpClientResponse response, @Nullable Throwable error) {
RequestAndContext requestAndContext = clientContexts.pop();
RequestAndContext requestAndContext = clientContexts.poll();
if (requestAndContext != null) {
instrumenter().end(requestAndContext.context, requestAndContext.request, response, error);
}
Expand Down

0 comments on commit 51014a1

Please sign in to comment.