3232import java .util .concurrent .CompletableFuture ;
3333import java .util .concurrent .Executors ;
3434import java .util .concurrent .ScheduledExecutorService ;
35+ import java .util .concurrent .ThreadLocalRandom ;
3536import java .util .concurrent .TimeUnit ;
3637
3738import static com .mongodb .internal .async .AsyncRunnable .beginAsync ;
@@ -77,28 +78,32 @@ private enum IterationExecutionType {
7778 SYNC_SAME_THREAD ,
7879 SYNC_DIFFERENT_THREAD ,
7980 ASYNC ,
81+ MIXED_SYNC_SAME_AND_ASYNC
8082 }
8183
8284 @ ParameterizedTest ()
8385 @ CsvSource ({
84- "10, 0, SYNC_SAME_THREAD, 0" ,
85- // "10, 0, SYNC_DIFFERENT_THREAD, 0",
86- "10, 0, ASYNC, 4" ,
87- "10, 4, ASYNC, 0"
86+ "10, 0, SYNC_SAME_THREAD, 0, true" ,
87+ // "10, 0, SYNC_DIFFERENT_THREAD, 0, true",
88+ "10, 0, ASYNC, 4, true" ,
89+ "10, 4, ASYNC, 0, true" ,
90+ "1_000_000, 0, MIXED_SYNC_SAME_AND_ASYNC, 0, false" ,
8891 })
8992 void testThenRunDoWhileLoop (
9093 final int counterInitialValue ,
9194 final int blockSyncPartOfIterationTotalSeconds ,
9295 final IterationExecutionType executionType ,
93- final int delayAsyncExecutionTotalSeconds ) throws Exception {
96+ final int delayAsyncExecutionTotalSeconds ,
97+ final boolean verbose ) throws Exception {
9498 System .err .printf ("baselineStackDepth=%d%n%n" , Thread .currentThread ().getStackTrace ().length );
9599 Duration blockSyncPartOfIterationTotalDuration = Duration .ofSeconds (blockSyncPartOfIterationTotalSeconds );
96100 com .mongodb .assertions .Assertions .assertTrue (
97101 executionType .equals (IterationExecutionType .ASYNC ) || delayAsyncExecutionTotalSeconds == 0 );
98102 Duration delayAsyncExecutionTotalDuration = Duration .ofSeconds (delayAsyncExecutionTotalSeconds );
99103 StartTime start = StartTime .now ();
100104 CompletableFuture <Void > join = new CompletableFuture <>();
101- asyncLoop (new Counter (counterInitialValue ), blockSyncPartOfIterationTotalDuration , executionType , delayAsyncExecutionTotalDuration ,
105+ asyncLoop (new Counter (counterInitialValue , verbose ),
106+ blockSyncPartOfIterationTotalDuration , executionType , delayAsyncExecutionTotalDuration , verbose ,
102107 (r , t ) -> {
103108 System .err .printf ("test callback completed callStackDepth=%s, r=%s, t=%s%n" ,
104109 Thread .currentThread ().getStackTrace ().length , r , exceptionToString (t ));
@@ -114,25 +119,31 @@ private static void asyncLoop(
114119 final Duration blockSyncPartOfIterationTotalDuration ,
115120 final IterationExecutionType executionType ,
116121 final Duration delayAsyncExecutionTotalDuration ,
122+ final boolean verbose ,
117123 final SingleResultCallback <Void > callback ) {
118124 beginAsync ().thenRunDoWhileLoop (c -> {
119125 sleep (blockSyncPartOfIterationTotalDuration .dividedBy (counter .initial ()));
120126 StartTime start = StartTime .now ();
121- asyncPartOfIteration (counter , executionType , delayAsyncExecutionTotalDuration , c );
122- System .err .printf ("\t asyncPartOfIteration returned in %s%n" , start .elapsed ());
127+ asyncPartOfIteration (counter , executionType , delayAsyncExecutionTotalDuration , verbose , c );
128+ if (verbose ) {
129+ System .err .printf ("\t asyncPartOfIteration returned in %s%n" , start .elapsed ());
130+ }
123131 }, () -> !counter .done ()).finish (callback );
124132 }
125133
126134 private static void asyncPartOfIteration (
127135 final Counter counter ,
128136 final IterationExecutionType executionType ,
129137 final Duration delayAsyncExecutionTotalDuration ,
138+ final boolean verbose ,
130139 final SingleResultCallback <Void > callback ) {
131140 Runnable asyncPartOfIteration = () -> {
132141 counter .countDown ();
133142 StartTime start = StartTime .now ();
134143 callback .complete (callback );
135- System .err .printf ("\t asyncPartOfIteration callback.complete returned in %s%n" , start .elapsed ());
144+ if (verbose ) {
145+ System .err .printf ("\t asyncPartOfIteration callback.complete returned in %s%n" , start .elapsed ());
146+ }
136147 };
137148 switch (executionType ) {
138149 case SYNC_SAME_THREAD : {
@@ -150,6 +161,15 @@ private static void asyncPartOfIteration(
150161 delayAsyncExecutionTotalDuration .dividedBy (counter .initial ()).toNanos (), TimeUnit .NANOSECONDS );
151162 break ;
152163 }
164+ case MIXED_SYNC_SAME_AND_ASYNC : {
165+ if (ThreadLocalRandom .current ().nextBoolean ()) {
166+ asyncPartOfIteration .run ();
167+ } else {
168+ executor .schedule (asyncPartOfIteration ,
169+ delayAsyncExecutionTotalDuration .dividedBy (counter .initial ()).toNanos (), TimeUnit .NANOSECONDS );
170+ }
171+ break ;
172+ }
153173 default : {
154174 com .mongodb .assertions .Assertions .fail (executionType .toString ());
155175 }
@@ -159,10 +179,12 @@ private static void asyncPartOfIteration(
159179 private static final class Counter {
160180 private final int initial ;
161181 private int current ;
182+ private final boolean verbose ;
162183
163- Counter (final int initial ) {
184+ Counter (final int initial , final boolean verbose ) {
164185 this .initial = initial ;
165186 this .current = initial ;
187+ this .verbose = verbose ;
166188 }
167189
168190 int initial () {
@@ -173,7 +195,10 @@ void countDown() {
173195 com .mongodb .assertions .Assertions .assertTrue (current > 0 );
174196 int previous = current ;
175197 int decremented = --current ;
176- System .err .printf ("counted %d->%d callStackDepth=%d %n" , previous , decremented , Thread .currentThread ().getStackTrace ().length );
198+ if (verbose || decremented % 100_000 == 0 ) {
199+ System .err .printf ("counted %d->%d callStackDepth=%d %n" ,
200+ previous , decremented , Thread .currentThread ().getStackTrace ().length );
201+ }
177202 }
178203
179204 boolean done () {
0 commit comments