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

io.camunda.zeebe.broker.system.partitions.impl.PartitionProcessingState Maven / Gradle / Ivy

There is a newer version: 8.7.0-alpha1
Show newest version
/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
 * one or more contributor license agreements. See the NOTICE file distributed
 * with this work for additional information regarding copyright ownership.
 * Licensed under the Camunda License 1.0. You may not use this file
 * except in compliance with the Camunda License 1.0.
 */
package io.camunda.zeebe.broker.system.partitions.impl;

import io.atomix.raft.partition.RaftPartition;
import io.camunda.zeebe.broker.exporter.stream.ExporterPhase;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;

public class PartitionProcessingState {

  private static final String PERSISTED_PAUSE_STATE_FILENAME = ".processorPaused";
  private static final String PERSISTED_EXPORTER_PAUSE_STATE_FILENAME = ".exporterPaused";
  private boolean isProcessingPaused;
  private ExporterPhase exporterPhase;
  private final RaftPartition raftPartition;
  private boolean diskSpaceAvailable;

  public PartitionProcessingState(final RaftPartition raftPartition) {
    this.raftPartition = raftPartition;
    initProcessingStatus();
    initExportingState();
  }

  public boolean isDiskSpaceAvailable() {
    return diskSpaceAvailable;
  }

  public void setDiskSpaceAvailable(final boolean diskSpaceAvailable) {
    this.diskSpaceAvailable = diskSpaceAvailable;
  }

  public boolean isProcessingPaused() {
    return isProcessingPaused;
  }

  public void resumeProcessing() throws IOException {
    final File persistedPauseState = getPersistedPauseState(PERSISTED_PAUSE_STATE_FILENAME);
    Files.deleteIfExists(persistedPauseState.toPath());
    if (!persistedPauseState.exists()) {
      isProcessingPaused = false;
    }
  }

  @SuppressWarnings({"squid:S899"})
  public void pauseProcessing() throws IOException {
    final File persistedPauseState = getPersistedPauseState(PERSISTED_PAUSE_STATE_FILENAME);
    persistedPauseState.createNewFile();
    if (persistedPauseState.exists()) {
      isProcessingPaused = true;
    }
  }

  private File getPersistedPauseState(final String filename) {
    return raftPartition.dataDirectory().toPath().resolve(filename).toFile();
  }

  private void initProcessingStatus() {
    isProcessingPaused = getPersistedPauseState(PERSISTED_PAUSE_STATE_FILENAME).exists();
  }

  public boolean shouldProcess() {
    return isDiskSpaceAvailable() && !isProcessingPaused();
  }

  public boolean isExportingPaused() {
    return exporterPhase.equals(ExporterPhase.PAUSED);
  }

  public ExporterPhase getExporterPhase() {
    return exporterPhase;
  }

  @SuppressWarnings({"squid:S899"})
  /** Returns true if exporting is paused. This method overrides the effects of soft pause. */
  public boolean pauseExporting() {
    try {
      setPersistedExporterPhase(ExporterPhase.PAUSED);
    } catch (final IOException e) {
      return false;
    }
    return true;
  }

  /** Returns true if soft exporting is paused. This method overrides the effects of hard pause. */
  public boolean softPauseExporting() {
    try {
      setPersistedExporterPhase(ExporterPhase.SOFT_PAUSED);
    } catch (final IOException e) {
      return false;
    }
    return true;
  }

  /** Returns true if exporting is resumed. This method resumes both soft and "hard" exporting. */
  public boolean resumeExporting() {
    try {
      setPersistedExporterPhase(ExporterPhase.EXPORTING);
    } catch (final IOException e) {
      return false;
    }
    return true;
  }

  void setPersistedExporterPhase(final ExporterPhase state) throws IOException {
    exporterPhase = state;
    if (state.equals(ExporterPhase.EXPORTING)) {
      // since exporting is the default state, we can delete the file
      Files.deleteIfExists(
          getPersistedPauseState(PERSISTED_EXPORTER_PAUSE_STATE_FILENAME).toPath());
      return;
    }

    final File persistedExporterPauseState =
        getPersistedPauseState(PERSISTED_EXPORTER_PAUSE_STATE_FILENAME);
    Files.writeString(
        persistedExporterPauseState.toPath(),
        state.name(),
        StandardCharsets.UTF_8,
        StandardOpenOption.DSYNC,
        StandardOpenOption.CREATE);
  }

  private void initExportingState() {
    try {
      if (!getPersistedPauseState(PERSISTED_EXPORTER_PAUSE_STATE_FILENAME).exists()) {
        setPersistedExporterPhase(ExporterPhase.EXPORTING);
        exporterPhase = ExporterPhase.EXPORTING;
      } else {
        final var state =
            Files.readString(
                getPersistedPauseState(PERSISTED_EXPORTER_PAUSE_STATE_FILENAME).toPath());
        if (state == null || state.isEmpty() || state.isBlank()) {
          // Backwards compatibility. If the file exists, it is paused.
          exporterPhase = ExporterPhase.PAUSED;
          return;
        }
        exporterPhase = ExporterPhase.valueOf(state);
      }
    } catch (final IOException e) {
      // exporting is the default state
      exporterPhase = ExporterPhase.EXPORTING;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy