Skip to content

Commit

Permalink
Merge pull request bisq-network#4583 from chimp1984/improve-startup-r…
Browse files Browse the repository at this point in the history
…outines

Improve startup routines
  • Loading branch information
sqrrm authored Oct 1, 2020
2 parents 418361a + d841222 commit 6c28d1a
Show file tree
Hide file tree
Showing 22 changed files with 261 additions and 324 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.core.app;
package bisq.common.app;

import lombok.extern.slf4j.Slf4j;

Expand Down
7 changes: 7 additions & 0 deletions common/src/main/java/bisq/common/app/DevEnv.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package bisq.common.app;

import bisq.common.config.Config;

import lombok.extern.slf4j.Slf4j;

@Slf4j
Expand All @@ -30,6 +32,11 @@ public class DevEnv {
public static final String DEV_PRIVILEGE_PUB_KEY = "027a381b5333a56e1cc3d90d3a7d07f26509adf7029ed06fc997c656621f8da1ee";
public static final String DEV_PRIVILEGE_PRIV_KEY = "6ac43ea1df2a290c1c8391736aa42e4339c5cb4f110ff0257a13b63211977b7a";

public static void setup(Config config) {
DevEnv.setDevMode(config.useDevMode);
DevEnv.setDaoActivated(config.daoActivated);
}

// If set to true we ignore several UI behavior like confirmation popups as well dummy accounts are created and
// offers are filled with default values. Intended to make dev testing faster.
private static boolean devMode = false;
Expand Down
10 changes: 0 additions & 10 deletions common/src/main/java/bisq/common/crypto/CryptoUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@

package bisq.common.crypto;

import javax.crypto.Cipher;

import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.X509EncodedKeySpec;
Expand All @@ -40,11 +37,4 @@ public static byte[] getRandomBytes(int size) {
new SecureRandom().nextBytes(bytes);
return bytes;
}

public static void checkCryptoPolicySetup() throws NoSuchAlgorithmException, LimitedKeyStrengthException {
if (Cipher.getMaxAllowedKeyLength("AES") > 128)
log.debug("Congratulations, you have unlimited key length support!");
else
throw new LimitedKeyStrengthException();
}
}

This file was deleted.

73 changes: 62 additions & 11 deletions common/src/main/java/bisq/common/setup/CommonSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,51 @@
package bisq.common.setup;

import bisq.common.UserThread;
import bisq.common.crypto.CryptoUtils;
import bisq.common.crypto.LimitedKeyStrengthException;
import bisq.common.app.AsciiLogo;
import bisq.common.app.DevEnv;
import bisq.common.app.Log;
import bisq.common.app.Version;
import bisq.common.config.Config;
import bisq.common.util.Profiler;
import bisq.common.util.Utilities;

import org.bitcoinj.store.BlockStoreException;

import org.apache.commons.lang3.exception.ExceptionUtils;

import java.security.NoSuchAlgorithmException;
import java.net.URISyntaxException;

import java.nio.file.Paths;

import java.util.concurrent.TimeUnit;

import ch.qos.logback.classic.Level;

import lombok.extern.slf4j.Slf4j;



import sun.misc.Signal;

