@Override public void install(SnapshotReader reader) { List<ResourceHolder> resources = new ArrayList<>(this.resources.values()); Collections.sort(resources, (r1, r2) -> (int)(r1.id - r2.id)); for (ResourceHolder resource : resources) { if (resource.stateMachine instanceof Snapshottable) { ((Snapshottable) resource.stateMachine).install(reader); } } }
@Override public void install(SnapshotReader reader) { List<ResourceHolder> resources = new ArrayList<>(this.resources.values()); Collections.sort(resources, (r1, r2) -> (int)(r1.id - r2.id)); for (ResourceHolder resource : resources) { if (resource.stateMachine instanceof Snapshottable) { ((Snapshottable) resource.stateMachine).install(reader); } } }
/** * Installs a snapshot of the state machine state if necessary. * <p> * Snapshots are installed only if there's a local snapshot stored with a version equal to the * last applied index. */ private void installSnapshot() { // If the last stored snapshot has not yet been installed and its index matches the last applied state // machine index, install the snapshot. This requires that the state machine see all indexes sequentially // even for entries that have been compacted from the log. Snapshot currentSnapshot = state.getSnapshotStore().currentSnapshot(); if (currentSnapshot != null && currentSnapshot.index() > log.compactor().snapshotIndex() && currentSnapshot.index() == lastApplied && stateMachine instanceof Snapshottable) { // Install the snapshot in the state machine thread. Multiple threads can access snapshots, so we // synchronize on the snapshot object. In practice, this probably isn't even necessary and could prove // to be an expensive operation. Snapshots can be read concurrently with separate SnapshotReaders since // memory snapshots are copied to the reader and file snapshots open a separate FileBuffer for each reader. LOGGER.info("{} - Installing snapshot {}", state.getCluster().member().address(), currentSnapshot.index()); executor.executor().execute(() -> { synchronized (currentSnapshot) { try (SnapshotReader reader = currentSnapshot.reader()) { ((Snapshottable) stateMachine).install(reader); } } }); // Once a snapshot has been applied, snapshot dependent entries can be cleaned from the log. log.compactor().snapshotIndex(currentSnapshot.index()); } }
/** * Installs a snapshot of the state machine state if necessary. * <p> * Snapshots are installed only if there's a local snapshot stored with a version equal to the * last applied index. */ private void installSnapshot() { state.checkThread(); // If the last stored snapshot has not yet been installed and its index matches the last applied state // machine index, install the snapshot. This requires that the state machine see all indexes sequentially // even for entries that have been compacted from the log. Snapshot currentSnapshot = state.getSnapshotStore().currentSnapshot(); if (currentSnapshot != null && currentSnapshot.index() > log.compactor().snapshotIndex() && currentSnapshot.index() == lastApplied && stateMachine instanceof Snapshottable) { // Install the snapshot in the state machine thread. Multiple threads can access snapshots, so we // synchronize on the snapshot object. In practice, this probably isn't even necessary and could prove // to be an expensive operation. Snapshots can be read concurrently with separate SnapshotReaders since // memory snapshots are copied to the reader and file snapshots open a separate FileBuffer for each reader. LOGGER.info("{} - Installing snapshot {}", state.getCluster().member().address(), currentSnapshot.index()); executor.executor().execute(() -> { synchronized (currentSnapshot) { try (SnapshotReader reader = currentSnapshot.reader()) { ((Snapshottable) stateMachine).install(reader); } } }); // Once a snapshot has been applied, snapshot dependent entries can be cleaned from the log. log.compactor().snapshotIndex(currentSnapshot.index()); } }
/** * Installs a snapshot of the state machine state if necessary. * <p> * Snapshots are installed only if there's a local snapshot stored with a version equal to the * last applied index. */ private void installSnapshot() { state.checkThread(); // If the last stored snapshot has not yet been installed and its index matches the last applied state // machine index, install the snapshot. This requires that the state machine see all indexes sequentially // even for entries that have been compacted from the log. Snapshot currentSnapshot = state.getSnapshotStore().currentSnapshot(); if (currentSnapshot != null && currentSnapshot.index() > log.compactor().snapshotIndex() && currentSnapshot.index() == lastApplied && stateMachine instanceof Snapshottable) { // Install the snapshot in the state machine thread. Multiple threads can access snapshots, so we // synchronize on the snapshot object. In practice, this probably isn't even necessary and could prove // to be an expensive operation. Snapshots can be read concurrently with separate SnapshotReaders since // memory snapshots are copied to the reader and file snapshots open a separate FileBuffer for each reader. LOGGER.info("{} - Installing snapshot {}", state.getCluster().member().address(), currentSnapshot.index()); executor.executor().execute(() -> { synchronized (currentSnapshot) { try (SnapshotReader reader = currentSnapshot.reader()) { ((Snapshottable) stateMachine).install(reader); } } }); // Once a snapshot has been applied, snapshot dependent entries can be cleaned from the log. log.compactor().snapshotIndex(currentSnapshot.index()); } }