Asynchronous processing
Using java.lang.Runnable in threads
When you use java.lang.Runnable to start a new thread or a thread pool for asynchronous processing, the SOFATracer log context must be passed from the parent thread to the subthread. The com.alipay.common.tracer.core.async.SofaTracerRunnable class provided by SOFATracer performs this operation by default. You can use it as follows:
Thread thread =new Thread(new SofaTracerRunnable(new Runnable(){
@Override
public void run(){
//do something your business code
}
}));
thread.start();Using java.util.concurrent.Callable in threads
When you use java.util.concurrent.Callable to start a new thread or a thread pool for asynchronous processing, the SOFATracer log context must be passed from the parent thread to the subthread. The com.alipay.common.tracer.core.async.SofaTracerCallable class provided by SOFATracer performs this operation by default. You can use it as follows:
ExecutorService executor =Executors.newCachedThreadPool();
SofaTracerCallable<Object> sofaTracerSpanSofaTracerCallable =new SofaTracerCallable<Object>(newCallable<Object>(){
@Override
public Object call()throws Exception{
return new Object();
}
});
Future<Object> futureResult = executor.submit(sofaTracerSpanSofaTracerCallable);
//do something in current thread
Thread.sleep(1000);
//another thread execute success and get result
Object objectReturn = futureResult.get();In this example, the object type of the result returned by java.util.concurrent.Callable is java.lang.Object. You can replace this with the desired type as needed.
SOFATracer support for thread pools and asynchronous invocations
Asynchronous scenarios
In an asynchronous invocation, such as a remote procedure call (RPC), the client sends a request and continues processing without waiting for a response. This creates a time gap during which a new RPC request can be sent before the callback for the previous request returns. If the TracerContext in the current thread is not cleared, the spanId auto-increments, but the tracerId remains the same.
For asynchronous operations, SOFATracer handles this by clearing the current thread's tracerContext in advance. It does not wait for the callback to return or for the cr phase to be invoked. This ensures the trace link is correct.
Thread pools
SOFARPC and Dubbo instrumentation behave the same way in both single-threaded and thread pool implementations:
Synchronous call: A thread from the thread pool is allocated to process an RPC request. This thread remains occupied until the request is complete. This prevents the next RPC request from mistakenly using the tracerContext data of the previous request.
Asynchronous invocation: The context is cleared in advance, not within the callback. This prevents data from being mixed between requests.
Asynchronous callback: An asynchronous callback is treated as an asynchronous invocation and is handled in the same way.