Skip to content

Commit 08b599d

Browse files
committed
Modify waiting strategy
1 parent 9c61037 commit 08b599d

1 file changed

Lines changed: 52 additions & 7 deletions

File tree

contrib/storage-hive/core/src/test/java/org/apache/drill/exec/hive/HiveContainer.java

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.slf4j.LoggerFactory;
2222
import org.testcontainers.containers.GenericContainer;
2323
import org.testcontainers.containers.wait.strategy.Wait;
24+
import org.testcontainers.containers.wait.strategy.WaitAllStrategy;
2425
import org.testcontainers.utility.DockerImageName;
2526

2627
import java.time.Duration;
@@ -93,16 +94,22 @@ private void configureContainer() {
9394
waitingFor(Wait.forLogMessage(".*Hive container ready \\(pre-initialized\\)!.*", 1)
9495
.withStartupTimeout(Duration.ofMinutes(2)));
9596
} else if (useFallbackImage) {
96-
// Fallback to apache/hive:3.1.3 - wait for HiveServer2 to be ready
97-
// This image uses a different startup sequence
98-
waitingFor(Wait.forLogMessage(".*Starting HiveServer2.*", 1)
99-
.withStartupTimeout(Duration.ofMinutes(5)));
97+
// Fallback to apache/hive:3.1.3 - wait for both metastore port AND HiveServer2 to be ready
98+
// The metastore must be accepting connections before Drill can use it
99+
WaitAllStrategy waitStrategy = new WaitAllStrategy()
100+
.withStrategy(Wait.forListeningPort()) // Wait for metastore port 9083 to be listening
101+
.withStrategy(Wait.forLogMessage(".*Starting HiveServer2.*", 1))
102+
.withStartupTimeout(Duration.ofMinutes(10)); // Allow up to 10 minutes for full startup
103+
waitingFor(waitStrategy);
100104
} else {
101-
// Custom image: wait for both HiveServer2 to start AND test data to be initialized
105+
// Custom image: wait for metastore port AND test data initialization message
102106
// Allow up to 20 minutes: Metastore + HiveServer2 startup (~5-10 min) + data initialization (~5-10 min)
103107
// This is only on first run; container reuse makes subsequent tests fast (~1 second)
104-
waitingFor(Wait.forLogMessage(".*Test data loaded and ready for queries.*", 1)
105-
.withStartupTimeout(Duration.ofMinutes(20)));
108+
WaitAllStrategy waitStrategy = new WaitAllStrategy()
109+
.withStrategy(Wait.forListeningPort()) // Wait for metastore port 9083 to be listening
110+
.withStrategy(Wait.forLogMessage(".*Test data loaded and ready for queries.*", 1))
111+
.withStartupTimeout(Duration.ofMinutes(20));
112+
waitingFor(waitStrategy);
106113
}
107114

108115
// Enable reuse for faster test execution
@@ -175,6 +182,11 @@ private static HiveContainer tryStartContainer(String imageName, boolean isFallb
175182
System.out.println("Pulling Docker image and starting container...");
176183
long startTime = System.currentTimeMillis();
177184
container.start();
185+
186+
// Additional wait for metastore to stabilize
187+
System.out.println("Waiting for metastore to stabilize...");
188+
waitForMetastoreReady(container);
189+
178190
long elapsedSeconds = (System.currentTimeMillis() - startTime) / 1000;
179191

180192
System.out.println("========================================");
@@ -192,6 +204,39 @@ private static HiveContainer tryStartContainer(String imageName, boolean isFallb
192204
return container;
193205
}
194206

207+
/**
208+
* Waits for the metastore to be fully ready by attempting socket connections.
209+
* This ensures the Thrift service is actually accepting connections.
210+
*/
211+
private static void waitForMetastoreReady(HiveContainer container) {
212+
int maxAttempts = 30;
213+
int attemptDelayMs = 2000;
214+
String host = container.getHost();
215+
int port = container.getMetastorePort();
216+
217+
for (int i = 1; i <= maxAttempts; i++) {
218+
try (java.net.Socket socket = new java.net.Socket()) {
219+
socket.connect(new java.net.InetSocketAddress(host, port), 1000);
220+
// Connection successful - wait a bit more for service to fully initialize
221+
Thread.sleep(3000);
222+
System.out.println("Metastore is ready and accepting connections");
223+
return;
224+
} catch (Exception e) {
225+
if (i < maxAttempts) {
226+
logger.debug("Metastore not ready yet (attempt {}/{}): {}", i, maxAttempts, e.getMessage());
227+
try {
228+
Thread.sleep(attemptDelayMs);
229+
} catch (InterruptedException ie) {
230+
Thread.currentThread().interrupt();
231+
throw new RuntimeException("Interrupted while waiting for metastore", ie);
232+
}
233+
} else {
234+
throw new RuntimeException("Metastore failed to become ready after " + maxAttempts + " attempts", e);
235+
}
236+
}
237+
}
238+
}
239+
195240
/**
196241
* Gets the JDBC URL for connecting to HiveServer2.
197242
*

0 commit comments

Comments
 (0)