Pass a repository instance into the bulk archiving and pruning methods.

This is a better approach than opening a new session for each, and it makes it easier to write unit tests.
This commit is contained in:
CalDescent 2021-09-28 20:29:53 +01:00
parent ce5bc80347
commit 0d17f02191
4 changed files with 278 additions and 279 deletions

View File

@ -2,8 +2,11 @@ package org.qortal.controller;
import java.awt.TrayIcon.MessageType; import java.awt.TrayIcon.MessageType;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.Security; import java.security.Security;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -409,8 +412,11 @@ public class Controller extends Thread {
try { try {
RepositoryFactory repositoryFactory = new HSQLDBRepositoryFactory(getRepositoryUrl()); RepositoryFactory repositoryFactory = new HSQLDBRepositoryFactory(getRepositoryUrl());
RepositoryManager.setRepositoryFactory(repositoryFactory); RepositoryManager.setRepositoryFactory(repositoryFactory);
RepositoryManager.archive();
RepositoryManager.prune(); try (final Repository repository = RepositoryManager.getRepository()) {
RepositoryManager.archive(repository);
RepositoryManager.prune(repository);
}
} catch (DataException e) { } catch (DataException e) {
// If exception has no cause then repository is in use by some other process. // If exception has no cause then repository is in use by some other process.
if (e.getCause() == null) { if (e.getCause() == null) {

View File

@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.qortal.repository.hsqldb.HSQLDBDatabaseArchiving; import org.qortal.repository.hsqldb.HSQLDBDatabaseArchiving;
import org.qortal.repository.hsqldb.HSQLDBDatabasePruning; import org.qortal.repository.hsqldb.HSQLDBDatabasePruning;
import org.qortal.repository.hsqldb.HSQLDBRepository;
import org.qortal.settings.Settings; import org.qortal.settings.Settings;
import java.sql.SQLException; import java.sql.SQLException;
@ -58,12 +59,12 @@ public abstract class RepositoryManager {
} }
} }
public static boolean archive() { public static boolean archive(Repository repository) {
// Bulk archive the database the first time we use archive mode // Bulk archive the database the first time we use archive mode
if (Settings.getInstance().isArchiveEnabled()) { if (Settings.getInstance().isArchiveEnabled()) {
if (RepositoryManager.canArchiveOrPrune()) { if (RepositoryManager.canArchiveOrPrune()) {
try { try {
return HSQLDBDatabaseArchiving.buildBlockArchive(); return HSQLDBDatabaseArchiving.buildBlockArchive(repository);
} catch (DataException e) { } catch (DataException e) {
LOGGER.info("Unable to build block archive. The database may have been left in an inconsistent state."); LOGGER.info("Unable to build block archive. The database may have been left in an inconsistent state.");
@ -76,18 +77,18 @@ public abstract class RepositoryManager {
return false; return false;
} }
public static boolean prune() { public static boolean prune(Repository repository) {
// Bulk prune the database the first time we use pruning mode // Bulk prune the database the first time we use pruning mode
if (Settings.getInstance().isPruningEnabled() || if (Settings.getInstance().isPruningEnabled() ||
Settings.getInstance().isArchiveEnabled()) { Settings.getInstance().isArchiveEnabled()) {
if (RepositoryManager.canArchiveOrPrune()) { if (RepositoryManager.canArchiveOrPrune()) {
try { try {
boolean prunedATStates = HSQLDBDatabasePruning.pruneATStates(); boolean prunedATStates = HSQLDBDatabasePruning.pruneATStates((HSQLDBRepository) repository);
boolean prunedBlocks = HSQLDBDatabasePruning.pruneBlocks(); boolean prunedBlocks = HSQLDBDatabasePruning.pruneBlocks((HSQLDBRepository) repository);
// Perform repository maintenance to shrink the db size down // Perform repository maintenance to shrink the db size down
if (prunedATStates && prunedBlocks) { if (prunedATStates && prunedBlocks) {
HSQLDBDatabasePruning.performMaintenance(); HSQLDBDatabasePruning.performMaintenance(repository);
return true; return true;
} }

View File

@ -5,6 +5,7 @@ import org.apache.logging.log4j.Logger;
import org.qortal.controller.Controller; import org.qortal.controller.Controller;
import org.qortal.repository.BlockArchiveWriter; import org.qortal.repository.BlockArchiveWriter;
import org.qortal.repository.DataException; import org.qortal.repository.DataException;
import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager; import org.qortal.repository.RepositoryManager;
import org.qortal.transform.TransformationException; import org.qortal.transform.TransformationException;
@ -29,8 +30,7 @@ public class HSQLDBDatabaseArchiving {
private static final Logger LOGGER = LogManager.getLogger(HSQLDBDatabaseArchiving.class); private static final Logger LOGGER = LogManager.getLogger(HSQLDBDatabaseArchiving.class);
public static boolean buildBlockArchive() throws DataException { public static boolean buildBlockArchive(Repository repository) throws DataException {
try (final HSQLDBRepository repository = (HSQLDBRepository)RepositoryManager.getRepository()) {
// Only build the archive if we have never done so before // Only build the archive if we have never done so before
int archiveHeight = repository.getBlockArchiveRepository().getBlockArchiveHeight(); int archiveHeight = repository.getBlockArchiveRepository().getBlockArchiveHeight();
@ -77,7 +77,6 @@ public class HSQLDBDatabaseArchiving {
return false; return false;
} }
} }
}
// If we got this far then something went wrong (most likely the app is stopping) // If we got this far then something went wrong (most likely the app is stopping)
return false; return false;

View File

@ -6,6 +6,7 @@ import org.qortal.controller.Controller;
import org.qortal.data.block.BlockData; import org.qortal.data.block.BlockData;
import org.qortal.repository.BlockArchiveWriter; import org.qortal.repository.BlockArchiveWriter;
import org.qortal.repository.DataException; import org.qortal.repository.DataException;
import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager; import org.qortal.repository.RepositoryManager;
import org.qortal.settings.Settings; import org.qortal.settings.Settings;
@ -38,8 +39,7 @@ public class HSQLDBDatabasePruning {
private static final Logger LOGGER = LogManager.getLogger(HSQLDBDatabasePruning.class); private static final Logger LOGGER = LogManager.getLogger(HSQLDBDatabasePruning.class);
public static boolean pruneATStates() throws SQLException, DataException { public static boolean pruneATStates(HSQLDBRepository repository) throws SQLException, DataException {
try (final HSQLDBRepository repository = (HSQLDBRepository)RepositoryManager.getRepository()) {
// Only bulk prune AT states if we have never done so before // Only bulk prune AT states if we have never done so before
int pruneHeight = repository.getATRepository().getAtPruneHeight(); int pruneHeight = repository.getATRepository().getAtPruneHeight();
@ -173,16 +173,14 @@ public class HSQLDBDatabasePruning {
repository.executeCheckedUpdate("CHECKPOINT"); repository.executeCheckedUpdate("CHECKPOINT");
// Now prune/trim the ATStatesData, as this currently goes back over a month // Now prune/trim the ATStatesData, as this currently goes back over a month
return HSQLDBDatabasePruning.pruneATStateData(); return HSQLDBDatabasePruning.pruneATStateData(repository);
}
} }
/* /*
* Bulk prune ATStatesData to catch up with the now pruned ATStates table * Bulk prune ATStatesData to catch up with the now pruned ATStates table
* This uses the existing AT States trimming code but with a much higher end block * This uses the existing AT States trimming code but with a much higher end block
*/ */
private static boolean pruneATStateData() throws SQLException, DataException { private static boolean pruneATStateData(Repository repository) throws DataException {
try (final HSQLDBRepository repository = (HSQLDBRepository) RepositoryManager.getRepository()) {
if (Settings.getInstance().isArchiveEnabled()) { if (Settings.getInstance().isArchiveEnabled()) {
// Don't prune ATStatesData in archive mode // Don't prune ATStatesData in archive mode
@ -241,10 +239,8 @@ public class HSQLDBDatabasePruning {
return true; return true;
} }
}
public static boolean pruneBlocks() throws SQLException, DataException { public static boolean pruneBlocks(Repository repository) throws SQLException, DataException {
try (final HSQLDBRepository repository = (HSQLDBRepository) RepositoryManager.getRepository()) {
// Only bulk prune AT states if we have never done so before // Only bulk prune AT states if we have never done so before
int pruneHeight = repository.getBlockRepository().getBlockPruneHeight(); int pruneHeight = repository.getBlockRepository().getBlockPruneHeight();
@ -312,12 +308,9 @@ public class HSQLDBDatabasePruning {
return true; return true;
} }
}
public static void performMaintenance() throws SQLException, DataException { public static void performMaintenance(Repository repository) throws SQLException, DataException {
try (final HSQLDBRepository repository = (HSQLDBRepository) RepositoryManager.getRepository()) {
repository.performPeriodicMaintenance(); repository.performPeriodicMaintenance();
} }
}
} }