Skip to content

Commit

Permalink
Move duplicated code to super class
Browse files Browse the repository at this point in the history
Signed-off-by: HenrikJannsen <[email protected]>
  • Loading branch information
HenrikJannsen committed Jun 28, 2024
1 parent ed5547a commit 59f2df9
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 234 deletions.
111 changes: 111 additions & 0 deletions core/src/main/java/bisq/core/app/misc/ExecutableForAppWithP2p.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,30 @@
package bisq.core.app.misc;

import bisq.core.app.BisqExecutable;
import bisq.core.app.TorSetup;
import bisq.core.btc.setup.WalletsSetup;
import bisq.core.btc.wallet.BsqWalletService;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.dao.DaoSetup;
import bisq.core.dao.monitoring.DaoStateMonitoringService;
import bisq.core.dao.node.full.RpcService;
import bisq.core.offer.OpenOfferManager;
import bisq.core.offer.bsq_swap.OpenBsqSwapOfferService;
import bisq.core.payment.TradeLimits;
import bisq.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
import bisq.core.user.Cookie;
import bisq.core.user.CookieKey;
import bisq.core.user.User;

import bisq.network.p2p.P2PService;
import bisq.network.p2p.P2PServiceListener;
import bisq.network.p2p.peers.PeerManager;

import bisq.common.Timer;
import bisq.common.UserThread;
import bisq.common.app.AppModule;
import bisq.common.app.DevEnv;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import bisq.common.file.JsonFileManager;
import bisq.common.handlers.ResultHandler;
Expand All @@ -41,6 +50,9 @@
import bisq.common.util.Profiler;
import bisq.common.util.SingleThreadExecutorUtils;

import com.google.inject.Key;
import com.google.inject.name.Names;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

