@@ -260,4 +260,51 @@ public void onNext(Frame object) {
260260 executor .shutdownNow ();
261261 }
262262 }
263+
264+ @ Test (timeout = 10_000 )
265+ public void asyncLongDockerLogCmd () throws Exception {
266+ // Create a new client to not affect other tests
267+ DockerClient client = dockerRule .newClient ();
268+ CreateContainerResponse container = client .createContainerCmd ("icevivek/logreader" )
269+ .exec ();
270+
271+ client .startContainerCmd (container .getId ()).exec ();
272+
273+ // Simulate 100 simultaneous connections
274+ int connections = 100 ;
275+
276+ ExecutorService executor = Executors .newFixedThreadPool (connections );
277+ try {
278+ List <Frame > firstFrames = new CopyOnWriteArrayList <>();
279+ executor .invokeAll (
280+ LongStream .range (0 , connections ).<Callable <Object >>mapToObj (__ -> {
281+ return () -> {
282+ return client .logContainerCmd (container .getId ())
283+ .withStdOut (true )
284+ .withFollowStream (true )
285+ .exec (new ResultCallback .Adapter <Frame >() {
286+
287+ final AtomicBoolean first = new AtomicBoolean (true );
288+
289+ @ Override
290+ public void onNext (Frame object ) {
291+ if (first .compareAndSet (true , false )) {
292+ firstFrames .add (object );
293+ }
294+ super .onNext (object );
295+ }
296+ });
297+ };
298+ }).collect (Collectors .toList ())
299+ );
300+
301+ await ().atMost (30 , TimeUnit .SECONDS ).untilAsserted (() -> {
302+ assertThat (firstFrames , hasSize (connections ));
303+ });
304+
305+ assertThat (firstFrames .size (), is (187 ));
306+ } finally {
307+ executor .shutdownNow ();
308+ }
309+ }
263310}
0 commit comments