1
1
package org .testcontainers .containers .wait .strategy ;
2
2
3
+ import lombok .SneakyThrows ;
3
4
import lombok .extern .slf4j .Slf4j ;
4
- import org .rnorth .ducttape .TimeoutException ;
5
- import org .rnorth .ducttape .unreliables .Unreliables ;
5
+ import org .awaitility .Awaitility ;
6
6
import org .testcontainers .containers .ContainerLaunchException ;
7
7
import org .testcontainers .containers .wait .internal .ExternalPortListeningCheck ;
8
8
import org .testcontainers .containers .wait .internal .InternalCommandPortListeningCheck ;
9
9
10
+ import java .time .Duration ;
11
+ import java .time .Instant ;
12
+ import java .util .Arrays ;
10
13
import java .util .List ;
11
14
import java .util .Set ;
12
15
import java .util .concurrent .Callable ;
16
+ import java .util .concurrent .CancellationException ;
17
+ import java .util .concurrent .ExecutionException ;
18
+ import java .util .concurrent .Future ;
13
19
import java .util .concurrent .TimeUnit ;
20
+ import java .util .concurrent .TimeoutException ;
14
21
import java .util .stream .Collectors ;
15
22
16
23
/**
22
29
public class HostPortWaitStrategy extends AbstractWaitStrategy {
23
30
24
31
@ Override
32
+ @ SneakyThrows (InterruptedException .class )
25
33
protected void waitUntilReady () {
26
34
final Set <Integer > externalLivenessCheckPorts = getLivenessCheckPorts ();
27
35
if (externalLivenessCheckPorts .isEmpty ()) {
@@ -31,7 +39,6 @@ protected void waitUntilReady() {
31
39
return ;
32
40
}
33
41
34
- @ SuppressWarnings ("unchecked" )
35
42
List <Integer > exposedPorts = waitStrategyTarget .getExposedPorts ();
36
43
37
44
final Set <Integer > internalPorts = getInternalPorts (externalLivenessCheckPorts , exposedPorts );
@@ -41,10 +48,43 @@ protected void waitUntilReady() {
41
48
Callable <Boolean > externalCheck = new ExternalPortListeningCheck (waitStrategyTarget , externalLivenessCheckPorts );
42
49
43
50
try {
44
- Unreliables .retryUntilTrue ((int ) startupTimeout .getSeconds (), TimeUnit .SECONDS ,
45
- () -> getRateLimiter ().getWhenReady (() -> internalCheck .call () && externalCheck .call ()));
51
+ List <Future <Boolean >> futures = EXECUTOR .invokeAll (Arrays .asList (
52
+ // Blocking
53
+ () -> {
54
+ Instant now = Instant .now ();
55
+ Boolean result = internalCheck .call ();
56
+ log .debug (
57
+ "Internal port check {} for {} in {}" ,
58
+ Boolean .TRUE .equals (result ) ? "passed" : "failed" ,
59
+ internalPorts ,
60
+ Duration .between (now , Instant .now ())
61
+ );
62
+ return result ;
63
+ },
64
+ // Polling
65
+ () -> {
66
+ Instant now = Instant .now ();
67
+ Awaitility .await ()
68
+ .pollInSameThread ()
69
+ .pollInterval (Duration .ofMillis (100 ))
70
+ .pollDelay (Duration .ZERO )
71
+ .forever ()
72
+ .until (externalCheck );
46
73
47
- } catch (TimeoutException e ) {
74
+ log .debug (
75
+ "External port check passed for {} mapped as {} in {}" ,
76
+ internalPorts ,
77
+ externalLivenessCheckPorts ,
78
+ Duration .between (now , Instant .now ())
79
+ );
80
+ return true ;
81
+ }
82
+ ), startupTimeout .getSeconds (), TimeUnit .SECONDS );
83
+
84
+ for (Future <Boolean > future : futures ) {
85
+ future .get (0 , TimeUnit .SECONDS );
86
+ }
87
+ } catch (CancellationException | ExecutionException | TimeoutException e ) {
48
88
throw new ContainerLaunchException ("Timed out waiting for container port to open (" +
49
89
waitStrategyTarget .getHost () +
50
90
" ports: " +
0 commit comments