Skip to content

Commit

Permalink
JAVA-2234: Handle terminated executor when the session is closed twice
Browse files Browse the repository at this point in the history
  • Loading branch information
olim7t committed Jun 6, 2019
1 parent a86b022 commit e98d153
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
1 change: 1 addition & 0 deletions changelog/README.md
Expand Up @@ -4,6 +4,7 @@

### 4.1.0 (in progress)

- [bug] JAVA-2234: Handle terminated executor when the session is closed twice
- [documentation] JAVA-2220: Emphasize that query builder is now a separate artifact in root README
- [documentation] JAVA-2217: Cover contact points and local datacenter earlier in the manual
- [improvement] JAVA-2242: Allow skipping all integration tests with -DskipITs
Expand Down
Expand Up @@ -54,6 +54,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.RejectedExecutionException;
import java.util.function.Supplier;
import net.jcip.annotations.ThreadSafe;
import org.slf4j.Logger;
Expand Down Expand Up @@ -246,14 +247,31 @@ public CompletionStage<Void> closeFuture() {
@NonNull
@Override
public CompletionStage<Void> closeAsync() {
RunOrSchedule.on(adminExecutor, singleThreaded::close);
return singleThreaded.closeFuture;
return closeSafely(singleThreaded::close);
}

@NonNull
@Override
public CompletionStage<Void> forceCloseAsync() {
RunOrSchedule.on(adminExecutor, singleThreaded::forceClose);
return closeSafely(singleThreaded::forceClose);
}

private CompletionStage<Void> closeSafely(Runnable action) {
// Protect against getting closed twice: with the default NettyOptions, closing shuts down
// adminExecutor, so we don't want to call RunOrSchedule the second time.
if (!singleThreaded.closeFuture.isDone()) {
try {
RunOrSchedule.on(adminExecutor, action);
} catch (RejectedExecutionException e) {
// Checking the future is racy, there is still a tiny window that could get us here.
LOG.warn(
"[{}] Ignoring terminated executor. "
+ "This generally happens if you close the session multiple times concurrently, "
+ "and can be safely ignored if the close() call returns normally.",
logPrefix,
e);
}
}
return singleThreaded.closeFuture;
}

Expand Down
Expand Up @@ -128,4 +128,11 @@ public void should_fail_requests_when_session_is_closed() throws Exception {
// Then
assertThat(unexpectedErrors).isEmpty();
}

@Test
public void should_handle_getting_closed_twice() {
CqlSession session = SessionUtils.newSession(simulacronRule);
session.close();
session.close();
}
}

0 comments on commit e98d153

Please sign in to comment.