diff --git a/pricenode/src/main/java/bisq/price/PriceProvider.java b/pricenode/src/main/java/bisq/price/PriceProvider.java index 13b1dc7b0a8..cbeefd9422b 100644 --- a/pricenode/src/main/java/bisq/price/PriceProvider.java +++ b/pricenode/src/main/java/bisq/price/PriceProvider.java @@ -17,12 +17,15 @@ package bisq.price; +import bisq.common.UserThread; + import org.springframework.context.SmartLifecycle; import java.time.Duration; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import org.slf4j.Logger; @@ -45,17 +48,19 @@ public PriceProvider(Duration refreshInterval) { @Override public final T get() { - if (!isRunning()) - throw new IllegalStateException("call start() before calling get()"); - return cachedResult; } @Override public final void start() { - // we call refresh outside the context of a timer once at startup to ensure that - // any exceptions thrown get propagated and cause the application to halt - refresh(); + // do the initial refresh asynchronously + UserThread.runAfter(() -> { + try { + refresh(); + } catch (Throwable t) { + log.warn("initial refresh failed", t); + } + }, 1, TimeUnit.MILLISECONDS); timer.scheduleAtFixedRate(new TimerTask() { @Override diff --git a/pricenode/src/main/java/bisq/price/mining/FeeRateService.java b/pricenode/src/main/java/bisq/price/mining/FeeRateService.java index 43116dd24a2..7234e636c8b 100644 --- a/pricenode/src/main/java/bisq/price/mining/FeeRateService.java +++ b/pricenode/src/main/java/bisq/price/mining/FeeRateService.java @@ -27,6 +27,9 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * High-level mining {@link FeeRate} operations. */ @@ -34,6 +37,7 @@ class FeeRateService { private final List providers; + protected final Logger log = LoggerFactory.getLogger(this.getClass()); /** * Construct a {@link FeeRateService} with a list of all {@link FeeRateProvider} @@ -56,6 +60,10 @@ public Map getFees() { // Process each provider, retrieve and store their fee rate providers.forEach(p -> { FeeRate feeRate = p.get(); + if (feeRate == null) { + log.warn("feeRate is null, provider={} ", p.toString()); + return; + } String currency = feeRate.getCurrency(); if ("BTC".equals(currency)) { sumOfAllFeeRates.getAndAdd(feeRate.getPrice()); diff --git a/pricenode/src/main/java/bisq/price/spot/ExchangeRateService.java b/pricenode/src/main/java/bisq/price/spot/ExchangeRateService.java index 6fcf4a6eb2b..e1300b6d5a2 100644 --- a/pricenode/src/main/java/bisq/price/spot/ExchangeRateService.java +++ b/pricenode/src/main/java/bisq/price/spot/ExchangeRateService.java @@ -61,6 +61,8 @@ public Map getAllMarketPrices() { Map aggregateExchangeRates = getAggregateExchangeRates(); providers.forEach(p -> { + if (p.get() == null) + return; Set exchangeRates = p.get(); // Specific metadata fields for specific providers are expected by the client, @@ -136,6 +138,8 @@ private Map getAggregateExchangeRates() { private Map> getCurrencyCodeToExchangeRates() { Map> currencyCodeToExchangeRates = new HashMap<>(); for (ExchangeRateProvider p : providers) { + if (p.get() == null) + continue; for (ExchangeRate exchangeRate : p.get()) { String currencyCode = exchangeRate.getCurrency(); if (currencyCodeToExchangeRates.containsKey(currencyCode)) { diff --git a/pricenode/src/test/java/bisq/price/mining/providers/MempoolFeeRateProviderTest.java b/pricenode/src/test/java/bisq/price/mining/providers/MempoolFeeRateProviderTest.java index e15a3e18a74..153f35687a5 100644 --- a/pricenode/src/test/java/bisq/price/mining/providers/MempoolFeeRateProviderTest.java +++ b/pricenode/src/test/java/bisq/price/mining/providers/MempoolFeeRateProviderTest.java @@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test; +import static java.lang.Thread.sleep; import static org.junit.Assert.assertTrue; /** @@ -66,6 +67,9 @@ protected FeeRate doGet() { // Initialize provider dummyProvider.start(); + try { + sleep(1000); + } catch (InterruptedException e) { } dummyProvider.stop(); return dummyProvider; @@ -86,6 +90,9 @@ protected FeeRate doGet() { // Initialize provider dummyProvider.start(); + try { + sleep(1000); + } catch (InterruptedException e) { } dummyProvider.stop(); return dummyProvider; diff --git a/pricenode/src/test/java/bisq/price/spot/ExchangeRateServiceTest.java b/pricenode/src/test/java/bisq/price/spot/ExchangeRateServiceTest.java index 61d2ffbee6a..fefb3c85bff 100644 --- a/pricenode/src/test/java/bisq/price/spot/ExchangeRateServiceTest.java +++ b/pricenode/src/test/java/bisq/price/spot/ExchangeRateServiceTest.java @@ -44,6 +44,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static java.lang.Thread.sleep; import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -287,6 +288,9 @@ protected Set doGet() { // Initialize provider dummyProvider.start(); + try { + sleep(1000); + } catch (InterruptedException e) { } dummyProvider.stop(); return dummyProvider; @@ -322,6 +326,9 @@ protected Set doGet() { // Initialize provider dummyProvider.start(); + try { + sleep(1000); + } catch (InterruptedException e) { } dummyProvider.stop(); return dummyProvider;