Using instrumented clients in worker threads - Amazon X-Ray
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Using instrumented clients in worker threads

Scorekeep uses a worker thread to publish a notification to Amazon SNS when a user wins a game. Publishing the notification takes longer than the rest of the request operations combined, and doesn't affect the client or user. Therefore, performing the task asynchronously is a good way to improve response time.

However, the X-Ray SDK for Java doesn't know which segment was active when the thread is created. As a result, when you try to use the instrumented Amazon SDK for Java client within the thread, it throws a SegmentNotFoundException, crashing the thread.

Example Web-1.error.log
Exception in thread "Thread-2" com.amazonaws.xray.exceptions.SegmentNotFoundException: Failed to begin subsegment named 'AmazonSNS': segment cannot be found. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ...

To fix this, the application uses GetTraceEntity to get a reference to the segment in the main thread, and Entity.run() to safely run the worker thread code with access to the segment's context.

Example src/main/java/scorekeep/MoveFactory.java – Passing trace context to a worker thread
import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.AWSXRayRecorder; import com.amazonaws.xray.entities.Entity; import com.amazonaws.xray.entities.Segment; import com.amazonaws.xray.entities.Subsegment; ... Entity segment = recorder.getTraceEntity(); Thread comm = new Thread() { public void run() { segment.run(() -> { Subsegment subsegment = AWSXRay.beginSubsegment("## Send notification"); Sns.sendNotification("Scorekeep game completed", "Winner: " + userId); AWSXRay.endSubsegment(); } }

Because the request is now resolved before the call to Amazon SNS, the application creates a separate subsegment for the thread. This prevents the X-Ray SDK from closing the segment before it records the response from Amazon SNS. If no subsegment is open when Scorekeep resolved the request, the response from Amazon SNS could be lost.


      Trace overview with asynchronous thread subsegment.

See Passing segment context between threads in a multithreaded application for more information about multithreading.