Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve seednode [D] #7182

Merged
72 changes: 12 additions & 60 deletions core/src/main/java/bisq/core/app/misc/ExecutableForAppWithP2p.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@
import bisq.core.payment.TradeLimits;
import bisq.core.support.dispute.arbitration.arbitrator.ArbitratorManager;

import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.P2PService;
import bisq.network.p2p.seed.SeedNodeRepository;

import bisq.common.UserThread;
import bisq.common.app.AppModule;
Expand All @@ -43,13 +41,6 @@
import bisq.common.util.Profiler;
import bisq.common.util.SingleThreadExecutorUtils;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

Expand All @@ -58,8 +49,8 @@
@Slf4j
public abstract class ExecutableForAppWithP2p extends BisqExecutable {
private static final long CHECK_MEMORY_PERIOD_SEC = 300;
private static final long CHECK_SHUTDOWN_SEC = TimeUnit.HOURS.toSeconds(1);
private static final long SHUTDOWN_INTERVAL = TimeUnit.HOURS.toMillis(24);
protected static final long CHECK_SHUTDOWN_SEC = TimeUnit.HOURS.toSeconds(1);
protected static final long SHUTDOWN_INTERVAL = TimeUnit.HOURS.toMillis(24);
private volatile boolean stopped;
private final long startTime = System.currentTimeMillis();
private TradeLimits tradeLimits;
Expand Down Expand Up @@ -146,61 +137,22 @@ public void gracefulShutDown(ResultHandler resultHandler) {
}
}

public void startShutDownInterval(GracefulShutDownHandler gracefulShutDownHandler) {
public void startShutDownInterval() {
if (DevEnv.isDevMode() || injector.getInstance(Config.class).useLocalhostForP2P) {
return;
}

List<NodeAddress> seedNodeAddresses = new ArrayList<>(injector.getInstance(SeedNodeRepository.class).getSeedNodeAddresses());
seedNodeAddresses.sort(Comparator.comparing(NodeAddress::getFullAddress));

NodeAddress myAddress = injector.getInstance(P2PService.class).getNetworkNode().getNodeAddress();
int myIndex = seedNodeAddresses.indexOf(myAddress);

if (myIndex == -1) {
log.warn("We did not find our node address in the seed nodes repository. " +
"We use a 24 hour delay after startup as shut down strategy." +
"myAddress={}, seedNodeAddresses={}",
myAddress, seedNodeAddresses);

UserThread.runPeriodically(() -> {
if (System.currentTimeMillis() - startTime > SHUTDOWN_INTERVAL) {
log.warn("\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" +
"Shut down as node was running longer as {} hours" +
"\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n",
SHUTDOWN_INTERVAL / 3600000);

shutDown(gracefulShutDownHandler);
}

}, CHECK_SHUTDOWN_SEC);
return;
}

// We interpret the value of myIndex as hour of day (0-23). That way we avoid the risk of a restart of
// multiple nodes around the same time in case it would be not deterministic.
UserThread.runPeriodically(() -> {
if (System.currentTimeMillis() - startTime > SHUTDOWN_INTERVAL) {
log.warn("\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" +
"Shut down as node was running longer as {} hours" +
"\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n",
SHUTDOWN_INTERVAL / 3600000);

// We wrap our periodic check in a delay of 2 hours to avoid that we get
// triggered multiple times after a restart while being in the same hour. It can be that we miss our target
// hour during that delay but that is not considered problematic, the seed would just restart a bit longer than
// 24 hours.
UserThread.runAfter(() -> {
// We check every hour if we are in the target hour.
UserThread.runPeriodically(() -> {
int currentHour = ZonedDateTime.ofInstant(Instant.now(), ZoneId.of("UTC")).getHour();
shutDown(this);
}

// distribute evenly between 0-23
long target = Math.round(24d / seedNodeAddresses.size() * myIndex) % 24;
if (currentHour == target) {
log.warn("\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" +
"Shut down node at hour {} (UTC time is {})" +
"\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n",
target,
ZonedDateTime.ofInstant(Instant.now(), ZoneId.of("UTC")).toString());
shutDown(gracefulShutDownHandler);
}
}, TimeUnit.MINUTES.toSeconds(10));
}, TimeUnit.HOURS.toSeconds(2));
}, CHECK_SHUTDOWN_SEC);
}

@SuppressWarnings("InfiniteLoopStatement")
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/bisq/core/user/CookieKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ public enum CookieKey {
STAGE_W,
STAGE_H,
TRADE_STAT_CHART_USE_USD,
CLEAN_TOR_DIR_AT_RESTART
CLEAN_TOR_DIR_AT_RESTART,
DELAY_STARTUP
}
3 changes: 2 additions & 1 deletion inventory/src/main/java/bisq/inventory/InventoryMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ public InventoryMonitor(File appDir,

TorSetup torSetup = new TorSetup(torDir);
if (cleanupTorFiles) {
torSetup.cleanupTorFiles(() -> log.info("Tor directory cleaned up"), log::error);
torSetup.cleanupTorFiles(() -> {
}, log::error);
}
}

Expand Down
9 changes: 4 additions & 5 deletions restapi/src/main/java/bisq/restapi/RestApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,9 @@ protected void 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(() -> {
log.info("Tor directory reset");
cookie.remove(CookieKey.CLEAN_TOR_DIR_AT_RESTART);
}, log::error);
injector.getInstance(TorSetup.class).cleanupTorFiles(() ->
cookie.remove(CookieKey.CLEAN_TOR_DIR_AT_RESTART),
log::error);
}
});

Expand Down Expand Up @@ -147,7 +146,7 @@ public void onHiddenServicePublished() {
boolean preventPeriodicShutdownAtSeedNode = injector.getInstance(Key.get(boolean.class,
Names.named(Config.PREVENT_PERIODIC_SHUTDOWN_AT_SEED_NODE)));
if (!preventPeriodicShutdownAtSeedNode) {
startShutDownInterval(RestApi.this);
startShutDownInterval();
}
UserThread.runAfter(() -> setupConnectionLossCheck(), 60);

Expand Down
27 changes: 13 additions & 14 deletions seednode/src/main/java/bisq/seednode/SeedNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,28 @@
import com.google.inject.Key;
import com.google.inject.name.Names;

import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SeedNode {
@Setter
private Injector injector;
private AppSetup appSetup;
private GetInventoryRequestHandler getInventoryRequestHandler;
private SeedNodeReportingService seedNodeReportingService;
private final AppSetup appSetup;
private final GetInventoryRequestHandler getInventoryRequestHandler;
private final SeedNodeReportingService seedNodeReportingService;
private final boolean useSeedNodeReportingService;

public SeedNode() {
}

public void startApplication() {
public SeedNode(Injector injector) {
appSetup = injector.getInstance(AppSetupWithP2PAndDAO.class);
appSetup.start();

getInventoryRequestHandler = injector.getInstance(GetInventoryRequestHandler.class);
seedNodeReportingService = injector.getInstance(SeedNodeReportingService.class);

String seedNodeReportingServerUrl = injector.getInstance(Key.get(String.class, Names.named(Config.SEED_NODE_REPORTING_SERVER_URL)));
if (seedNodeReportingServerUrl != null && !seedNodeReportingServerUrl.trim().isEmpty()) {
seedNodeReportingService = injector.getInstance(SeedNodeReportingService.class);
useSeedNodeReportingService = seedNodeReportingServerUrl != null && !seedNodeReportingServerUrl.trim().isEmpty();
}

public void startApplication() {
appSetup.start();
if (useSeedNodeReportingService) {
seedNodeReportingService.initialize();
}
}

Expand Down
Loading
Loading