1919
2020package org .elasticsearch .common .util .concurrent ;
2121
22+ import org .apache .logging .log4j .message .ParameterizedMessage ;
2223import org .elasticsearch .action .ActionListener ;
2324import org .elasticsearch .common .settings .Settings ;
2425import org .elasticsearch .test .ESTestCase ;
3031import java .util .concurrent .ExecutorService ;
3132import java .util .concurrent .atomic .AtomicInteger ;
3233
34+ import static org .hamcrest .Matchers .is ;
35+
3336public class ListenableFutureTests extends ESTestCase {
3437
3538 private ExecutorService executorService ;
39+ private ThreadContext threadContext = new ThreadContext (Settings .EMPTY );
3640
3741 @ After
3842 public void stopExecutorService () throws InterruptedException {
@@ -46,7 +50,7 @@ public void testListenableFutureNotifiesListeners() {
4650 AtomicInteger notifications = new AtomicInteger (0 );
4751 final int numberOfListeners = scaledRandomIntBetween (1 , 12 );
4852 for (int i = 0 ; i < numberOfListeners ; i ++) {
49- future .addListener (ActionListener .wrap (notifications ::incrementAndGet ), EsExecutors .newDirectExecutorService ());
53+ future .addListener (ActionListener .wrap (notifications ::incrementAndGet ), EsExecutors .newDirectExecutorService (), threadContext );
5054 }
5155
5256 future .onResponse ("" );
@@ -63,7 +67,7 @@ public void testListenableFutureNotifiesListenersOnException() {
6367 future .addListener (ActionListener .wrap (s -> fail ("this should never be called" ), e -> {
6468 assertEquals (exception , e );
6569 notifications .incrementAndGet ();
66- }), EsExecutors .newDirectExecutorService ());
70+ }), EsExecutors .newDirectExecutorService (), threadContext );
6771 }
6872
6973 future .onFailure (exception );
@@ -76,7 +80,7 @@ public void testConcurrentListenerRegistrationAndCompletion() throws BrokenBarri
7680 final int completingThread = randomIntBetween (0 , numberOfThreads - 1 );
7781 final ListenableFuture <String > future = new ListenableFuture <>();
7882 executorService = EsExecutors .newFixed ("testConcurrentListenerRegistrationAndCompletion" , numberOfThreads , 1000 ,
79- EsExecutors .daemonThreadFactory ("listener" ), new ThreadContext ( Settings . EMPTY ) );
83+ EsExecutors .daemonThreadFactory ("listener" ), threadContext );
8084 final CyclicBarrier barrier = new CyclicBarrier (1 + numberOfThreads );
8185 final CountDownLatch listenersLatch = new CountDownLatch (numberOfThreads - 1 );
8286 final AtomicInteger numResponses = new AtomicInteger (0 );
@@ -85,20 +89,31 @@ public void testConcurrentListenerRegistrationAndCompletion() throws BrokenBarri
8589 for (int i = 0 ; i < numberOfThreads ; i ++) {
8690 final int threadNum = i ;
8791 Thread thread = new Thread (() -> {
92+ threadContext .putTransient ("key" , threadNum );
8893 try {
8994 barrier .await ();
9095 if (threadNum == completingThread ) {
96+ // we need to do more than just call onResponse as this often results in synchronous
97+ // execution of the listeners instead of actually going async
98+ final int waitTime = randomIntBetween (0 , 50 );
99+ Thread .sleep (waitTime );
100+ logger .info ("completing the future after sleeping {}ms" , waitTime );
91101 future .onResponse ("" );
102+ logger .info ("future received response" );
92103 } else {
104+ logger .info ("adding listener {}" , threadNum );
93105 future .addListener (ActionListener .wrap (s -> {
106+ logger .info ("listener {} received value {}" , threadNum , s );
94107 assertEquals ("" , s );
108+ assertThat (threadContext .getTransient ("key" ), is (threadNum ));
95109 numResponses .incrementAndGet ();
96110 listenersLatch .countDown ();
97111 }, e -> {
98- logger .error (" caught unexpected exception" , e );
112+ logger .error (new ParameterizedMessage ( "listener {} caught unexpected exception", threadNum ) , e );
99113 numExceptions .incrementAndGet ();
100114 listenersLatch .countDown ();
101- }), executorService );
115+ }), executorService , threadContext );
116+ logger .info ("listener {} added" , threadNum );
102117 }
103118 barrier .await ();
104119 } catch (InterruptedException | BrokenBarrierException e ) {
0 commit comments