All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.zeebe.logstreams.state.StateSnapshotController Maven / Gradle / Ivy

There is a newer version: 0.16.4
Show newest version
/*
 * Copyright © 2017 camunda services GmbH ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.zeebe.logstreams.state;

import io.zeebe.db.ZeebeDb;
import io.zeebe.db.ZeebeDbFactory;
import io.zeebe.logstreams.impl.Loggers;
import io.zeebe.logstreams.spi.SnapshotController;
import io.zeebe.util.FileUtil;
import java.io.File;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
import org.slf4j.Logger;

/** Controls how snapshot/recovery operations are performed */
public class StateSnapshotController implements SnapshotController {
  private static final Logger LOG = Loggers.ROCKSDB_LOGGER;

  private final StateStorage storage;
  private final ZeebeDbFactory zeebeDbFactory;
  private ZeebeDb db;

  public StateSnapshotController(final ZeebeDbFactory rocksDbFactory, final StateStorage storage) {
    zeebeDbFactory = rocksDbFactory;
    this.storage = storage;
  }

  @Override
  public void takeSnapshot(final StateSnapshotMetadata metadata) {
    if (db == null) {
      throw new IllegalStateException("Cannot create snapshot of not open database.");
    }

    if (exists(metadata)) {
      return;
    }

    final File snapshotDir = storage.getSnapshotDirectoryFor(metadata);
    db.createSnapshot(snapshotDir);
  }

  @Override
  public StateSnapshotMetadata recover(
      long commitPosition, int term, Predicate filter) throws Exception {
    final List snapshots = storage.listRecoverable(commitPosition);
    return extractMostRecentSnapshot(snapshots, term, filter);
  }

  @Override
  public StateSnapshotMetadata recoverFromLatestSnapshot() throws Exception {
    return extractMostRecentSnapshot(storage.list(), 0, m -> true);
  }

  private StateSnapshotMetadata extractMostRecentSnapshot(
      List snapshots, int term, Predicate filter)
      throws Exception {
    final File runtimeDirectory = storage.getRuntimeDirectory();
    StateSnapshotMetadata recoveredMetadata = null;

    if (!snapshots.isEmpty()) {
      recoveredMetadata =
          snapshots.stream()
              .sorted(Comparator.reverseOrder())
              .filter(filter)
              .findFirst()
              .orElse(null);
    }

    if (runtimeDirectory.exists()) {
      FileUtil.deleteFolder(runtimeDirectory.getAbsolutePath());
    }

    if (recoveredMetadata != null) {
      final File snapshotPath = storage.getSnapshotDirectoryFor(recoveredMetadata);
      FileUtil.copySnapshot(runtimeDirectory, snapshotPath);
    } else {
      recoveredMetadata = StateSnapshotMetadata.createInitial(term);
    }

    return recoveredMetadata;
  }

  @Override
  public ZeebeDb openDb() {
    db = zeebeDbFactory.createDb(storage.getRuntimeDirectory());
    return db;
  }

  @Override
  public void purgeAll(Predicate matcher) throws Exception {
    final List others = storage.list(matcher);

    for (final StateSnapshotMetadata other : others) {
      FileUtil.deleteFolder(storage.getSnapshotDirectoryFor(other).getAbsolutePath());
      LOG.trace("Purged snapshot {}", other);
    }
  }

  private boolean exists(final StateSnapshotMetadata metadata) {
    return storage.getSnapshotDirectoryFor(metadata).exists();
  }

  @Override
  public void close() throws Exception {
    if (db != null) {
      db.close();
      db = null;
    }
  }

  public boolean isDbOpened() {
    return db != null;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy