From f0242bf700b481a8894c6dcae1c2214a85187e1d Mon Sep 17 00:00:00 2001 From: chimp1984 <54558767+chimp1984@users.noreply.github.com> Date: Wed, 23 Oct 2019 14:38:00 -0500 Subject: [PATCH] Use safe version for seednodes (#3452) * Apply shutdown and memory check again To not risk issues with the release and seed nodes we merge back the old code base for handling memory check and shutdowns. The newly added changes for cross connecting between seed nodes cause out of memory issues and require more work and testing before it can be used. * Revert code change for periodic updates between seed nodes. The periodic updates code caused out of memory issues and require more work and testing before it can be used. --- .../app/misc/ExecutableForAppWithP2p.java | 33 ++++++++++++++++--- .../java/bisq/network/p2p/P2PService.java | 6 ++-- .../p2p/peers/getdata/RequestDataHandler.java | 16 ++++----- .../main/java/bisq/seednode/SeedNodeMain.java | 2 ++ 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/bisq/core/app/misc/ExecutableForAppWithP2p.java b/core/src/main/java/bisq/core/app/misc/ExecutableForAppWithP2p.java index 5959b7ee894..783440b1b76 100644 --- a/core/src/main/java/bisq/core/app/misc/ExecutableForAppWithP2p.java +++ b/core/src/main/java/bisq/core/app/misc/ExecutableForAppWithP2p.java @@ -41,14 +41,18 @@ import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; @Slf4j public abstract class ExecutableForAppWithP2p extends BisqExecutable implements UncaughtExceptionHandler { - private static final long MAX_MEMORY_MB_DEFAULT = 500; + private static final long MAX_MEMORY_MB_DEFAULT = 1200; 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); private volatile boolean stopped; + private final long startTime = System.currentTimeMillis(); private static long maxMemory = MAX_MEMORY_MB_DEFAULT; public ExecutableForAppWithP2p(String fullName, String scriptName, String version) { @@ -120,6 +124,20 @@ protected void keepRunning() { } } + protected void startShutDownInterval(GracefulShutDownHandler gracefulShutDownHandler) { + 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); + } + protected void checkMemory(BisqEnvironment environment, GracefulShutDownHandler gracefulShutDownHandler) { String maxMemoryOption = environment.getProperty(AppOptionKeys.MAX_MEMORY); if (maxMemoryOption != null && !maxMemoryOption.isEmpty()) { @@ -153,16 +171,24 @@ protected void checkMemory(BisqEnvironment environment, GracefulShutDownHandler long usedMemory = Profiler.getUsedMemoryInMB(); if (usedMemory > maxMemory) { log.warn("\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" + - "We are over our memory limit ({}) and trigger a restart. usedMemory: {} MB. freeMemory: {} MB" + + "We are over our memory limit ({}) and trigger a shutdown. usedMemory: {} MB. freeMemory: {} MB" + "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n", (int) maxMemory, usedMemory, Profiler.getFreeMemoryInMB()); - restart(environment, gracefulShutDownHandler); + shutDown(gracefulShutDownHandler); } }, 5); } }, CHECK_MEMORY_PERIOD_SEC); } + protected void shutDown(GracefulShutDownHandler gracefulShutDownHandler) { + stopped = true; + gracefulShutDownHandler.gracefulShutDown(() -> { + log.info("Shutdown complete"); + System.exit(1); + }); + } + protected void restart(BisqEnvironment bisqEnvironment, GracefulShutDownHandler gracefulShutDownHandler) { stopped = true; gracefulShutDownHandler.gracefulShutDown(() -> { @@ -180,5 +206,4 @@ protected void restart(BisqEnvironment bisqEnvironment, GracefulShutDownHandler } }); } - } diff --git a/p2p/src/main/java/bisq/network/p2p/P2PService.java b/p2p/src/main/java/bisq/network/p2p/P2PService.java index 52a364c0b0c..f0a1fcddb75 100644 --- a/p2p/src/main/java/bisq/network/p2p/P2PService.java +++ b/p2p/src/main/java/bisq/network/p2p/P2PService.java @@ -47,8 +47,6 @@ import bisq.network.p2p.storage.payload.ProtectedStoragePayload; import bisq.common.UserThread; -import bisq.common.app.Capabilities; -import bisq.common.app.Capability; import bisq.common.crypto.CryptoException; import bisq.common.crypto.KeyRing; import bisq.common.crypto.PubKeyRing; @@ -313,8 +311,8 @@ private void onNetworkReady() { "seedNodeOfPreliminaryDataRequest must be present"); requestDataManager.requestUpdateData(); - if (Capabilities.app.containsAll(Capability.SEED_NODE)) - UserThread.runPeriodically(() -> requestDataManager.requestUpdateData(), 1, TimeUnit.HOURS); + /*if (Capabilities.app.containsAll(Capability.SEED_NODE)) + UserThread.runPeriodically(() -> requestDataManager.requestUpdateData(), 1, TimeUnit.HOURS);*/ // If we start up first time we don't have any peers so we need to request from seed node. // As well it can be that the persisted peer list is outdated with dead peers. diff --git a/p2p/src/main/java/bisq/network/p2p/peers/getdata/RequestDataHandler.java b/p2p/src/main/java/bisq/network/p2p/peers/getdata/RequestDataHandler.java index db4d94b3637..c97dae0f5ce 100644 --- a/p2p/src/main/java/bisq/network/p2p/peers/getdata/RequestDataHandler.java +++ b/p2p/src/main/java/bisq/network/p2p/peers/getdata/RequestDataHandler.java @@ -35,8 +35,6 @@ import bisq.common.Timer; import bisq.common.UserThread; -import bisq.common.app.Capabilities; -import bisq.common.app.Capability; import bisq.common.proto.network.NetworkEnvelope; import bisq.common.proto.network.NetworkPayload; @@ -61,13 +59,15 @@ class RequestDataHandler implements MessageListener { private static final long TIMEOUT = 90; private NodeAddress peersNodeAddress; + /* + */ /** * when we are run as a seed node, we spawn a RequestDataHandler every hour. However, we do not want to receive * {@link PersistableNetworkPayload}s (for now, as there are hardly any cases where such data goes out of sync). This * flag indicates whether we already received our first set of {@link PersistableNetworkPayload}s. - */ - private static boolean firstRequest = true; + *//* + private static boolean firstRequest = true;*/ /////////////////////////////////////////////////////////////////////////////////////////// // Listener @@ -227,11 +227,11 @@ public void onMessage(NetworkEnvelope networkEnvelope, Connection connection) { }); log.info("Processing {} protectedStorageEntries took {} ms.", counter.get(), System.currentTimeMillis() - ts); - // engage the firstRequest logic only if we are a seed node. Normal clients get here twice at most. + /* // engage the firstRequest logic only if we are a seed node. Normal clients get here twice at most. if (!Capabilities.app.containsAll(Capability.SEED_NODE)) - firstRequest = true; + firstRequest = true;*/ - if (persistableNetworkPayloadSet != null && firstRequest) { + if (persistableNetworkPayloadSet != null /*&& firstRequest*/) { ts = System.currentTimeMillis(); persistableNetworkPayloadSet.forEach(e -> { if (e instanceof LazyProcessedPayload) { @@ -253,7 +253,7 @@ public void onMessage(NetworkEnvelope networkEnvelope, Connection connection) { cleanup(); listener.onComplete(); - firstRequest = false; + // firstRequest = false; } else { log.warn("Nonce not matching. That can happen rarely if we get a response after a canceled " + "handshake (timeout causes connection close but peer might have sent a msg before " + diff --git a/seednode/src/main/java/bisq/seednode/SeedNodeMain.java b/seednode/src/main/java/bisq/seednode/SeedNodeMain.java index 1c3b239087c..03d8763d023 100644 --- a/seednode/src/main/java/bisq/seednode/SeedNodeMain.java +++ b/seednode/src/main/java/bisq/seednode/SeedNodeMain.java @@ -53,6 +53,8 @@ public static void main(String[] args) throws Exception { protected void doExecute(OptionSet options) { super.doExecute(options); + checkMemory(bisqEnvironment, this); + startShutDownInterval(this); CommonSetup.setup(this); keepRunning();