Merge pull request #4035 from stejbac/speed-up-dao-state-monitor-view-load

Speed up DAO state monitor view load
This commit is contained in:
Christoph Atteneder 2020-03-10 09:05:44 +01:00 committed by GitHub
commit dc583d1a37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 115 additions and 36 deletions

View file

@ -133,7 +133,7 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
private Timer checkNumberOfP2pNetworkPeersTimer;
@SuppressWarnings("FieldCanBeLocal")
private MonadicBinding<Boolean> tradesAndUIReady;
private Queue<Overlay> popupQueue = new PriorityQueue<>(Comparator.comparing(Overlay::getDisplayOrderPriority));
private Queue<Overlay<?>> popupQueue = new PriorityQueue<>(Comparator.comparing(Overlay::getDisplayOrderPriority));
///////////////////////////////////////////////////////////////////////////////////////////
@ -362,7 +362,7 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
.show());
bisqSetup.setDisplayLocalhostHandler(key -> {
if (!DevEnv.isDevMode()) {
Overlay popup = new Popup().backgroundInfo(Res.get("popup.bitcoinLocalhostNode.msg") +
Popup popup = new Popup().backgroundInfo(Res.get("popup.bitcoinLocalhostNode.msg") +
Res.get("popup.bitcoinLocalhostNode.additionalRequirements"))
.dontShowAgainId(key);
popup.setDisplayOrderPriority(5);
@ -396,14 +396,14 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
tradeManager.getTradesWithoutDepositTx().addListener((ListChangeListener<Trade>) c -> {
c.next();
if (c.wasAdded()) {
c.getAddedSubList().forEach(trade -> {
new Popup().warning(Res.get("popup.warning.trade.depositTxNull", trade.getShortId()))
.actionButtonText(Res.get("popup.warning.trade.depositTxNull.shutDown"))
.onAction(() -> BisqApp.getShutDownHandler().run())
.secondaryActionButtonText(Res.get("popup.warning.trade.depositTxNull.moveToFailedTrades"))
.onSecondaryAction(() -> tradeManager.addTradeToFailedTrades(trade))
.show();
});
c.getAddedSubList().forEach(trade ->
new Popup().warning(Res.get("popup.warning.trade.depositTxNull", trade.getShortId()))
.actionButtonText(Res.get("popup.warning.trade.depositTxNull.shutDown"))
.onAction(() -> BisqApp.getShutDownHandler().run())
.secondaryActionButtonText(Res.get("popup.warning.trade.depositTxNull.moveToFailedTrades"))
.onSecondaryAction(() -> tradeManager.addTradeToFailedTrades(trade))
.show()
);
}
});
@ -682,7 +682,7 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
private void maybeShowPopupsFromQueue() {
if (!popupQueue.isEmpty()) {
Overlay overlay = popupQueue.poll();
Overlay<?> overlay = popupQueue.poll();
overlay.getIsHiddenProperty().addListener((observable, oldValue, newValue) -> {
if (newValue) {
UserThread.runAfter(this::maybeShowPopupsFromQueue, 2);

View file

@ -23,6 +23,11 @@ import bisq.core.locale.Res;
import bisq.common.util.Utilities;
import com.google.common.base.Suppliers;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@ -31,17 +36,27 @@ import lombok.extern.slf4j.Slf4j;
@Getter
@EqualsAndHashCode
public abstract class StateBlockListItem<StH extends StateHash, StB extends StateBlock<StH>> {
protected final StateBlock<StH> stateBlock;
protected final String height;
protected final String hash;
protected final String prevHash;
protected final String numNetworkMessages;
protected final String numMisMatches;
protected final boolean isInSync;
private final StateBlock<StH> stateBlock;
private final Supplier<String> height;
private final String hash;
private final String prevHash;
private final String numNetworkMessages;
private final String numMisMatches;
private final boolean isInSync;
public String getHeight() {
return height.get();
}
protected StateBlockListItem(StB stateBlock, int cycleIndex) {
this(stateBlock, () -> cycleIndex);
}
protected StateBlockListItem(StB stateBlock, IntSupplier cycleIndexSupplier) {
this.stateBlock = stateBlock;
height = Res.get("dao.monitor.table.cycleBlockHeight", cycleIndex + 1, String.valueOf(stateBlock.getHeight()));
height = Suppliers.memoize(() ->
Res.get("dao.monitor.table.cycleBlockHeight", cycleIndexSupplier.getAsInt() + 1,
String.valueOf(stateBlock.getHeight())))::get;
hash = Utilities.bytesAsHexString(stateBlock.getHash());
prevHash = stateBlock.getPrevHash().length > 0 ? Utilities.bytesAsHexString(stateBlock.getPrevHash()) : "-";
numNetworkMessages = String.valueOf(stateBlock.getPeersMap().size());

View file

@ -22,6 +22,8 @@ import bisq.desktop.main.dao.monitor.StateBlockListItem;
import bisq.core.dao.monitoring.model.DaoStateBlock;
import bisq.core.dao.monitoring.model.DaoStateHash;
import java.util.function.IntSupplier;
import lombok.EqualsAndHashCode;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
@ -30,8 +32,7 @@ import lombok.extern.slf4j.Slf4j;
@Value
@EqualsAndHashCode(callSuper = true)
class DaoStateBlockListItem extends StateBlockListItem<DaoStateHash, DaoStateBlock> {
DaoStateBlockListItem(DaoStateBlock stateBlock, int cycleIndex) {
super(stateBlock, cycleIndex);
DaoStateBlockListItem(DaoStateBlock stateBlock, IntSupplier cycleIndexSupplier) {
super(stateBlock, cycleIndexSupplier);
}
}

View file

@ -19,7 +19,6 @@ package bisq.desktop.main.dao.monitor.daostate;
import bisq.desktop.common.view.FxmlView;
import bisq.desktop.main.dao.monitor.StateMonitorView;
import bisq.desktop.main.overlays.Overlay;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.util.FormBuilder;
@ -46,6 +45,7 @@ import javafx.collections.ListChangeListener;
import java.io.File;
import java.util.Map;
import java.util.function.IntSupplier;
import java.util.stream.Collectors;
@FxmlView
@ -53,7 +53,7 @@ public class DaoStateMonitorView extends StateMonitorView<DaoStateHash, DaoState
implements DaoStateMonitoringService.Listener {
private final DaoStateMonitoringService daoStateMonitoringService;
private ListChangeListener<UtxoMismatch> utxoMismatchListChangeListener;
private Overlay warningPopup;
private Popup warningPopup;
///////////////////////////////////////////////////////////////////////////////////////////
@ -127,8 +127,10 @@ public class DaoStateMonitorView extends StateMonitorView<DaoStateHash, DaoState
@Override
protected DaoStateBlockListItem getStateBlockListItem(DaoStateBlock daoStateBlock) {
int cycleIndex = periodService.getCycle(daoStateBlock.getHeight()).map(cycleService::getCycleIndex).orElse(0);
return new DaoStateBlockListItem(daoStateBlock, cycleIndex);
IntSupplier cycleIndexSupplier = () -> periodService.getCycle(daoStateBlock.getHeight())
.map(cycleService::getCycleIndex)
.orElse(0);
return new DaoStateBlockListItem(daoStateBlock, cycleIndexSupplier);
}
@Override
@ -208,17 +210,16 @@ public class DaoStateMonitorView extends StateMonitorView<DaoStateHash, DaoState
private void updateUtxoMismatches() {
if (!daoStateMonitoringService.getUtxoMismatches().isEmpty()) {
StringBuilder sb = new StringBuilder();
daoStateMonitoringService.getUtxoMismatches().forEach(e -> {
sb.append("\n").append(Res.get("dao.monitor.daoState.utxoConflicts.blockHeight", e.getHeight())).append("\n")
.append(Res.get("dao.monitor.daoState.utxoConflicts.sumUtxo", e.getSumUtxo() / 100)).append("\n")
.append(Res.get("dao.monitor.daoState.utxoConflicts.sumBsq", e.getSumBsq() / 100));
});
daoStateMonitoringService.getUtxoMismatches().forEach(e -> sb.append("\n")
.append(Res.get("dao.monitor.daoState.utxoConflicts.blockHeight", e.getHeight())).append("\n")
.append(Res.get("dao.monitor.daoState.utxoConflicts.sumUtxo", e.getSumUtxo() / 100)).append("\n")
.append(Res.get("dao.monitor.daoState.utxoConflicts.sumBsq", e.getSumBsq() / 100))
);
if (warningPopup == null) {
warningPopup = new Popup().headLine(Res.get("dao.monitor.daoState.utxoConflicts"))
.warning(Utilities.toTruncatedString(sb.toString(), 500, false)).onClose(() -> {
warningPopup = null;
});
.warning(Utilities.toTruncatedString(sb.toString(), 500, false))
.onClose(() -> warningPopup = null);
warningPopup.show();
}
}

View file

@ -20,7 +20,6 @@ package bisq.desktop.main.portfolio.pendingtrades.steps;
import bisq.desktop.components.InfoTextField;
import bisq.desktop.components.TitledGroupBg;
import bisq.desktop.components.TxIdTextField;
import bisq.desktop.main.overlays.Overlay;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.portfolio.pendingtrades.PendingTradesViewModel;
import bisq.desktop.main.portfolio.pendingtrades.TradeStepInfo;
@ -93,7 +92,7 @@ public abstract class TradeStepView extends AnchorPane {
private ClockWatcher.Listener clockListener;
private final ChangeListener<String> errorMessageListener;
protected Label infoLabel;
private Overlay acceptMediationResultPopup;
private Popup acceptMediationResultPopup;
private BootstrapListener bootstrapListener;

View file

@ -0,0 +1,63 @@
/*
* This file is part of Bisq.
*
* Bisq 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.
*
* Bisq 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 Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.dao.monitor.daostate;
import bisq.core.dao.monitoring.model.DaoStateBlock;
import bisq.core.dao.monitoring.model.DaoStateHash;
import bisq.core.locale.Res;
import java.util.Locale;
import java.util.function.IntSupplier;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class DaoStateBlockListItemTest {
@Before
public void setup() {
Locale.setDefault(new Locale("en", "US"));
Res.setBaseCurrencyCode("BTC");
Res.setBaseCurrencyName("Bitcoin");
}
@Test
public void testEqualsAndHashCode() {
var block = new DaoStateBlock(new DaoStateHash(0, new byte[0], new byte[0]));
var item1 = new DaoStateBlockListItem(block, newSupplier(1));
var item2 = new DaoStateBlockListItem(block, newSupplier(2));
var item3 = new DaoStateBlockListItem(block, newSupplier(1));
assertNotEquals(item1, item2);
assertNotEquals(item2, item3);
assertEquals(item1, item3);
assertEquals(item1.hashCode(), item3.hashCode());
}
private IntSupplier newSupplier(int i) {
//noinspection Convert2Lambda
return new IntSupplier() {
@Override
public int getAsInt() {
return i;
}
};
}
}