Class PersistenceManager

java.lang.Object
de.bsvrz.ars.ars.persistence.PersistenceManager
All Implemented Interfaces:
TaskManager, TaskManagerInterface, ContainerCreator, DataIdentificationManager, DataGapManager

public final class PersistenceManager extends Object implements ContainerCreator, DataGapManager, TaskManager
Zentrale Persistenz-Verwaltung für die Archivierung von Daten auf einem Speichermedium vom Typ A (Festplatte) und die entsprechende Meta-Daten-Verwaltung.
  • Field Details

    • BACKUP_DIR_NAME

      public static final String BACKUP_DIR_NAME
      Name des Verzeichnisses für das Datenkonsistente Backup
      See Also:
    • RESTART_TIME_FILE_NAME

      public static final String RESTART_TIME_FILE_NAME
      Name der Datei mit den Datenzeitinformationen für den Neustart
      See Also:
  • Constructor Details

    • PersistenceManager

      public PersistenceManager(TaskManagerInterface archMgr, Path archPath, TimeDomain<?> domain)
      Erzeugt den Persistenz-Manager.
      Parameters:
      archMgr - Archiv-Manager oder andere Implementierung von TaskManagerInterface (insb. für Tests)
      archPath - Archivierungs-Verzeichnis
      domain - Klasse, die die Unterteilung der Persistenzverzeichnisse definiert
  • Method Details

    • setDeleteBrokenContainers

      public static void setDeleteBrokenContainers(boolean deleteBrokenContainers)
      Setzt, ob defekte Containerdateien umbenannt werden sollen
      Parameters:
      deleteBrokenContainers - Sollen defekte Containerdateien umbenannt werden?
    • shouldDeleteBrokenContainers

      public boolean shouldDeleteBrokenContainers()
      Description copied from interface: DataIdentificationManager
      Gibt zurück, ob bei Fehlern beim Lesen von Containerdateien die Datei umbenannt (und damit deaktiviert) werden soll.
      Specified by:
      shouldDeleteBrokenContainers in interface DataIdentificationManager
      Returns:
      Defekte Container umbenennen/löschen?
    • getGapFilePath

      @NotNull public Path getGapFilePath(IdDataIdentification dataIdentification)
      Gibt den Dateipfad zurück, in dem Lückendateien gespeichert werden sollen
      Parameters:
      dataIdentification - Datenidentifikation
      Returns:
      Dateipfad
    • initialize

      Initialisiert die vorhandenen Wochenverzeichnisse von der Festplatte
      Throws:
      IOException - Lesefehler
      InterruptedException - Unterbrochen
      PersistenceException - Lesefehler
      DirectoryIsLockedException - Das aktuelle Persistenzverzeichnis ist noch gesperrt (_isActive.flag-Datei existiert)
    • deleteSimVar

      public void deleteSimVar(SyncKey<IdDataIdentification> syncKey) throws PersistenceException
      Diese Methode loescht das komplette Verzeichnis eines DataIdentNode mit allen Unterverzeichnissen der Datensatzarten und aller darin befindlichen Datencontainern; damit werden alle archivierten Datensätze einer Simulationsvariante geloescht. Der DataIdentNode muss in der Verwaltung aus dem DataIdentTree geloescht werden. Falls die Simulationsvariante gleich null ist, oder das Verzeichnis nicht geloescht werden konnte, wird eine PersistenceException geworfen.
      Parameters:
      syncKey - Schlüssel für Zugriff auf Indexknoten
      Throws:
      PersistenceException - Schreibfehler im Persistenzverzeichnis
    • deletePath

      public static void deletePath(Path path) throws IOException
      Löscht ein Verzeichnis inklusive enthaltener Dateien.
      Parameters:
      path - Verzeichnis
      Throws:
      IOException - Mögliche Exception
    • prepareShutdown

      public void prepareShutdown() throws InterruptedException
      Die Methode prepareShutdown wird beim Herunterfahren des Archivsystems ausgeführt.
      Throws:
      InterruptedException - Wenn der Thread beim Warten auf das Schließen der Indexdateien unterbrochen wurde
    • startupProcedure

      public boolean startupProcedure(RebuildMode rebuildMode)
      Versucht, die StartUp-Properties-Datei einzulesen. Wenn das nicht gelingt, wird das gesamte Persistenzverzeichnis (RestorePersDirTsk) durchlaufen und versucht, einen gueltigen Startpunkt wiederherzustellen. Das Persistenzverzeichnis wird in InQueuesMgr.NUM_OF_ARCH_QUEUES_ONLINE Teile aufgeteilt, die jeweils von einem Thread bearbeitet werden (zwecks Performance). Am Schluss wird die StartUp-Properties-Datei geloescht. Beim Herunterfahren wird in prepareShutdown() die Datei neu geschrieben. Daran kann das ArS beim nächsten Start erkennen, ob es ordnungsgemäß heruntergefahren wurde oder ob ein Wiederherstellungslauf erforderlich ist.
      Parameters:
      rebuildMode - Wiederherstellungsmodus
      Returns:
      Wahr, falls der Durchlauf des Persistenzverzeichnisses erfolgreich war und das Archivsystem starten kann, falsch sonst.
    • getStatistics

      public PersistenceManager.Statistics getStatistics()
      Gibt Statistiken von diesem PersistenceManager-Objekt zurück.
      Returns:
      Statistiken (Typ Statistics)
    • nextContainerID

      public long nextContainerID()
      Erhoeht nextContainerID um 1 und gibt den Wert zurück.
      Specified by:
      nextContainerID in interface ContainerCreator
      Returns:
      als nächste zu verwendende Container-ID
    • getCloseThreadCount

      public int getCloseThreadCount()
      Description copied from interface: ContainerCreator
      Gibt die Anzahl Threads zurück, die für das Schließen von Container- und Indexdateien benutzt werden sollen.
      Specified by:
      getCloseThreadCount in interface ContainerCreator
      Returns:
      Anzahl Threads (>= 1)
    • getLastContainerID

      public long getLastContainerID()
      Returns:
      Letzte vergebe ContainerID
    • saveUnsubscriptionTime

      public void saveUnsubscriptionTime()
      Sichert den letzten Zeitpunkt, wo gültige Daten empfangen wurden bzw. beim Beenden wo Daten abgemeldet wurden. Dieser Zeitpunkt wird nach einem Neustart als Grundlage für die Bildung von potenziellen Datenlücken verwendet.
    • saveUnsubscriptionTime

      public void saveUnsubscriptionTime(com.google.common.collect.Multimap<Long,IdDataIdentification> didForUnsubscriptionTime, Path unsubscriptionFile)
      Sichert den letzten Zeitpunkt, wo gültige Daten empfangen wurden bzw. beim Beenden wo Daten abgemeldet wurden. Dieser Zeitpunkt wird nach einem Neustart als Grundlage für die Bildung von potenziellen Datenlücken verwendet.
      Parameters:
      didForUnsubscriptionTime - Zu schreibende Zeitstempel
      unsubscriptionFile - Datei, die geschrieben wird.
    • getLastContainerHeaders

      @Nullable public ContainerHeaders getLastContainerHeaders(LockedContainerDirectory containerDirectory) throws IndexException
      Ermittelt die Header vom letzten Container (vom Container mit der größten ID)
      Parameters:
      containerDirectory - Referenz auf die gelockte Datenidentifikation und Datenart für den Zugriff auf Containerdaten (Datenidentifikation + ADK, unabhängig vom spezifischen Persistenzverzeichnis)
      Returns:
      ContainerHeaders
      Throws:
      IndexException - wenn der Indexzugriff fehlschlägt
    • getLastDataSet

      Ermittelt den zuletzt archivierten Datensatz einer Datenidentifikation und Datenart
      Parameters:
      containerDirectory - Referenz auf die gelockte Datenidentifikation und Datenart für den Zugriff auf Containerdaten (Datenidentifikation + ADK, unabhängig vom spezifischen Persistenzverzeichnis)
      Returns:
      ContainerHeaders
      Throws:
      IndexException - wenn der Indexzugriff fehlschlägt
      SynchronizationFailedException - Synchronisierung fehlgeschlagen
      PersistenceException - Persistenzfehler
    • lockIndex

      Description copied from interface: DataIdentificationManager
      Muss immer vor Zugriffen auf den kritischen Bereich (die Indexe oder Container) der Datenidentifikation aufgerufen werden.

      Wenn ein anderer Task sich im kritischen Bereich befindet, blockiert diese Methode bis der kritische Bereich wieder frei ist.

      Da der Index-Bereich möglicherweise von vielen Tasks benutzt wird (und auch Zugriffe beim Archivieren von Daten erfolgen sollte), der Bereich so schnell wie möglich wieder verlassen werden. Es ist zwingend erforderlich, das zurückgegebene Lock-Objekt nach Benutzung zu schließen, sonst können andere Threads blockiert werden.

      Beispiel-Code:

      
       	 try(SyncKey<IdDataIdentification> lock = archMgr.lockIndex(din.getDataIdentification())) {
       		  // Tue was mit den Indexen
         }
       

      Das zurückgegebene SyncKey-Objekt verhält sich wie ein ReentrantLock, es ist also möglich, ein zweites Lock zu erhalten, wenn bereits ein Lock geholt wurde.

      Specified by:
      lockIndex in interface DataIdentificationManager
      Parameters:
      dataIdentification - Datenidentifikation
      Returns:
      Lock
      Throws:
      SynchronizationFailedException - Synchronisierung ist fehlgeschlagen (Unterbrochen beim Warten)
    • getIndexLocks

      public com.google.common.collect.SetMultimap<IdDataIdentification,SyncKey<IdDataIdentification>> getIndexLocks()
      Gibt alle aktuell genutzten Locks zur Synchronisation auf die Datenidentifikationen zurück.
      Returns:
      Locks
    • assertNoLocks

      public void assertNoLocks()
      Testmethode fürs Debugging, stellt sicher, dass aktuell keine Locks vom aktuellen Thread gehalten werden. Dieser Aufruf kann eingefügt werden, wenn eine Methode einen blockierenden Aufruf macht (z. B. auf Netzwerkantwort warten). Dies sollte aus Deadlock-Gefahr-Gründen nicht gemacht werden, während ein Index gelockt ist.
    • getActivePersistenceDirectory

      @Nullable public ActivePersistenceDirectory getActivePersistenceDirectory(int simVariant)
      Gibt das aktive Persistenzverzeichnis (in das gerade aktiviert wird) zurück.
      Parameters:
      simVariant - Simulationsvariante
      Returns:
      Persistenzverzeichnis, oder null, wenn gerade keines zum Beschreiben benutzt wird.
    • getPersistenceDirectories

      public List<? extends PersistenceDirectory> getPersistenceDirectories(int simVariant, SequenceSpecification sequenceSpecification)
      Ermittelt relevante Persistenzverzeichnisse. Achtung: Die zurückgegebenen Verzeichnisse sind grob nach der angegebenen SequenceSpecification gefiltert. D. h. der Anfangs-Zustand und ein ggf. nachfolgender Datensatz fehlen in sehr ungünstigen Fällen eventuell, und zwar wenn die Grenze des Anfragebereichs genau auf einem Wechsel des Wochenverzeichnisses liegt.

      Daher muss in diesen Fällen #validateIndexResult aufgerufen werden.

      Parameters:
      simVariant - Simulationsvariante (oder 0 für "normale" Daten)
      sequenceSpecification - Anfragebereich
      Returns:
      Liste mit Persistenzverzeichnissen
    • getPersistenceDirectories

      public List<? extends PersistenceDirectory> getPersistenceDirectories(int simVariant)
      Gibt alle Persistenzverzeichnisse einer Simulationsvariante zurück.
      Parameters:
      simVariant - Simulationsvariante (oder 0 für "normale" Daten)
      Returns:
      alle Persistenzverzeichnisse, die zurückgegebene Liste ist immutable.
    • getIndexResult

      public LocatedIndexResult<IndexValues> getIndexResult(LockedContainerDirectory containerDirectory, de.bsvrz.dav.daf.main.archive.ArchiveTimeSpecification archiveTimeSpecification) throws IndexException
      Führt eine Index-Abfrage über mehrere Persistenzverzeichnisse durch
      Parameters:
      containerDirectory - Gelocktes Containerverzeichnis
      archiveTimeSpecification - Archivzeitspezifikation
      Returns:
      Index-Ergebnis
      Throws:
      IndexException - Fehler beim Index-Zugriff
    • getIndexResult

      public LocatedIndexResult<IndexValues> getIndexResult(LockedContainerDirectory containerDirectory, SequenceSpecification sequenceSpecification) throws IndexException
      Führt eine Index-Abfrage über mehrere Persistenzverzeichnisse durch
      Parameters:
      containerDirectory - Gelocktes Containerverzeichnis
      sequenceSpecification - Abfragebereich
      Returns:
      Index-Ergebnis
      Throws:
      IndexException - Fehler beim Index-Zugriff
    • createSequenceFromArchiveTimeSpecification

      public SequenceSpecification createSequenceFromArchiveTimeSpecification(de.bsvrz.dav.daf.main.archive.ArchiveTimeSpecification ats, LockedContainerDirectory containerDirectory) throws IndexException
      Konvertiert eine ArchiveTimeSpecification (aus einer Anfrage) in eine SequenceSpecification. Es werden nur absolute ArchiveTimeSpecification-Objekte unterstützt.
      Parameters:
      ats - Archivzeitspezifikation
      containerDirectory - Containerverzeichnis
      Returns:
      SequenceSpecification
      Throws:
      IndexException - Fehler beim Index-Zugriff
    • getBackupConfigurationDirectory

      public Path getBackupConfigurationDirectory()
    • deletePersistenceDirectory

      public void deletePersistenceDirectory(ActivePersistenceDirectory directory) throws PersistenceException
      Löscht das Persistenzverzeichnis von einer Simulation komplett vom Datenträger. Es dürfen keine Verzeichnisse übergeben werden, die nicht von Simulationen können, dann wird ein Fehler geworfen.
      Parameters:
      directory - Persistenzverzeichnis der Simulation.
      Throws:
      PersistenceException - Fehler beim Löschen
    • updateArchTime

      public void updateArchTime(long archTime) throws PersistenceException
      Diese Methode wird aufgerufen, um die aktuelle Archivzeit zu setzen. Diese Methode wird aufgerufen, bevor ein Datensatz archiviert wird, damit die Persistenzschicht die erforderlichen Arbeiten durchführen kann, also z. B. ein neues Wochenverzeichnis anzulegen.
      Parameters:
      archTime - Aktuelle Archivzeit
      Throws:
      PersistenceException - Fehler beim Erstellen eines neuen Persistenzverzeichnisses
    • updateAndGetActivePersistenceDirectory

      @NotNull public ActivePersistenceDirectory updateAndGetActivePersistenceDirectory(long archTime, int simVariant) throws PersistenceException
      Diese Methode wird aufgerufen, um die aktuelle Archivzeit zu setzen und gibt gleichzeitig das zugehörige aktive Persistenzverzeichnis zurück. Diese Methode wird aufgerufen, bevor ein Datensatz archiviert wird, damit die Persistenzschicht die erforderlichen Arbeiten durchführen kann, also z. B. ein neues Wochenverzeichnis anzulegen.

      Im Gegensatz zu getActivePersistenceDirectory(int) wird nie null zurückgegeben.

      Parameters:
      archTime - Aktuelle Archivzeit
      simVariant - Simulationsvariante
      Returns:
      Persistenzverzeichnis für die angegebenen Dateninformationen.
      Throws:
      PersistenceException - Fehler beim Erstellen eines neuen Persistenzverzeichnisses
    • getRootPath

      public Path getRootPath()
      Gibt das Wurzelverzeichnis der Persistenz zurück.
      Returns:
      Wurzelverzeichnis
    • getPersistenceDirectoryManager

      public PersistenceDirectoryManager getPersistenceDirectoryManager()
      Gibt die Verwaltung der einzelnen Unterverzeichnisse zurück.
      Returns:
      Verwaltungsschicht für Verzeichnisse
    • getDataIdentTree

      public DataIdentTree getDataIdentTree()
      Description copied from interface: ContainerCreator
      Gibt den DataIdentTree zurück, der zu Datenidentifikationen zusatzinformationen enthält.
      Specified by:
      getDataIdentTree in interface ContainerCreator
      Returns:
      den DataIdentTree
    • getIndexCacheMaxSize

      public int getIndexCacheMaxSize()
      Description copied from interface: DataIdentificationManager
      Gibt die maximale Größe für Index-Caches zurück
      Specified by:
      getIndexCacheMaxSize in interface DataIdentificationManager
      Specified by:
      getIndexCacheMaxSize in interface TaskManagerInterface
      Returns:
      Maximale Größe in Bytes
    • formatObj

      public String formatObj(long objId)
      Die Methode formatObj gibt eine Objekt-ID als lesbaren String aus (z. B. ermitteln der Pid falls möglich)
      Specified by:
      formatObj in interface DataIdentificationManager
      Parameters:
      objId - von Typ long
      Returns:
      String
    • isRangeUnavailable

      public boolean isRangeUnavailable(long fromArchiveTime, long toArchiveTime)
      Description copied from interface: DataGapManager
      Prüft, ob sich Teile des Persistenzverzeichnisses zwischen 2 Datensätzen nicht mehr im direkten Zugriff befinden, also ausgelagert oder gelöscht wurden. Es wird davon ausgegangen, dass die Zeitstempel selbst zu Daten gehören, die gelesen wurden und also noch im Zugriff sind.
      Specified by:
      isRangeUnavailable in interface DataGapManager
      Parameters:
      fromArchiveTime - Start-Archivzeit in Epoch-Millis
      toArchiveTime - End-Archivzeit in Epoch-Millis
      Returns:
      true, falls der Bereich nicht vollständig verfügbar ist
    • wasTerminated

      public boolean wasTerminated()
      Description copied from interface: TaskManagerInterface
      Gibt true zurück, wenn das System terminiert wurde.
      Specified by:
      wasTerminated in interface TaskManagerInterface
      Returns:
      true, wenn das System terminiert wurde, sonst false
    • getNumCloseIndexThreads

      public int getNumCloseIndexThreads()
      Specified by:
      getNumCloseIndexThreads in interface TaskManagerInterface
    • getRuntimeControl

      @Nullable public RuntimeControl getRuntimeControl()
      Description copied from interface: TaskManagerInterface
      Gibt die aktuelle Laufzeitsteuerung zurück. Falls das System noch nicht voll initialisiert ist, wird null zurückgegeben.
      Specified by:
      getRuntimeControl in interface TaskManagerInterface
      Returns:
      die aktuelle Laufzeitsteuerung
    • suspendTaskIfNecessary

      public void suspendTaskIfNecessary(Task task) throws InterruptedException
      Description copied from interface: TaskManagerInterface
      Die Methode blockiert und hält damit den aufrufenden Task an, wenn dies (z. B. wegen Überlastung) notwendig ist.
      Specified by:
      suspendTaskIfNecessary in interface TaskManagerInterface
      Parameters:
      task - Task
      Throws:
      InterruptedException - Unterbrochen beim Anhalten
    • countDataInQueues

      public long countDataInQueues()
      Specified by:
      countDataInQueues in interface TaskManagerInterface
    • estimateQueueMemoryUsage

      public long estimateQueueMemoryUsage()
      Specified by:
      estimateQueueMemoryUsage in interface TaskManagerInterface
    • getNumCheckPersistenceThreads

      public int getNumCheckPersistenceThreads()
      Specified by:
      getNumCheckPersistenceThreads in interface TaskManagerInterface
    • getPersistenceManager

      public PersistenceManager getPersistenceManager()
      Description copied from interface: TaskManager
      Gibt den PersistenzManager zurück.
      Specified by:
      getPersistenceManager in interface TaskManager
      Returns:
      den PersistenzManager