Expand All @@ -51,10 +63,18 @@ public abstract class ExecutableForAppWithP2p extends BisqExecutable {
private static final long CHECK_MEMORY_PERIOD_SEC = 300;
protected static final long CHECK_SHUTDOWN_SEC = TimeUnit.HOURS.toSeconds(1);
protected static final long SHUTDOWN_INTERVAL = TimeUnit.HOURS.toMillis(24);
private static final long CHECK_CONNECTION_LOSS_SEC = 30;

private volatile boolean stopped;
private final long startTime = System.currentTimeMillis();
private TradeLimits tradeLimits;
private AppSetupWithP2PAndDAO appSetupWithP2PAndDAO;
protected P2PService p2PService;
protected DaoStateMonitoringService daoStateMonitoringService;

protected Cookie cookie;
private Timer checkConnectionLossTimer;
private Boolean preventPeriodicShutdownAtSeedNode;

public ExecutableForAppWithP2p(String fullName, String scriptName, String appName, String version) {
super(fullName, scriptName, appName, version);
Expand All @@ -76,15 +96,69 @@ protected void applyInjector() {
super.applyInjector();

appSetupWithP2PAndDAO = injector.getInstance(AppSetupWithP2PAndDAO.class);
p2PService = injector.getInstance(P2PService.class);
cookie = injector.getInstance(User.class).getCookie();
// Pin that as it is used in PaymentMethods and verification in TradeStatistics
tradeLimits = injector.getInstance(TradeLimits.class);
daoStateMonitoringService = injector.getInstance(DaoStateMonitoringService.class);
preventPeriodicShutdownAtSeedNode = injector.getInstance(Key.get(boolean.class,
Names.named(Config.PREVENT_PERIODIC_SHUTDOWN_AT_SEED_NODE)));
}

@Override
protected void startApplication() {
cookie.getAsOptionalBoolean(CookieKey.CLEAN_TOR_DIR_AT_RESTART).ifPresent(cleanTorDirAtRestart -> {
if (cleanTorDirAtRestart) {
injector.getInstance(TorSetup.class).cleanupTorFiles(() ->
cookie.remove(CookieKey.CLEAN_TOR_DIR_AT_RESTART),
log::error);
}
});

daoStateMonitoringService.addListener(new DaoStateMonitoringService.Listener() {
@Override
public void onCheckpointFailed() {
gracefulShutDown();
}
});

p2PService.addP2PServiceListener(new P2PServiceListener() {
@Override
public void onDataReceived() {
}

@Override
public void onNoSeedNodeAvailable() {
}

@Override
public void onNoPeersAvailable() {
}

@Override
public void onUpdatedDataReceived() {
}

@Override
public void onTorNodeReady() {
}

@Override
public void onHiddenServicePublished() {
ExecutableForAppWithP2p.this.onHiddenServicePublished();
}
});

appSetupWithP2PAndDAO.start();
}

protected void onHiddenServicePublished() {
if (!preventPeriodicShutdownAtSeedNode) {
startShutDownInterval();
}
UserThread.runAfter(this::setupConnectionLossCheck, 60);
}

@Override
protected void launchApplication() {
onApplicationLaunched();
Expand All @@ -95,10 +169,26 @@ public void onSetupComplete() {
log.info("onSetupComplete");
}


///////////////////////////////////////////////////////////////////////////////////////////
// UncaughtExceptionHandler implementation
///////////////////////////////////////////////////////////////////////////////////////////

@Override
public void handleUncaughtException(Throwable throwable, boolean doShutDown) {
if (throwable instanceof OutOfMemoryError || doShutDown) {
log.error("We got an OutOfMemoryError and shut down");
gracefulShutDown(() -> log.info("gracefulShutDown complete"));
}
}

// We don't use the gracefulShutDown implementation of the super class as we have a limited set of modules
@Override
public void gracefulShutDown(ResultHandler resultHandler) {
log.info("gracefulShutDown");
if (checkConnectionLossTimer != null) {
checkConnectionLossTimer.stop();
}
try {
if (injector != null) {
JsonFileManager.shutDownAllInstances();
Expand Down Expand Up @@ -216,4 +306,25 @@ protected void shutDown(GracefulShutDownHandler gracefulShutDownHandler) {
System.exit(1);
});
}

protected void setupConnectionLossCheck() {
// For dev testing (usually on BTC_REGTEST) we don't want to get the seed shut
// down as it is normal that the seed is the only actively running node.
if (Config.baseCurrencyNetwork() == BaseCurrencyNetwork.BTC_REGTEST) {
return;
}

if (checkConnectionLossTimer != null) {
return;
}

checkConnectionLossTimer = UserThread.runPeriodically(() -> {
if (injector.getInstance(PeerManager.class).getNumAllConnectionsLostEvents() > 1) {
// We set a flag to clear tor cache files at re-start. We cannot clear it now as Tor is used and
// that can cause problems.
injector.getInstance(User.class).getCookie().putAsBoolean(CookieKey.CLEAN_TOR_DIR_AT_RESTART, true);
shutDown(this);
}
}, CHECK_CONNECTION_LOSS_SEC);
}
}
125 changes: 13 additions & 112 deletions restapi/src/main/java/bisq/restapi/RestApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,41 +19,22 @@


import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.app.TorSetup;
import bisq.core.app.misc.ExecutableForAppWithP2p;
import bisq.core.dao.SignVerifyService;
import bisq.core.dao.governance.bond.reputation.BondedReputationRepository;
import bisq.core.dao.governance.bond.role.BondedRolesRepository;
import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.DaoStateSnapshotService;
import bisq.core.user.Cookie;
import bisq.core.user.CookieKey;
import bisq.core.user.Preferences;
import bisq.core.user.User;

import bisq.network.p2p.P2PService;
import bisq.network.p2p.P2PServiceListener;
import bisq.network.p2p.peers.PeerManager;

import bisq.common.Timer;
import bisq.common.UserThread;
import bisq.common.app.Version;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import bisq.common.handlers.ResultHandler;

import com.google.inject.Key;
import com.google.inject.name.Names;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
//todo not sure if the restart handling from seed nodes is required

@Slf4j
public class RestApi extends ExecutableForAppWithP2p {
private static final long CHECK_CONNECTION_LOSS_SEC = 30;

private Timer checkConnectionLossTime;
@Getter
private DaoStateService daoStateService;
@Getter
Expand All @@ -64,6 +45,8 @@ public class RestApi extends ExecutableForAppWithP2p {
private BondedRolesRepository bondedRolesRepository;
@Getter
private SignVerifyService signVerifyService;
private DaoStateSnapshotService daoStateSnapshotService;
private Preferences preferences;

public RestApi() {
super("Bisq Rest Api", "bisq_restapi", "bisq_restapi", Version.VERSION);
Expand All @@ -80,113 +63,31 @@ protected void doExecute() {
checkMemory(config, this);
}


///////////////////////////////////////////////////////////////////////////////////////////
// We continue with a series of synchronous execution tasks
///////////////////////////////////////////////////////////////////////////////////////////

@Override
protected void applyInjector() {
super.applyInjector();

injector.getInstance(DaoStateSnapshotService.class).setResyncDaoStateFromResourcesHandler(this::gracefulShutDown);
}

@Override
protected void startApplication() {
super.startApplication();

Cookie cookie = injector.getInstance(User.class).getCookie();
cookie.getAsOptionalBoolean(CookieKey.CLEAN_TOR_DIR_AT_RESTART).ifPresent(cleanTorDirAtRestart -> {
if (cleanTorDirAtRestart) {
injector.getInstance(TorSetup.class).cleanupTorFiles(() ->
cookie.remove(CookieKey.CLEAN_TOR_DIR_AT_RESTART),
log::error);
}
});

injector.getInstance(Preferences.class).setUseFullModeDaoMonitor(false);

preferences = injector.getInstance(Preferences.class);
daoStateService = injector.getInstance(DaoStateService.class);
accountAgeWitnessService = injector.getInstance(AccountAgeWitnessService.class);
bondedReputationRepository = injector.getInstance(BondedReputationRepository.class);
bondedRolesRepository = injector.getInstance(BondedRolesRepository.class);
signVerifyService = injector.getInstance(SignVerifyService.class);

injector.getInstance(P2PService.class).addP2PServiceListener(new P2PServiceListener() {
@Override
public void onDataReceived() {
// Do nothing
}

@Override
public void onNoSeedNodeAvailable() {
// Do nothing
}

@Override
public void onNoPeersAvailable() {
// Do nothing
}

@Override
public void onUpdatedDataReceived() {
// Do nothing
}

@Override
public void onTorNodeReady() {
// Do nothing
}

@Override
public void onHiddenServicePublished() {
boolean preventPeriodicShutdownAtSeedNode = injector.getInstance(Key.get(boolean.class,
Names.named(Config.PREVENT_PERIODIC_SHUTDOWN_AT_SEED_NODE)));
if (!preventPeriodicShutdownAtSeedNode) {
startShutDownInterval();
}
UserThread.runAfter(() -> setupConnectionLossCheck(), 60);

accountAgeWitnessService.onAllServicesInitialized();
}

@Override
public void onSetupFailed(Throwable throwable) {
// Do nothing
}

@Override
public void onRequestCustomBridges() {
// Do nothing
}
});
daoStateSnapshotService = injector.getInstance(DaoStateSnapshotService.class);
}

private void setupConnectionLossCheck() {
// For dev testing (usually on BTC_REGTEST) we don't want to get the seed shut
// down as it is normal that the seed is the only actively running node.
if (Config.baseCurrencyNetwork() == BaseCurrencyNetwork.BTC_REGTEST) {
return;
}

if (checkConnectionLossTime != null) {
return;
}

checkConnectionLossTime = UserThread.runPeriodically(() -> {
if (injector.getInstance(PeerManager.class).getNumAllConnectionsLostEvents() > 1) {
// We set a flag to clear tor cache files at re-start. We cannot clear it now as Tor is used and
// that can cause problems.
injector.getInstance(User.class).getCookie().putAsBoolean(CookieKey.CLEAN_TOR_DIR_AT_RESTART, true);
shutDown(this);
}
}, CHECK_CONNECTION_LOSS_SEC);
@Override
protected void startApplication() {
super.startApplication();

preferences.setUseFullModeDaoMonitor(false);
daoStateSnapshotService.setResyncDaoStateFromResourcesHandler(this::gracefulShutDown);
}

@Override
public void gracefulShutDown(ResultHandler resultHandler) {
super.gracefulShutDown(resultHandler);
protected void onHiddenServicePublished() {
super.onHiddenServicePublished();

accountAgeWitnessService.onAllServicesInitialized();
}
}
Loading

0 comments on commit 59f2df9

Please sign in to comment.