@Slf4j
public class CommonSetup {

public static void setup(UncaughtExceptionHandler uncaughtExceptionHandler) {
setupErrorHandler(uncaughtExceptionHandler);
public static void setup(Config config, GracefulShutDownHandler gracefulShutDownHandler) {
AsciiLogo.showAsciiLogo();
setupLog(config);
Version.setBaseCryptoNetworkId(config.baseCurrencyNetwork.ordinal());
Version.printVersion();
maybePrintPathOfCodeSource();
Profiler.printSystemLoad();
UserThread.runPeriodically(Profiler::printSystemLoad, 10, TimeUnit.MINUTES);

if (Utilities.isLinux())
System.setProperty("prism.lcdtext", "false");
setSystemProperties();
setupSigIntHandlers(gracefulShutDownHandler);

DevEnv.setup(config);
}

private static void setupErrorHandler(UncaughtExceptionHandler uncaughtExceptionHandler) {
public static void setupUncaughtExceptionHandler(UncaughtExceptionHandler uncaughtExceptionHandler) {
Thread.UncaughtExceptionHandler handler = (thread, throwable) -> {
// Might come from another thread
if (throwable.getCause() != null && throwable.getCause().getCause() != null &&
Expand All @@ -60,12 +82,41 @@ private static void setupErrorHandler(UncaughtExceptionHandler uncaughtException
};
Thread.setDefaultUncaughtExceptionHandler(handler);
Thread.currentThread().setUncaughtExceptionHandler(handler);
}

private static void setupLog(Config config) {
String logPath = Paths.get(config.appDataDir.getPath(), "bisq").toString();
Log.setup(logPath);
log.info("Log files under: {}", logPath);
Utilities.printSysInfo();
Log.setLevel(Level.toLevel(config.logLevel));
}

protected static void setSystemProperties() {
if (Utilities.isLinux())
System.setProperty("prism.lcdtext", "false");
}

protected static void setupSigIntHandlers(GracefulShutDownHandler gracefulShutDownHandler) {
Signal.handle(new Signal("INT"), signal -> {
gracefulShutDownHandler.gracefulShutDown(() -> {
});
});

Signal.handle(new Signal("TERM"), signal -> {
gracefulShutDownHandler.gracefulShutDown(() -> {
});
});
}

protected static void maybePrintPathOfCodeSource() {
try {
CryptoUtils.checkCryptoPolicySetup();
} catch (NoSuchAlgorithmException | LimitedKeyStrengthException e) {
final String pathOfCodeSource = Utilities.getPathOfCodeSource();
if (!pathOfCodeSource.endsWith("classes"))
log.info("Path to Bisq jar file: " + pathOfCodeSource);
} catch (URISyntaxException e) {
log.error(e.toString());
e.printStackTrace();
UserThread.execute(() -> uncaughtExceptionHandler.handleUncaughtException(e, true));
}
}
}
15 changes: 9 additions & 6 deletions common/src/main/java/bisq/common/util/Profiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@

package bisq.common.util;

import org.slf4j.Logger;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Profiler {
public static void printSystemLoad(Logger log) {
log.info(printSystemLoadString());
}
public static void printSystemLoad() {
Runtime runtime = Runtime.getRuntime();
long free = runtime.freeMemory() / 1024 / 1024;
long total = runtime.totalMemory() / 1024 / 1024;
long used = total - free;

public static String printSystemLoadString() {
return "System load: Memory (MB): " + getUsedMemoryInMB() + " / No. of threads: " + Thread.activeCount();
log.info("System report: Used memory: {} MB; Free memory: {} MB; Total memory: {} MB; No. of threads: {}",
used, free, total, Thread.activeCount());
}

public static long getUsedMemoryInMB() {
Expand Down
16 changes: 16 additions & 0 deletions common/src/main/java/bisq/common/util/Utilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
import java.net.URI;
import java.net.URISyntaxException;

import java.nio.file.Paths;

import java.io.File;
import java.io.IOException;

Expand Down Expand Up @@ -198,6 +200,20 @@ public static String getOSVersion() {
return System.getProperty("os.version").toLowerCase(Locale.US);
}

/**
* Returns the well-known "user data directory" for the current operating system.
*/
public static File getUserDataDir() {
if (Utilities.isWindows())
return new File(System.getenv("APPDATA"));

if (Utilities.isOSX())
return Paths.get(System.getProperty("user.home"), "Library", "Application Support").toFile();

// *nix
return Paths.get(System.getProperty("user.home"), ".local", "share").toFile();
}

public static int getMinorVersion() throws InvalidVersionException {
String version = getOSVersion();
String[] tokens = version.split("\\.");
Expand Down
67 changes: 26 additions & 41 deletions core/src/main/java/bisq/core/app/BisqExecutable.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,18 @@
import bisq.common.config.ConfigException;
import bisq.common.handlers.ResultHandler;
import bisq.common.proto.persistable.PersistedDataHost;
import bisq.common.setup.CommonSetup;
import bisq.common.setup.GracefulShutDownHandler;
import bisq.common.setup.UncaughtExceptionHandler;
import bisq.common.util.Utilities;

import com.google.inject.Guice;
import com.google.inject.Injector;

import java.nio.file.Paths;

import java.io.File;

import lombok.extern.slf4j.Slf4j;



import sun.misc.Signal;

@Slf4j
public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSetup.BisqSetupListener {
public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSetup.BisqSetupListener, UncaughtExceptionHandler {

private static final int EXIT_SUCCESS = 0;
private static final int EXIT_FAILURE = 1;
Expand All @@ -78,7 +72,7 @@ public BisqExecutable(String fullName, String scriptName, String appName, String

public void execute(String[] args) {
try {
config = new Config(appName, osUserDataDir(), args);
config = new Config(appName, Utilities.getUserDataDir(), args);
if (config.helpRequested) {
config.printHelp(System.out, new BisqHelpFormatter(fullName, scriptName, version));
System.exit(EXIT_SUCCESS);
Expand All @@ -101,20 +95,11 @@ public void execute(String[] args) {
///////////////////////////////////////////////////////////////////////////////////////////

protected void doExecute() {
AsciiLogo.showAsciiLogo();
configUserThread();
CommonSetup.setup(config, this);
CoreSetup.setup(config);
addCapabilities();

Signal.handle(new Signal("INT"), signal -> {
gracefulShutDown(() -> {
});
});

Signal.handle(new Signal("TERM"), signal -> {
gracefulShutDown(() -> {
});
});
configUserThread();
addCapabilities();

// If application is JavaFX application we need to wait until it is initialized
launchApplication();
Expand All @@ -136,7 +121,12 @@ protected void addCapabilities() {

// Headless versions can call inside launchApplication the onApplicationLaunched() manually
protected void onApplicationLaunched() {
// As the handler method might be overwritten by subclasses and they use the application as handler
// we need to setup the handler after the application is created.
CommonSetup.setupUncaughtExceptionHandler(this);

setupGuice();
setupAvoidStandbyMode();
startApplication();
}

Expand All @@ -158,16 +148,9 @@ protected Injector getInjector() {
}

protected void applyInjector() {
setupDevEnv();

setupPersistedDataHosts(injector);
}

protected void setupDevEnv() {
DevEnv.setDevMode(config.useDevMode);
DevEnv.setDaoActivated(config.daoActivated);
}

protected void setupPersistedDataHosts(Injector injector) {
try {
PersistedDataHost.apply(CorePersistedDataHost.getPersistedDataHosts(injector));
Expand All @@ -182,14 +165,17 @@ protected void setupPersistedDataHosts(Injector injector) {
}
}

protected void setupAvoidStandbyMode() {
}

protected abstract void startApplication();

// Once the application is ready we get that callback and we start the setup
protected void onApplicationStarted() {
startAppSetup();
runBisqSetup();
}

protected void startAppSetup() {
protected void runBisqSetup() {
BisqSetup bisqSetup = injector.getInstance(BisqSetup.class);
bisqSetup.addBisqSetupListener(this);
bisqSetup.start();
Expand Down Expand Up @@ -260,17 +246,16 @@ public void gracefulShutDown(ResultHandler resultHandler) {
}
}

/**
* Returns the well-known "user data directory" for the current operating system.
*/
private static File osUserDataDir() {
if (Utilities.isWindows())
return new File(System.getenv("APPDATA"));

if (Utilities.isOSX())
return Paths.get(System.getProperty("user.home"), "Library", "Application Support").toFile();
///////////////////////////////////////////////////////////////////////////////////////////
// UncaughtExceptionHandler implementation
///////////////////////////////////////////////////////////////////////////////////////////

@Override
public void handleUncaughtException(Throwable throwable, boolean doShutDown) {
log.error(throwable.toString());

// *nix
return Paths.get(System.getProperty("user.home"), ".local", "share").toFile();
if (doShutDown)
gracefulShutDown(() -> log.info("gracefulShutDown complete"));
}
}
4 changes: 0 additions & 4 deletions core/src/main/java/bisq/core/app/BisqHeadlessApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import bisq.common.UserThread;
import bisq.common.setup.GracefulShutDownHandler;
import bisq.common.storage.CorruptedDatabaseFilesHandler;
import bisq.common.util.Profiler;

import com.google.inject.Injector;

Expand Down Expand Up @@ -60,8 +59,6 @@ public void startApplication() {
tradeManager = injector.getInstance(TradeManager.class);

setupHandlers();

UserThread.runPeriodically(() -> Profiler.printSystemLoad(log), LOG_MEMORY_PERIOD_MIN, TimeUnit.MINUTES);
} catch (Throwable throwable) {
log.error("Error during app init", throwable);
handleUncaughtException(throwable, false);
Expand All @@ -78,7 +75,6 @@ protected void setupHandlers() {
log.info("onDisplayTacHandler: We accept the tacs automatically in headless mode");
acceptedHandler.run();
});
bisqSetup.setCryptoSetupFailedHandler(msg -> log.error("onCryptoSetupFailedHandler: msg={}", msg));
bisqSetup.setDisplayTorNetworkSettingsHandler(show -> log.info("onDisplayTorNetworkSettingsHandler: show={}", show));
bisqSetup.setSpvFileCorruptedHandler(msg -> log.error("onSpvFileCorruptedHandler: msg={}", msg));
bisqSetup.setChainFileLockedExceptionHandler(msg -> log.error("onChainFileLockedExceptionHandler: msg={}", msg));
Expand Down
Loading

0 comments on commit 6c28d1a

Please sign in to comment.