From 59fbd805a55724184f2ada18583655e86cec1c42 Mon Sep 17 00:00:00 2001 From: woodser Date: Sat, 6 Apr 2024 17:39:21 -0400 Subject: [PATCH] update offer state on same thread to fix blocking --- .../main/java/haveno/core/offer/Offer.java | 2 +- .../desktop/main/market/MarketView.java | 36 ++++---- .../offerbook/OfferBookChartViewModel.java | 20 +++-- .../offer/takeoffer/TakeOfferViewModel.java | 88 ++++++++++--------- 4 files changed, 76 insertions(+), 70 deletions(-) diff --git a/core/src/main/java/haveno/core/offer/Offer.java b/core/src/main/java/haveno/core/offer/Offer.java index ae20538a..63bc8aa5 100644 --- a/core/src/main/java/haveno/core/offer/Offer.java +++ b/core/src/main/java/haveno/core/offer/Offer.java @@ -265,7 +265,7 @@ public class Offer implements NetworkPayload, PersistablePayload { /////////////////////////////////////////////////////////////////////////////////////////// public void setState(Offer.State state) { - UserThread.await(() -> stateProperty().set(state)); + stateProperty.set(state); } public ObjectProperty stateProperty() { diff --git a/desktop/src/main/java/haveno/desktop/main/market/MarketView.java b/desktop/src/main/java/haveno/desktop/main/market/MarketView.java index 3fb91650..98f5e754 100644 --- a/desktop/src/main/java/haveno/desktop/main/market/MarketView.java +++ b/desktop/src/main/java/haveno/desktop/main/market/MarketView.java @@ -200,22 +200,24 @@ public class MarketView extends ActivatableView { } private String getAllOffersWithReferralId() { - List list = offerBook.getOfferBookListItems().stream() - .map(OfferBookListItem::getOffer) - .filter(offer -> offer.getExtraDataMap() != null) - .filter(offer -> offer.getExtraDataMap().get(OfferPayload.REFERRAL_ID) != null) - .map(offer -> { - StringBuilder sb = new StringBuilder(); - sb.append("Offer ID: ").append(offer.getId()).append("\n") - .append("Type: ").append(offer.getDirection().name()).append("\n") - .append("Market: ").append(CurrencyUtil.getCurrencyPair(offer.getCurrencyCode())).append("\n") - .append("Price: ").append(FormattingUtils.formatPrice(offer.getPrice())).append("\n") - .append("Amount: ").append(DisplayUtils.formatAmount(offer, formatter)).append(" BTC\n") - .append("Payment method: ").append(Res.get(offer.getPaymentMethod().getId())).append("\n") - .append("ReferralID: ").append(offer.getExtraDataMap().get(OfferPayload.REFERRAL_ID)); - return sb.toString(); - }) - .collect(Collectors.toList()); - return Joiner.on("\n\n").join(list); + synchronized (offerBook.getOfferBookListItems()) { + List list = offerBook.getOfferBookListItems().stream() + .map(OfferBookListItem::getOffer) + .filter(offer -> offer.getExtraDataMap() != null) + .filter(offer -> offer.getExtraDataMap().get(OfferPayload.REFERRAL_ID) != null) + .map(offer -> { + StringBuilder sb = new StringBuilder(); + sb.append("Offer ID: ").append(offer.getId()).append("\n") + .append("Type: ").append(offer.getDirection().name()).append("\n") + .append("Market: ").append(CurrencyUtil.getCurrencyPair(offer.getCurrencyCode())).append("\n") + .append("Price: ").append(FormattingUtils.formatPrice(offer.getPrice())).append("\n") + .append("Amount: ").append(DisplayUtils.formatAmount(offer, formatter)).append(" BTC\n") + .append("Payment method: ").append(Res.get(offer.getPaymentMethod().getId())).append("\n") + .append("ReferralID: ").append(offer.getExtraDataMap().get(OfferPayload.REFERRAL_ID)); + return sb.toString(); + }) + .collect(Collectors.toList()); + return Joiner.on("\n\n").join(list); + } } } diff --git a/desktop/src/main/java/haveno/desktop/main/market/offerbook/OfferBookChartViewModel.java b/desktop/src/main/java/haveno/desktop/main/market/offerbook/OfferBookChartViewModel.java index 7f970494..8073351a 100644 --- a/desktop/src/main/java/haveno/desktop/main/market/offerbook/OfferBookChartViewModel.java +++ b/desktop/src/main/java/haveno/desktop/main/market/offerbook/OfferBookChartViewModel.java @@ -147,16 +147,18 @@ class OfferBookChartViewModel extends ActivatableViewModel { private void fillTradeCurrencies() { // Don't use a set as we need all entries - List tradeCurrencyList = offerBookListItems.stream() - .map(e -> { - String currencyCode = e.getOffer().getCurrencyCode(); - Optional tradeCurrencyOptional = CurrencyUtil.getTradeCurrency(currencyCode); - return tradeCurrencyOptional.orElse(null); - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + synchronized (offerBookListItems) { + List tradeCurrencyList = offerBookListItems.stream() + .map(e -> { + String currencyCode = e.getOffer().getCurrencyCode(); + Optional tradeCurrencyOptional = CurrencyUtil.getTradeCurrency(currencyCode); + return tradeCurrencyOptional.orElse(null); + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); - currencyListItems.updateWithCurrencies(tradeCurrencyList, null); + currencyListItems.updateWithCurrencies(tradeCurrencyList, null); + } } @Override diff --git a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java index 742dddb6..04ad8fc0 100644 --- a/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java +++ b/desktop/src/main/java/haveno/desktop/main/offer/takeoffer/TakeOfferViewModel.java @@ -350,50 +350,52 @@ class TakeOfferViewModel extends ActivatableWithDataModel im /////////////////////////////////////////////////////////////////////////////////////////// private void applyOfferState(Offer.State state) { - offerWarning.set(null); + UserThread.execute(() -> { + offerWarning.set(null); - // We have 2 situations handled here: - // 1. when clicking take offer in the offerbook screen, we do the availability check - // 2. Before actually taking the offer in the take offer screen, we check again the availability as some time might have passed in the meantime - // So we use the takeOfferRequested flag to display different network_messages depending on the context. - switch (state) { - case UNKNOWN: - break; - case OFFER_FEE_RESERVED: - // irrelevant for taker - break; - case AVAILABLE: - isOfferAvailable.set(true); - updateButtonDisableState(); - break; - case NOT_AVAILABLE: - if (takeOfferRequested) - offerWarning.set(Res.get("takeOffer.failed.offerNotAvailable")); - else - offerWarning.set(Res.get("takeOffer.failed.offerTaken")); - takeOfferRequested = false; - break; - case REMOVED: - if (!takeOfferRequested) - offerWarning.set(Res.get("takeOffer.failed.offerRemoved")); - - takeOfferRequested = false; - break; - case MAKER_OFFLINE: - if (takeOfferRequested) - offerWarning.set(Res.get("takeOffer.failed.offererNotOnline")); - else - offerWarning.set(Res.get("takeOffer.failed.offererOffline")); - takeOfferRequested = false; - break; - default: - log.error("Unhandled offer state: " + state); - break; - } - - updateSpinnerInfo(); - - updateButtonDisableState(); + // We have 2 situations handled here: + // 1. when clicking take offer in the offerbook screen, we do the availability check + // 2. Before actually taking the offer in the take offer screen, we check again the availability as some time might have passed in the meantime + // So we use the takeOfferRequested flag to display different network_messages depending on the context. + switch (state) { + case UNKNOWN: + break; + case OFFER_FEE_RESERVED: + // irrelevant for taker + break; + case AVAILABLE: + isOfferAvailable.set(true); + updateButtonDisableState(); + break; + case NOT_AVAILABLE: + if (takeOfferRequested) + offerWarning.set(Res.get("takeOffer.failed.offerNotAvailable")); + else + offerWarning.set(Res.get("takeOffer.failed.offerTaken")); + takeOfferRequested = false; + break; + case REMOVED: + if (!takeOfferRequested) + offerWarning.set(Res.get("takeOffer.failed.offerRemoved")); + + takeOfferRequested = false; + break; + case MAKER_OFFLINE: + if (takeOfferRequested) + offerWarning.set(Res.get("takeOffer.failed.offererNotOnline")); + else + offerWarning.set(Res.get("takeOffer.failed.offererOffline")); + takeOfferRequested = false; + break; + default: + log.error("Unhandled offer state: " + state); + break; + } + + updateSpinnerInfo(); + + updateButtonDisableState(); + }); } private void applyTradeErrorMessage(@Nullable String errorMessage) {