FileBasedTransientSnapshot implements TransientSnapshot { @Override public boolean take(final Predicate<Path> takeSnapshot) { final var snapshotMetrics = snapshotStore.getSnapshotMetrics(); boolean failed; try (final var ignored = snapshotMetrics.startTimer()) { try { failed = !takeSnapshot.test(getPath()); } catch (final Exception exception) { LOGGER.warn("Catched unexpected exception on taking snapshot ({})", metadata, exception); failed = true; } } if (failed) { abort(); } return !failed; } FileBasedTransientSnapshot(
      final FileBasedSnapshotMetadata metadata,
      final Path directory,
      final FileBasedSnapshotStore snapshotStore); @Override boolean take(final Predicate<Path> takeSnapshot); @Override void abort(); @Override PersistedSnapshot persist(); Path getPath(); @Override String toString();  }
@Test public void shouldTakeTransientSnapshot() { final var index = 1L; final var term = 2L; final var transientSnapshot = persistedSnapshotStore.newTransientSnapshot(index, term, 3, 4).orElseThrow(); transientSnapshot.take(this::createSnapshotDir); assertThat(snapshotsDir.toFile().listFiles()).isEmpty(); final var snapshotDirs = pendingSnapshotsDir.toFile().listFiles(); assertThat(snapshotDirs).isNotNull().hasSize(1); final var pendingSnapshotDir = snapshotDirs[0]; final FileBasedSnapshotMetadata pendingSnapshotId = FileBasedSnapshotMetadata.ofFileName(pendingSnapshotDir.getName()).orElseThrow(); assertThat(pendingSnapshotId.getIndex()).isEqualTo(1); assertThat(pendingSnapshotId.getTerm()).isEqualTo(2); assertThat(pendingSnapshotId.getProcessedPosition()).isEqualTo(3); assertThat(pendingSnapshotId.getExportedPosition()).isEqualTo(4); assertThat(pendingSnapshotDir.listFiles()) .isNotNull() .extracting(File::getName) .containsExactly("file1.txt"); }
@Test public void shouldPurgePendingOnStore() throws Exception { final var index = 1L; final var term = 0L; final var transientSnapshot = persistedSnapshotStore.newTransientSnapshot(index, term, 1, 0); transientSnapshot.orElseThrow().take(this::createSnapshotDir); persistedSnapshotStore.purgePendingSnapshots(); assertThat(snapshotsDir.toFile().listFiles()).isEmpty(); assertThat(pendingSnapshotsDir.toFile().listFiles()).isEmpty(); }
@Test public void shouldCleanUpPendingDirOnFailingTakeSnapshot() { final var index = 1L; final var term = 0L; final var oldTransientSnapshot = persistedSnapshotStore.newTransientSnapshot(index, term, 1, 0).orElseThrow(); oldTransientSnapshot.take( path -> { try { FileUtil.ensureDirectoryExists(path); } catch (final IOException e) { throw new UncheckedIOException(e); } return false; }); assertThat(pendingSnapshotsDir.toFile().listFiles()).isEmpty(); assertThat(snapshotsDir.toFile().listFiles()).isEmpty(); }
@Test public void shouldCleanUpPendingDirOnException() { final var index = 1L; final var term = 0L; final var oldTransientSnapshot = persistedSnapshotStore.newTransientSnapshot(index, term, 1, 0).orElseThrow(); oldTransientSnapshot.take( path -> { try { FileUtil.ensureDirectoryExists(path); throw new RuntimeException("EXPECTED"); } catch (final IOException e) { throw new UncheckedIOException(e); } }); assertThat(pendingSnapshotsDir.toFile().listFiles()).isEmpty(); assertThat(snapshotsDir.toFile().listFiles()).isEmpty(); }