Skip to content

Commit 39b1b40

Browse files
authored
[DE-424] Bugfix HTTP shutdown (#469)
* CodeQL fixes * fixed http shutdown
1 parent e688c84 commit 39b1b40

File tree

4 files changed

+71
-10
lines changed

4 files changed

+71
-10
lines changed

.github/workflows/codeql.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ jobs:
2929
name: Analyze
3030
runs-on: ubuntu-latest
3131

32-
defaults:
33-
run:
34-
working-directory: driver
35-
3632
permissions:
3733
actions: read
3834
contents: read
@@ -66,6 +62,7 @@ jobs:
6662
# If this step fails, then you should remove it and run the build manually (see below)
6763
- name: Autobuild
6864
uses: github/codeql-action/autobuild@v2
65+
working-directory: driver
6966

7067
# ℹ️ Command-line programs to run using the OS shell.
7168
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -79,3 +76,4 @@ jobs:
7976

8077
- name: Perform CodeQL Analysis
8178
uses: github/codeql-action/analyze@v2
79+
working-directory: driver

driver/src/main/java/com/arangodb/internal/net/ConnectionPoolImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package com.arangodb.internal.net;
2222

23+
import com.arangodb.ArangoDBException;
2324
import com.arangodb.internal.velocystream.internal.VstConnection;
2425
import com.arangodb.internal.velocystream.internal.VstConnectionSync;
2526
import org.slf4j.Logger;
@@ -42,6 +43,7 @@ public class ConnectionPoolImpl implements ConnectionPool {
4243
private final ConnectionFactory factory;
4344
private int current;
4445
private volatile String jwt = null;
46+
private boolean closed = false;
4547

4648
public ConnectionPoolImpl(final HostDescription host, final Integer maxConnections,
4749
final ConnectionFactory factory) {
@@ -62,6 +64,9 @@ public Connection createConnection(final HostDescription host) {
6264

6365
@Override
6466
public synchronized Connection connection() {
67+
if (closed) {
68+
throw new ArangoDBException("Connection pool already closed!");
69+
}
6570

6671
final Connection connection;
6772

@@ -91,6 +96,7 @@ public void setJwt(String jwt) {
9196

9297
@Override
9398
public synchronized void close() throws IOException {
99+
closed = true;
94100
for (final Connection connection : connections) {
95101
connection.close();
96102
}

resilience-tests/src/test/java/resilience/retry/RetryTest.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ class RetryTest extends SingleServerTest {
3333

3434
static Stream<ArangoDB> arangoProvider() {
3535
return Stream.of(
36-
dbBuilder().timeout(1_000).useProtocol(Protocol.VST).build(),
37-
dbBuilder().timeout(1_000).useProtocol(Protocol.HTTP_VPACK).build(),
38-
dbBuilder().timeout(1_000).useProtocol(Protocol.HTTP2_VPACK).build()
36+
dbBuilder().useProtocol(Protocol.VST).build(),
37+
dbBuilder().useProtocol(Protocol.HTTP_VPACK).build(),
38+
dbBuilder().useProtocol(Protocol.HTTP2_VPACK).build()
3939
);
4040
}
4141

@@ -57,9 +57,8 @@ void unreachableHost(ArangoDB arangoDB) {
5757
assertThat(thrown.getMessage()).contains("Cannot contact any host");
5858
assertThat(thrown.getCause()).isNotNull();
5959
assertThat(thrown.getCause()).isInstanceOf(ArangoDBMultipleException.class);
60-
((ArangoDBMultipleException) thrown.getCause()).getExceptions().forEach(e -> {
61-
assertThat(e).isInstanceOf(ConnectException.class);
62-
});
60+
((ArangoDBMultipleException) thrown.getCause()).getExceptions().forEach(e ->
61+
assertThat(e).isInstanceOf(ConnectException.class));
6362
}
6463

6564
long warnsCount = logs.getLoggedEvents().stream()
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package resilience.shutdown;
2+
3+
import com.arangodb.ArangoDB;
4+
import com.arangodb.ArangoDBException;
5+
import com.arangodb.Protocol;
6+
import io.vertx.core.http.HttpClosedException;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.EnumSource;
9+
import resilience.SingleServerTest;
10+
11+
import java.io.IOException;
12+
import java.util.concurrent.Executors;
13+
import java.util.concurrent.ScheduledExecutorService;
14+
import java.util.concurrent.TimeUnit;
15+
16+
import static org.assertj.core.api.Assertions.assertThat;
17+
import static org.assertj.core.api.Assertions.catchThrowable;
18+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
19+
20+
/**
21+
* @author Michele Rastelli
22+
*/
23+
class ShutdownTest extends SingleServerTest {
24+
25+
@ParameterizedTest
26+
@EnumSource(Protocol.class)
27+
void shutdown(Protocol protocol) throws InterruptedException {
28+
ArangoDB arangoDB = dbBuilder()
29+
.useProtocol(protocol)
30+
.build();
31+
32+
arangoDB.getVersion();
33+
arangoDB.shutdown();
34+
Thread.sleep(1_000);
35+
Throwable thrown = catchThrowable(arangoDB::getVersion);
36+
assertThat(thrown).isInstanceOf(ArangoDBException.class);
37+
assertThat(thrown.getMessage()).contains("closed");
38+
}
39+
40+
@ParameterizedTest
41+
@EnumSource(Protocol.class)
42+
void shutdownWithPendingRequests(Protocol protocol) {
43+
assumeTrue(protocol != Protocol.VST);
44+
ArangoDB arangoDB = dbBuilder()
45+
.useProtocol(protocol)
46+
.build();
47+
48+
ScheduledExecutorService es = Executors.newSingleThreadScheduledExecutor();
49+
es.schedule(arangoDB::shutdown, 200, TimeUnit.MILLISECONDS);
50+
Throwable thrown = catchThrowable(() -> arangoDB.db().query("return sleep(1)", Void.class));
51+
thrown.printStackTrace();
52+
assertThat(thrown).isInstanceOf(ArangoDBException.class);
53+
assertThat(thrown.getCause()).isInstanceOf(IOException.class);
54+
assertThat(thrown.getCause().getCause()).isInstanceOf(HttpClosedException.class);
55+
es.shutdown();
56+
}
57+
58+
}

0 commit comments

Comments
 (0)