shut down http connections with 5s timeout

This commit is contained in:
woodser 2024-01-26 09:07:03 -05:00
parent 64aa052d83
commit 8600c0cb0d
6 changed files with 85 additions and 69 deletions

View File

@ -35,7 +35,12 @@ public class ThreadUtils {
private static final int POOL_SIZE = 10; private static final int POOL_SIZE = 10;
private static final ExecutorService POOL = Executors.newFixedThreadPool(POOL_SIZE); private static final ExecutorService POOL = Executors.newFixedThreadPool(POOL_SIZE);
/**
* Execute the given command in a thread with the given id.
*
* @param command the command to execute
* @param threadId the thread id
*/
public static void execute(Runnable command, String threadId) { public static void execute(Runnable command, String threadId) {
synchronized (EXECUTORS) { synchronized (EXECUTORS) {
if (!EXECUTORS.containsKey(threadId)) EXECUTORS.put(threadId, Executors.newFixedThreadPool(1)); if (!EXECUTORS.containsKey(threadId)) EXECUTORS.put(threadId, Executors.newFixedThreadPool(1));
@ -107,6 +112,8 @@ public class ThreadUtils {
} }
} }
// TODO: consolidate and cleanup apis
public static Future<?> submitToPool(Runnable task) { public static Future<?> submitToPool(Runnable task) {
return submitToPool(Arrays.asList(task)).get(0); return submitToPool(Arrays.asList(task)).get(0);
} }

View File

@ -341,7 +341,7 @@ public abstract class HavenoExecutable implements GracefulShutDownHandler, Haven
tasks.add(() -> injector.getInstance(XmrConnectionService.class).onShutDownStarted()); tasks.add(() -> injector.getInstance(XmrConnectionService.class).onShutDownStarted());
tasks.add(() -> injector.getInstance(TradeManager.class).onShutDownStarted()); tasks.add(() -> injector.getInstance(TradeManager.class).onShutDownStarted());
try { try {
ThreadUtils.awaitTasks(tasks, tasks.size(), 120000l); // run in parallel with timeout ThreadUtils.awaitTasks(tasks, tasks.size(), 90000l); // run in parallel with timeout
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -361,9 +361,9 @@ public abstract class HavenoExecutable implements GracefulShutDownHandler, Haven
// shut down p2p service // shut down p2p service
injector.getInstance(P2PService.class).shutDown(() -> { injector.getInstance(P2PService.class).shutDown(() -> {
log.info("Done shutting down OpenOfferManager, OfferBookService, and P2PService");
// shut down monero wallets and connections // shut down monero wallets and connections
log.info("Shutting down wallet and connection services");
injector.getInstance(WalletsSetup.class).shutDownComplete.addListener((ov, o, n) -> { injector.getInstance(WalletsSetup.class).shutDownComplete.addListener((ov, o, n) -> {
// done shutting down // done shutting down

View File

@ -125,9 +125,9 @@ public abstract class ExecutableForAppWithP2p extends HavenoExecutable {
// shut down p2p service // shut down p2p service
injector.getInstance(P2PService.class).shutDown(() -> { injector.getInstance(P2PService.class).shutDown(() -> {
log.info("Done shutting down OpenOfferManager, OfferBookService, and P2PService");
// shut down monero wallets and connections // shut down monero wallets and connections
log.info("Shutting down wallet and connection services");
injector.getInstance(WalletsSetup.class).shutDownComplete.addListener((ov, o, n) -> { injector.getInstance(WalletsSetup.class).shutDownComplete.addListener((ov, o, n) -> {
module.close(injector); module.close(injector);
PersistenceManager.flushAllDataToDiskAtShutdown(() -> { PersistenceManager.flushAllDataToDiskAtShutdown(() -> {

View File

@ -416,11 +416,15 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
maybeUpdatePersistedOffers(); maybeUpdatePersistedOffers();
ThreadUtils.execute(() -> { // run off user thread so app is not blocked from starting
ThreadUtils.submitToPool(() -> {
// Wait for prices to be available // wait for prices to be available
priceFeedService.awaitExternalPrices(); priceFeedService.awaitExternalPrices();
// process open offers on dedicated thread
ThreadUtils.execute(() -> {
// Republish means we send the complete offer object // Republish means we send the complete offer object
republishOffers(); republishOffers();
startPeriodicRepublishOffersTimer(); startPeriodicRepublishOffersTimer();
@ -472,6 +476,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
signedOfferKeyImagePoller.addKeyImages(signedOffer.getReserveTxKeyImages()); signedOfferKeyImagePoller.addKeyImages(signedOffer.getReserveTxKeyImages());
} }
}, THREAD_ID); }, THREAD_ID);
});
} }

View File

@ -116,6 +116,7 @@ public class PriceFeedService {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void shutDown() { public void shutDown() {
log.info("Shutting down {}", getClass().getSimpleName());
if (requestTimer != null) { if (requestTimer != null) {
requestTimer.stop(); requestTimer.stop();
requestTimer = null; requestTimer = null;

View File

@ -18,6 +18,8 @@
package haveno.network.http; package haveno.network.http;
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy; import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
import haveno.common.ThreadUtils;
import haveno.common.app.Version; import haveno.common.app.Version;
import haveno.common.util.Utilities; import haveno.common.util.Utilities;
import haveno.network.Socks5ProxyProvider; import haveno.network.Socks5ProxyProvider;
@ -65,6 +67,7 @@ public class HttpClientImpl implements HttpClient {
private HttpURLConnection connection; private HttpURLConnection connection;
@Nullable @Nullable
private CloseableHttpClient closeableHttpClient; private CloseableHttpClient closeableHttpClient;
private static final long SHUTDOWN_TIMEOUT_MS = 5000l;
@Getter @Getter
@Setter @Setter
@ -88,6 +91,18 @@ public class HttpClientImpl implements HttpClient {
@Override @Override
public void shutDown() { public void shutDown() {
try {
ThreadUtils.awaitTask(() -> {
doShutDown(connection, closeableHttpClient);
connection = null;
closeableHttpClient = null;
}, SHUTDOWN_TIMEOUT_MS);
} catch (Exception e) {
// ignore
}
}
private void doShutDown(HttpURLConnection connection, CloseableHttpClient closeableHttpClient) {
try { try {
if (connection != null) { if (connection != null) {
connection.getInputStream().close(); connection.getInputStream().close();
@ -137,19 +152,7 @@ public class HttpClientImpl implements HttpClient {
public void cancelPendingRequest() { public void cancelPendingRequest() {
if (!hasPendingRequest) return; if (!hasPendingRequest) return;
try { shutDown();
if (connection != null) {
connection.getInputStream().close();
connection.disconnect();
connection = null;
}
if (closeableHttpClient != null) {
closeableHttpClient.close();
closeableHttpClient = null;
}
} catch (IOException err) {
// igbnore
}
hasPendingRequest = false; hasPendingRequest = false;
} }