Optimize RefreshTTLMessage, add UIClock

This commit is contained in:
Manfred Karrer 2016-02-19 18:13:45 +01:00
parent f5a61f9924
commit 79de2bcb11
18 changed files with 241 additions and 224 deletions

View file

@ -21,10 +21,12 @@ import com.google.inject.Singleton;
import io.bitsquare.alert.AlertModule;
import io.bitsquare.arbitration.ArbitratorModule;
import io.bitsquare.btc.BitcoinModule;
import io.bitsquare.common.Clock;
import io.bitsquare.common.crypto.KeyRing;
import io.bitsquare.common.crypto.KeyStorage;
import io.bitsquare.crypto.EncryptionServiceModule;
import io.bitsquare.gui.GuiModule;
import io.bitsquare.gui.common.UIClock;
import io.bitsquare.gui.common.view.CachingViewLoader;
import io.bitsquare.gui.main.intructions.InstructionCenter;
import io.bitsquare.gui.main.notifications.NotificationCenter;
@ -62,6 +64,7 @@ class BitsquareAppModule extends AppModule {
bind(Preferences.class).in(Singleton.class);
bind(NotificationCenter.class).in(Singleton.class);
bind(InstructionCenter.class).in(Singleton.class);
bind(Clock.class).to(UIClock.class).in(Singleton.class);
File storageDir = new File(env.getRequiredProperty(Storage.DIR_KEY));
bind(File.class).annotatedWith(named(Storage.DIR_KEY)).toInstance(storageDir);

View file

@ -0,0 +1,52 @@
package io.bitsquare.gui.common;
import io.bitsquare.common.Clock;
import org.reactfx.util.FxTimer;
import org.reactfx.util.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.util.LinkedList;
import java.util.List;
public class UIClock implements Clock {
private static final Logger log = LoggerFactory.getLogger(UIClock.class);
private Timer timer;
private final List<Listener> listeners = new LinkedList<>();
private long counter = 0;
public UIClock() {
}
@Override
public void start() {
if (timer == null)
timer = FxTimer.runPeriodically(Duration.ofSeconds(1), () -> {
listeners.stream().forEach(Listener::onSecondTick);
counter++;
if (counter >= 60) {
counter = 0;
listeners.stream().forEach(Listener::onMinuteTick);
}
});
}
@Override
public void stop() {
timer.stop();
timer = null;
counter = 0;
}
@Override
public void addListener(Listener listener) {
listeners.add(listener);
}
@Override
public void removeListener(Listener listener) {
listeners.remove(listener);
}
}

View file

@ -32,6 +32,7 @@ import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.btc.pricefeed.MarketPriceFeed;
import io.bitsquare.common.Clock;
import io.bitsquare.common.UserThread;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.common.model.ViewModel;
@ -93,6 +94,7 @@ public class MainViewModel implements ViewModel {
private final WalletPasswordPopup walletPasswordPopup;
private final NotificationCenter notificationCenter;
private final TacPopup tacPopup;
private Clock clock;
private final Navigation navigation;
private final BSFormatter formatter;
@ -132,12 +134,12 @@ public class MainViewModel implements ViewModel {
private final MarketPriceFeed marketPriceFeed;
private final User user;
private int numBTCPeers = 0;
private Timer checkForBtcSyncStateTimer;
private ChangeListener<Number> numConnectedPeersListener, btcNumPeersListener;
private java.util.Timer numberOfBtcPeersTimer;
private java.util.Timer numberOfP2PNetworkPeersTimer;
private Timer startupTimeout;
private final Map<String, Subscription> disputeIsClosedSubscriptionsMap = new HashMap<>();
private Subscription downloadPercentageSubscription;
///////////////////////////////////////////////////////////////////////////////////////////
@ -150,7 +152,7 @@ public class MainViewModel implements ViewModel {
ArbitratorManager arbitratorManager, P2PService p2PService, TradeManager tradeManager,
OpenOfferManager openOfferManager, DisputeManager disputeManager, Preferences preferences,
User user, AlertManager alertManager, WalletPasswordPopup walletPasswordPopup,
NotificationCenter notificationCenter, TacPopup tacPopup,
NotificationCenter notificationCenter, TacPopup tacPopup, Clock clock,
Navigation navigation, BSFormatter formatter) {
this.marketPriceFeed = marketPriceFeed;
this.user = user;
@ -166,6 +168,7 @@ public class MainViewModel implements ViewModel {
this.walletPasswordPopup = walletPasswordPopup;
this.notificationCenter = notificationCenter;
this.tacPopup = tacPopup;
this.clock = clock;
this.navigation = navigation;
this.formatter = formatter;
@ -215,9 +218,8 @@ public class MainViewModel implements ViewModel {
if (btcNumPeersListener != null)
walletService.numPeersProperty().removeListener(btcNumPeersListener);
if (checkForBtcSyncStateTimer != null)
checkForBtcSyncStateTimer.stop();
if (downloadPercentageSubscription != null)
downloadPercentageSubscription.unsubscribe();
}
@ -320,7 +322,8 @@ public class MainViewModel implements ViewModel {
}
private BooleanProperty initBitcoinWallet() {
EasyBind.subscribe(walletService.downloadPercentageProperty(), newValue -> setBitcoinNetworkSyncProgress((double) newValue));
downloadPercentageSubscription = EasyBind.subscribe(walletService.downloadPercentageProperty(),
percentage -> setBitcoinNetworkSyncProgress((double) percentage));
btcNumPeersListener = (observable, oldValue, newValue) -> {
if ((int) oldValue > 0 && (int) newValue == 0) {
@ -340,8 +343,8 @@ public class MainViewModel implements ViewModel {
}
numBTCPeers = (int) newValue;
setBitcoinNetworkSyncProgress(walletService.downloadPercentageProperty().get());
};
walletService.numPeersProperty().addListener(btcNumPeersListener);
final BooleanProperty walletInitialized = new SimpleBooleanProperty();
@ -357,6 +360,8 @@ public class MainViewModel implements ViewModel {
private void onAllServicesInitialized() {
Log.traceCall();
clock.start();
startupTimeout.stop();
// disputeManager
@ -395,9 +400,6 @@ public class MainViewModel implements ViewModel {
}
});
setBitcoinNetworkSyncProgress(walletService.downloadPercentageProperty().get());
checkPeriodicallyForBtcSyncState();
openOfferManager.getOpenOffers().addListener((ListChangeListener<OpenOffer>) c -> updateBalance());
openOfferManager.onAllServicesInitialized();
arbitratorManager.onAllServicesInitialized();
@ -427,7 +429,7 @@ public class MainViewModel implements ViewModel {
// in MainView showAppScreen handler
notificationCenter.onAllServicesAndViewsInitialized();
}
///////////////////////////////////////////////////////////////////////////////////////////
// States
@ -555,19 +557,6 @@ public class MainViewModel implements ViewModel {
typeProperty.bind(marketPriceFeed.typeProperty());
}
private void checkPeriodicallyForBtcSyncState() {
if (walletService.downloadPercentageProperty().get() == -1) {
checkForBtcSyncStateTimer = FxTimer.runPeriodically(Duration.ofSeconds(10),
() -> {
log.info("Bitcoin blockchain sync still not started.");
setBitcoinNetworkSyncProgress(walletService.downloadPercentageProperty().get());
}
);
} else {
stopCheckForBtcSyncStateTimer();
}
}
private void updateP2pNetworkInfoWithPeersChanged(int numPeers) {
p2PNetworkInfo.set("Nr. of P2P network peers: " + numPeers);
}
@ -690,12 +679,12 @@ public class MainViewModel implements ViewModel {
btcSplashInfo.set(numPeers + " / synchronized with " + btcNetworkAsString);
btcFooterInfo.set(btcSplashInfo.get());
btcSplashSyncIconId.set("image-connection-synced");
stopCheckForBtcSyncStateTimer();
if (downloadPercentageSubscription != null)
downloadPercentageSubscription.unsubscribe();
} else if (value > 0.0) {
String percentage = formatter.formatToPercent(value);
btcSplashInfo.set(numPeers + " / synchronizing with " + btcNetworkAsString + ": " + percentage);
btcFooterInfo.set(numPeers + " / synchronizing " + btcNetworkAsString + ": " + percentage);
stopCheckForBtcSyncStateTimer();
} else if (value == -1) {
btcSplashInfo.set(numPeers + " / connecting to " + btcNetworkAsString);
btcFooterInfo.set(btcSplashInfo.get());
@ -705,7 +694,6 @@ public class MainViewModel implements ViewModel {
}
private void setWalletServiceException(Throwable error) {
setBitcoinNetworkSyncProgress(0);
btcSplashInfo.set("Nr. of Bitcoin network peers: " + numBTCPeers + " / connecting to " + btcNetworkAsString + " failed");
btcFooterInfo.set(btcSplashInfo.get());
if (error instanceof TimeoutException) {
@ -722,13 +710,6 @@ public class MainViewModel implements ViewModel {
}
}
private void stopCheckForBtcSyncStateTimer() {
if (checkForBtcSyncStateTimer != null) {
checkForBtcSyncStateTimer.stop();
checkForBtcSyncStateTimer = null;
}
}
private void setupDevDummyPaymentAccount() {
if (BitsquareApp.DEV_MODE && user.getPaymentAccounts().isEmpty()) {
OKPayAccount okPayAccount = new OKPayAccount();

View file

@ -20,6 +20,7 @@ package io.bitsquare.gui.main.portfolio.pendingtrades;
import com.google.inject.Inject;
import io.bitsquare.app.Log;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.common.Clock;
import io.bitsquare.gui.common.model.ActivatableWithDataModel;
import io.bitsquare.gui.common.model.ViewModel;
import io.bitsquare.gui.util.BSFormatter;
@ -69,6 +70,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
public final P2PService p2PService;
public final User user;
public final Clock clock;
private final ObjectProperty<BuyerState> buyerState = new SimpleObjectProperty<>();
private final ObjectProperty<SellerState> sellerState = new SimpleObjectProperty<>();
@ -85,14 +87,15 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
BSFormatter formatter,
BtcAddressValidator btcAddressValidator,
P2PService p2PService,
User user
) {
User user,
Clock clock) {
super(dataModel);
this.formatter = formatter;
this.btcAddressValidator = btcAddressValidator;
this.p2PService = p2PService;
this.user = user;
this.clock = clock;
}
private ChangeListener<Trade.State> tradeStateChangeListener;

View file

@ -19,6 +19,7 @@ package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
import io.bitsquare.app.Log;
import io.bitsquare.arbitration.Dispute;
import io.bitsquare.common.Clock;
import io.bitsquare.gui.components.TitledGroupBg;
import io.bitsquare.gui.components.TxIdTextField;
import io.bitsquare.gui.components.paymentmethods.PaymentMethodForm;
@ -34,12 +35,9 @@ import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
import org.reactfx.util.FxTimer;
import org.reactfx.util.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
@ -56,7 +54,6 @@ public abstract class TradeStepView extends AnchorPane {
private Subscription errorMessageSubscription;
private Subscription disputeStateSubscription;
private Subscription tradePeriodStateSubscription;
private Timer timer;
protected int gridRow = 0;
protected TitledGroupBg tradeInfoTitledGroupBg;
private TextField timeLeftTextField;
@ -64,6 +61,7 @@ public abstract class TradeStepView extends AnchorPane {
private TxIdTextField txIdTextField;
protected TradeSubView.NotificationGroup notificationGroup;
private Subscription txIdSubscription;
private Clock.Listener clockListener;
///////////////////////////////////////////////////////////////////////////////////////////
@ -113,7 +111,17 @@ public abstract class TradeStepView extends AnchorPane {
}
});
timer = FxTimer.runPeriodically(Duration.ofMinutes(1), this::updateTimeLeft);
clockListener = new Clock.Listener() {
@Override
public void onSecondTick() {
}
@Override
public void onMinuteTick() {
updateTimeLeft();
}
};
model.clock.addListener(clockListener);
}
public void deactivate() {
@ -133,8 +141,8 @@ public abstract class TradeStepView extends AnchorPane {
if (tradePeriodStateSubscription != null)
tradePeriodStateSubscription.unsubscribe();
if (timer != null)
timer.stop();
if (clockListener != null)
model.clock.removeListener(clockListener);
if (notificationGroup != null)
notificationGroup.button.setOnAction(null);

View file

@ -20,6 +20,7 @@ package io.bitsquare.gui.main.settings.network;
import io.bitsquare.app.BitsquareApp;
import io.bitsquare.btc.BitcoinNetwork;
import io.bitsquare.btc.WalletService;
import io.bitsquare.common.Clock;
import io.bitsquare.gui.common.model.Activatable;
import io.bitsquare.gui.common.view.ActivatableViewAndModel;
import io.bitsquare.gui.common.view.FxmlView;
@ -52,6 +53,7 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
private final WalletService walletService;
private final Preferences preferences;
private Clock clock;
private final BSFormatter formatter;
private final P2PService p2PService;
@ -79,11 +81,12 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
private ChangeListener<List<Peer>> bitcoinPeersChangeListener;
@Inject
public NetworkSettingsView(WalletService walletService, P2PService p2PService, Preferences preferences,
public NetworkSettingsView(WalletService walletService, P2PService p2PService, Preferences preferences, Clock clock,
BSFormatter formatter) {
this.walletService = walletService;
this.p2PService = p2PService;
this.preferences = preferences;
this.clock = clock;
this.formatter = formatter;
}
@ -214,7 +217,7 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
p2PPeerTable.getItems().forEach(NetworkStatisticListItem::cleanup);
List<NetworkStatisticListItem> list = p2PService.getNetworkNode().getConfirmedConnections().stream()
.map(connection -> new NetworkStatisticListItem(connection, formatter))
.map(connection -> new NetworkStatisticListItem(connection, clock, formatter))
.collect(Collectors.toList());
p2PPeerTable.setItems(FXCollections.observableArrayList(list));
p2PPeerTable.sort();

View file

@ -17,7 +17,7 @@
package io.bitsquare.gui.main.settings.network;
import io.bitsquare.common.UserThread;
import io.bitsquare.common.Clock;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.p2p.network.Connection;
import io.bitsquare.p2p.network.OutboundConnection;
@ -27,28 +27,26 @@ import javafx.beans.property.StringProperty;
import org.apache.commons.lang3.time.DurationFormatUtils;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
import org.reactfx.util.FxTimer;
import org.reactfx.util.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
public class NetworkStatisticListItem {
private static final Logger log = LoggerFactory.getLogger(NetworkStatisticListItem.class);
private final Statistic statistic;
private final Connection connection;
private final Subscription sentBytesSubscription, receivedBytesSubscription;
private final Timer timer;
private final Clock clock;
private final BSFormatter formatter;
private final StringProperty lastActivity = new SimpleStringProperty();
private final StringProperty sentBytes = new SimpleStringProperty();
private final StringProperty receivedBytes = new SimpleStringProperty();
private final Clock.Listener listener;
public NetworkStatisticListItem(Connection connection, BSFormatter formatter) {
public NetworkStatisticListItem(Connection connection, Clock clock, BSFormatter formatter) {
this.connection = connection;
this.clock = clock;
this.formatter = formatter;
this.statistic = connection.getStatistic();
@ -57,8 +55,18 @@ public class NetworkStatisticListItem {
receivedBytesSubscription = EasyBind.subscribe(statistic.receivedBytesProperty(),
e -> receivedBytes.set(formatter.formatBytes((int) e)));
timer = FxTimer.runPeriodically(Duration.ofMillis(1000),
() -> UserThread.execute(() -> onLastActivityChanged(statistic.getLastActivityTimestamp())));
listener = new Clock.Listener() {
@Override
public void onSecondTick() {
onLastActivityChanged(statistic.getLastActivityTimestamp());
}
@Override
public void onMinuteTick() {
}
};
clock.addListener(listener);
onLastActivityChanged(statistic.getLastActivityTimestamp());
}
@ -69,7 +77,7 @@ public class NetworkStatisticListItem {
public void cleanup() {
sentBytesSubscription.unsubscribe();
receivedBytesSubscription.unsubscribe();
timer.stop();
clock.removeListener(listener);
}
public String getOnionAddress() {