/** * Starts a corfu server and increments the epoch from 0 to 1. * The server is then restarted and the new layout fetch is expected to return a layout with * epoch 2 or greater (recovery can fail and epoch can increase) as the state is not cleared * and the restart forces a recovery to increment the epoch. * * @throws Exception */ @Test public void restartTest() throws Exception { final int PORT_0 = 9000; Process corfuServer = runPersistentServer(corfuSingleNodeHost, PORT_0, true); CorfuRuntime corfuRuntime = createDefaultRuntime(); Layout l = incrementClusterEpoch(corfuRuntime); corfuRuntime.getLayoutView().getRuntimeLayout(l).getBaseClient("localhost:9000") .restart().get(); waitForEpochChange(epoch -> epoch >= l.getEpoch() + 1, corfuRuntime); assertThat(shutdownCorfuServer(corfuServer)).isTrue(); }
public void restartServer(CorfuRuntime corfuRuntime, String endpoint) { corfuRuntime.invalidateLayout(); RuntimeLayout runtimeLayout = corfuRuntime.getLayoutView().getRuntimeLayout(); try { runtimeLayout.getBaseClient(endpoint).restart().get(); } catch (ExecutionException | InterruptedException e) { log.error("Error: {}", e); } // The shutdown and restart can take an unknown amount of time and there is a chance that // the newer runtime may also connect to the older corfu server (before restart). // Hence the while loop. while (true) { try { if (corfuRuntime.getLayoutView().getLayout().getEpoch() == (runtimeLayout.getLayout().getEpoch() + 1)) { break; } Sleep.MILLISECONDS.sleepUninterruptibly(PARAMETERS.TIMEOUT_SHORT); corfuRuntime.invalidateLayout(); } catch (ShutdownException se) { log.error("Shutdown Exception thrown connecting to server:{} ignored, {}", endpoint, se); } } }