@Override public synchronized void stopInternal() throws InterruptedException, IOException { LOG.info("Shutting down raft journal"); mRaftJournalWriter.close(); try { mServer.shutdown().get(2, TimeUnit.SECONDS); } catch (ExecutionException e) { throw new RuntimeException("Failed to shut down Raft server", e); } catch (TimeoutException e) { LOG.info("Timed out shutting down raft server"); } LOG.info("Journal shutdown complete"); }
mServer.shutdown().get(); } catch (ExecutionException e) { LOG.error("Fatal error: failed to leave Raft cluster while stepping down", e);
/** * Shuts down the server without leaving the Copycat cluster. * * @return A completable future to be completed once the server has been shutdown. */ public CompletableFuture<Void> shutdown() { return server.shutdown(); }
try { if (s.isRunning()) { s.shutdown().get(10, TimeUnit.SECONDS);
try { if (s.isRunning()) { s.shutdown().get(10, TimeUnit.SECONDS);
if (openFuture == null) { cluster().leave().whenComplete((leaveResult, leaveError) -> { shutdown().whenComplete((shutdownResult, shutdownError) -> { context.delete(); closeFuture.complete(null); if (openError == null) { cluster().leave().whenComplete((leaveResult, leaveError) -> { shutdown().whenComplete((shutdownResult, shutdownError) -> { context.delete(); closeFuture.complete(null);
if (openFuture == null) { cluster().leave().whenComplete((leaveResult, leaveError) -> { shutdown().whenComplete((shutdownResult, shutdownError) -> { context.delete(); closeFuture.complete(null); if (openError == null) { cluster().leave().whenComplete((leaveResult, leaveError) -> { shutdown().whenComplete((shutdownResult, shutdownError) -> { context.delete(); closeFuture.complete(null);
} else { System.out.println("Shutting down server: " + server.cluster().member().address()); leaveFuture = server.shutdown();
@BeforeMethod @AfterMethod public void clearTests() throws Exception { clients.forEach(c -> { try { c.close().get(10, TimeUnit.SECONDS); } catch (Exception e) { } }); servers.forEach(s -> { try { if (s.isRunning()) { s.shutdown().get(10, TimeUnit.SECONDS); } } catch (Exception e) { } }); members = new ArrayList<>(); port = 5000; registry = new LocalServerRegistry(); clients = new ArrayList<>(); servers = new ArrayList<>(); }
/** * Tests joining a server to an existing cluster. */ public void testCrashRecover() throws Throwable { List<CopycatServer> servers = createServers(3); CopycatClient client = createClient(); submit(client, 0, 1000); await(30000); servers.get(0).shutdown().get(10, TimeUnit.SECONDS); CopycatServer server = createServer(members.get(0)); server.join(members.stream().map(Member::serverAddress).collect(Collectors.toList())).thenRun(this::resume); await(30000); submit(client, 0, 1000); await(30000); }
/** * Tests a member availability change. */ private void testAvailabilityChange(Member.Type type) throws Throwable { List<CopycatServer> servers = createServers(3); CopycatServer server = servers.get(0); server.cluster().onJoin(m -> { m.onStatusChange(s -> { threadAssertEquals(s, Member.Status.UNAVAILABLE); resume(); }); }); Member member = nextMember(type); CopycatServer joiner = createServer(member); joiner.join(members.stream().map(Member::serverAddress).collect(Collectors.toList())).thenRun(this::resume); await(10000); joiner.shutdown().thenRun(this::resume); await(10000, 2); }
/** * Tests detecting an availability change of a passive member on a reserve member. */ public void testReservePassiveAvailabilityChange() throws Throwable { createServers(3); CopycatServer passive = createServer(nextMember(Member.Type.PASSIVE)); passive.join(members.stream().map(Member::serverAddress).collect(Collectors.toList())).thenRun(this::resume); CopycatServer reserve = createServer(nextMember(Member.Type.RESERVE)); reserve.join(members.stream().map(Member::serverAddress).collect(Collectors.toList())).thenRun(this::resume); await(10000, 2); reserve.cluster().member(passive.cluster().member().address()).onStatusChange(s -> { threadAssertEquals(s, Member.Status.UNAVAILABLE); resume(); }); passive.shutdown().thenRun(this::resume); await(10000, 2); }
/** * Tests submitting a linearizable event that publishes to all sessions. */ private void testManyEventsAfterLeaderShutdown(int nodes) throws Throwable { List<CopycatServer> servers = createServers(nodes); CopycatClient client = createClient(); client.onEvent("test", message -> { threadAssertNotNull(message); resume(); }); for (int i = 0; i < 10; i++) { client.submit(new TestEvent(true)).thenAccept(result -> { threadAssertNotNull(result); resume(); }); await(30000, 2); } CopycatServer leader = servers.stream().filter(s -> s.state() == CopycatServer.State.LEADER).findFirst().get(); leader.shutdown().get(10, TimeUnit.SECONDS); for (int i = 0; i < 10; i++) { client.submit(new TestEvent(true)).thenAccept(result -> { threadAssertNotNull(result); resume(); }); await(30000, 2); } }
/** * Tests detecting an availability change of a reserve member on a passive member. */ public void testPassiveReserveAvailabilityChange() throws Throwable { createServers(3); CopycatServer passive = createServer(nextMember(Member.Type.PASSIVE)); passive.join(members.stream().map(Member::serverAddress).collect(Collectors.toList())).thenRun(this::resume); await(10000); Member reserveMember = nextMember(Member.Type.RESERVE); passive.cluster().onJoin(member -> { threadAssertEquals(member.address(), reserveMember.address()); member.onStatusChange(s -> { threadAssertEquals(s, Member.Status.UNAVAILABLE); resume(); }); }); CopycatServer reserve = createServer(reserveMember); reserve.join(members.stream().map(Member::serverAddress).collect(Collectors.toList())).thenRun(this::resume); await(10000); reserve.shutdown().thenRun(this::resume); await(10000, 2); }
follower.shutdown().get(10, TimeUnit.SECONDS);
leader.shutdown().get(10, TimeUnit.SECONDS);