mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-06-28 08:37:16 -04:00
delete and restore account restarts application automatically
added standard input to keepalive loop for issuing commands to daemon Co-authored-by: duriancrepe <duriancrepe@protonmail.com>
This commit is contained in:
parent
350d2d5398
commit
9877ba87a4
14 changed files with 181 additions and 73 deletions
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* This file is part of Haveno.
|
||||
*
|
||||
* Haveno is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Haveno is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package bisq.daemon.app;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
* A cancellable console input reader.
|
||||
* Derived from https://www.javaspecialists.eu/archive/Issue153-Timeout-on-Console-Input.html
|
||||
*/
|
||||
public class ConsoleInput {
|
||||
private final int tries;
|
||||
private final int timeout;
|
||||
private final TimeUnit unit;
|
||||
private Future<String> future;
|
||||
|
||||
public ConsoleInput(int tries, int timeout, TimeUnit unit) {
|
||||
this.tries = tries;
|
||||
this.timeout = timeout;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
if (future != null)
|
||||
future.cancel(true);
|
||||
}
|
||||
|
||||
public String readLine() throws InterruptedException {
|
||||
ExecutorService ex = Executors.newSingleThreadExecutor();
|
||||
String input = null;
|
||||
try {
|
||||
for (int i = 0; i < tries; i++) {
|
||||
future = ex.submit(new ConsoleInputReadTask());
|
||||
try {
|
||||
input = future.get(timeout, unit);
|
||||
break;
|
||||
} catch (ExecutionException e) {
|
||||
e.getCause().printStackTrace();
|
||||
} catch (TimeoutException e) {
|
||||
future.cancel(true);
|
||||
} finally {
|
||||
future = null;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
ex.shutdownNow();
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* This file is part of Haveno.
|
||||
*
|
||||
* Haveno is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Haveno is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package bisq.daemon.app;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class ConsoleInputReadTask implements Callable<String> {
|
||||
public String call() throws IOException {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
|
||||
log.debug("ConsoleInputReadTask run() called.");
|
||||
String input;
|
||||
do {
|
||||
try {
|
||||
// wait until we have data to complete a readLine()
|
||||
while (!br.ready()) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
// readline will always block until an input exists.
|
||||
input = br.readLine();
|
||||
} catch (InterruptedException e) {
|
||||
log.debug("ConsoleInputReadTask() cancelled");
|
||||
return null;
|
||||
}
|
||||
} while ("".equals(input));
|
||||
return input;
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package bisq.daemon.app;
|
||||
|
||||
import bisq.core.app.ConsoleInput;
|
||||
import bisq.core.app.HavenoHeadlessAppMain;
|
||||
import bisq.core.app.HavenoSetup;
|
||||
import bisq.core.api.AccountServiceListener;
|
||||
|
@ -26,6 +27,7 @@ import bisq.common.UserThread;
|
|||
import bisq.common.app.AppModule;
|
||||
import bisq.common.crypto.IncorrectPasswordException;
|
||||
import bisq.common.handlers.ResultHandler;
|
||||
import bisq.common.persistence.PersistenceManager;
|
||||
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
|
||||
|
@ -34,6 +36,7 @@ import java.util.concurrent.CancellationException;
|
|||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
@ -45,7 +48,28 @@ public class HavenoDaemonMain extends HavenoHeadlessAppMain implements HavenoSet
|
|||
private GrpcServer grpcServer;
|
||||
|
||||
public static void main(String[] args) {
|
||||
new HavenoDaemonMain().execute(args);
|
||||
var keepRunning = true;
|
||||
while (keepRunning) {
|
||||
keepRunning = false;
|
||||
var daemon = new HavenoDaemonMain();
|
||||
var ret = daemon.execute(args);
|
||||
if (ret == EXIT_SUCCESS) {
|
||||
UserThread.execute(() -> daemon.gracefulShutDown(() -> {}));
|
||||
} else if (ret == EXIT_RESTART) {
|
||||
AtomicBoolean shuttingDown = new AtomicBoolean(true);
|
||||
UserThread.execute(() -> daemon.gracefulShutDown(() -> shuttingDown.set(false), false));
|
||||
keepRunning = true;
|
||||
// wait for graceful shutdown
|
||||
try {
|
||||
while (shuttingDown.get()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
PersistenceManager.reset();
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("interrupted!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -106,8 +130,8 @@ public class HavenoDaemonMain extends HavenoHeadlessAppMain implements HavenoSet
|
|||
}
|
||||
|
||||
@Override
|
||||
public void gracefulShutDown(ResultHandler resultHandler) {
|
||||
super.gracefulShutDown(resultHandler);
|
||||
public void gracefulShutDown(ResultHandler resultHandler, boolean exit) {
|
||||
super.gracefulShutDown(resultHandler, exit);
|
||||
if (grpcServer != null) grpcServer.shutdown(); // could be null if application attempted to shutdown early
|
||||
}
|
||||
|
||||
|
@ -120,7 +144,6 @@ public class HavenoDaemonMain extends HavenoHeadlessAppMain implements HavenoSet
|
|||
|
||||
// Start rpc server in case login is coming in from rpc
|
||||
grpcServer = injector.getInstance(GrpcServer.class);
|
||||
grpcServer.start();
|
||||
|
||||
if (!opened) {
|
||||
// Nonblocking, we need to stop if the login occurred through rpc.
|
||||
|
@ -129,7 +152,6 @@ public class HavenoDaemonMain extends HavenoHeadlessAppMain implements HavenoSet
|
|||
Thread t = new Thread(() -> {
|
||||
interactiveLogin(reader);
|
||||
});
|
||||
t.start();
|
||||
|
||||
// Handle asynchronous account opens.
|
||||
// Will need to also close and reopen account.
|
||||
|
@ -143,10 +165,14 @@ public class HavenoDaemonMain extends HavenoHeadlessAppMain implements HavenoSet
|
|||
};
|
||||
accountService.addListener(accountListener);
|
||||
|
||||
// start server after the listener is registered
|
||||
grpcServer.start();
|
||||
|
||||
try {
|
||||
// Wait until interactive login or rpc. Check one more time if account is open to close race condition.
|
||||
if (!accountService.isAccountOpen()) {
|
||||
log.info("Interactive login required");
|
||||
t.start();
|
||||
t.join();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -155,6 +181,8 @@ public class HavenoDaemonMain extends HavenoHeadlessAppMain implements HavenoSet
|
|||
|
||||
accountService.removeListener(accountListener);
|
||||
opened = accountService.isAccountOpen();
|
||||
} else {
|
||||
grpcServer.start();
|
||||
}
|
||||
|
||||
return opened;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue