mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-06 05:34:50 -04:00
Refactor check offer availability
This commit is contained in:
parent
6888eacc24
commit
87539db93d
13 changed files with 320 additions and 302 deletions
|
@ -134,7 +134,7 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||||
offer.getStateProperty().addListener((observable, oldValue, newValue) -> {
|
offer.getStateProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
offerIsAvailable.set(newValue);
|
offerIsAvailable.set(newValue);
|
||||||
});
|
});
|
||||||
tradeManager.onGetOfferAvailableStateRequested(offer);
|
tradeManager.onCheckOfferAvailability(offer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void takeOffer() {
|
void takeOffer() {
|
||||||
|
|
|
@ -30,16 +30,16 @@ import io.bitsquare.offer.OfferBookService;
|
||||||
import io.bitsquare.offer.OpenOffer;
|
import io.bitsquare.offer.OpenOffer;
|
||||||
import io.bitsquare.persistence.Persistence;
|
import io.bitsquare.persistence.Persistence;
|
||||||
import io.bitsquare.trade.handlers.TransactionResultHandler;
|
import io.bitsquare.trade.handlers.TransactionResultHandler;
|
||||||
|
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.protocol.offer.CheckOfferAvailabilityModel;
|
||||||
|
import io.bitsquare.trade.protocol.offer.CheckOfferAvailabilityProtocol;
|
||||||
|
import io.bitsquare.trade.protocol.offer.messages.ReportOfferAvailabilityMessage;
|
||||||
|
import io.bitsquare.trade.protocol.offer.messages.RequestIsOfferAvailableMessage;
|
||||||
import io.bitsquare.trade.protocol.placeoffer.PlaceOfferProtocol;
|
import io.bitsquare.trade.protocol.placeoffer.PlaceOfferProtocol;
|
||||||
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.BuyerAsOffererModel;
|
import io.bitsquare.trade.protocol.trade.offerer.BuyerAsOffererModel;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.BuyerAsOffererProtocol;
|
import io.bitsquare.trade.protocol.trade.offerer.BuyerAsOffererProtocol;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.messages.IsOfferAvailableResponseMessage;
|
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.IsOfferAvailableResponse;
|
|
||||||
import io.bitsquare.trade.protocol.trade.taker.RequestIsOfferAvailableProtocol;
|
|
||||||
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerModel;
|
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerModel;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerProtocol;
|
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerProtocol;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.messages.RequestIsOfferAvailableMessage;
|
|
||||||
import io.bitsquare.user.User;
|
import io.bitsquare.user.User;
|
||||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||||
import io.bitsquare.util.handlers.ResultHandler;
|
import io.bitsquare.util.handlers.ResultHandler;
|
||||||
|
@ -55,8 +55,6 @@ import javax.inject.Inject;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableMap;
|
import javafx.collections.ObservableMap;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -81,7 +79,7 @@ public class TradeManager {
|
||||||
//TODO store TakerAsSellerProtocol in trade
|
//TODO store TakerAsSellerProtocol in trade
|
||||||
private final Map<String, SellerAsTakerProtocol> takerAsSellerProtocolMap = new HashMap<>();
|
private final Map<String, SellerAsTakerProtocol> takerAsSellerProtocolMap = new HashMap<>();
|
||||||
private final Map<String, BuyerAsOffererProtocol> offererAsBuyerProtocolMap = new HashMap<>();
|
private final Map<String, BuyerAsOffererProtocol> offererAsBuyerProtocolMap = new HashMap<>();
|
||||||
private final Map<String, RequestIsOfferAvailableProtocol> requestIsOfferAvailableProtocolMap = new HashMap<>();
|
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
|
||||||
|
|
||||||
private final ObservableMap<String, OpenOffer> openOffers = FXCollections.observableHashMap();
|
private final ObservableMap<String, OpenOffer> openOffers = FXCollections.observableHashMap();
|
||||||
private final ObservableMap<String, Trade> pendingTrades = FXCollections.observableHashMap();
|
private final ObservableMap<String, Trade> pendingTrades = FXCollections.observableHashMap();
|
||||||
|
@ -124,16 +122,7 @@ public class TradeManager {
|
||||||
closedTrades.putAll((Map<String, Trade>) closedTradesObject);
|
closedTrades.putAll((Map<String, Trade>) closedTradesObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
tradeMessageService.addMessageHandler(this::handleNewMessage);
|
tradeMessageService.addMessageHandler(this::handleMessage);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Public Methods
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void cleanup() {
|
|
||||||
tradeMessageService.removeMessageHandler(this::handleNewMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,20 +130,23 @@ public class TradeManager {
|
||||||
// Called from UI
|
// Called from UI
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public void onGetOfferAvailableStateRequested(Offer offer) {
|
public void onCheckOfferAvailability(Offer offer) {
|
||||||
if (!requestIsOfferAvailableProtocolMap.containsKey(offer.getId())) {
|
if (!checkOfferAvailabilityProtocolMap.containsKey(offer.getId())) {
|
||||||
RequestIsOfferAvailableProtocol protocol = new RequestIsOfferAvailableProtocol(offer, tradeMessageService);
|
|
||||||
requestIsOfferAvailableProtocolMap.put(offer.getId(), protocol);
|
CheckOfferAvailabilityModel model = new CheckOfferAvailabilityModel(offer, tradeMessageService, () -> {
|
||||||
protocol.start();
|
});
|
||||||
|
CheckOfferAvailabilityProtocol protocol = new CheckOfferAvailabilityProtocol(model);
|
||||||
|
checkOfferAvailabilityProtocolMap.put(offer.getId(), protocol);
|
||||||
|
protocol.onCheckOfferAvailability();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log.warn("requestIsOfferAvailable already called for offer with ID:" + offer.getId());
|
log.error("onGetOfferAvailableStateRequested already called for offer with ID:" + offer.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When closing take offer view, we are not interested in the requestIsOfferAvailable result anymore, so remove from the map
|
// When closing take offer view, we are not interested in the requestIsOfferAvailable result anymore, so remove from the map
|
||||||
public void onGetOfferAvailableStateRequestCanceled(Offer offer) {
|
public void onGetOfferAvailableStateRequestCanceled(Offer offer) {
|
||||||
requestIsOfferAvailableProtocolMap.remove(offer.getId());
|
cleanupCheckOfferAvailabilityProtocolMap(offer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPlaceOfferRequested(String id,
|
public void onPlaceOfferRequested(String id,
|
||||||
|
@ -201,7 +193,6 @@ public class TradeManager {
|
||||||
removeOpenOffer(offerId, resultHandler, errorMessageHandler, true);
|
removeOpenOffer(offerId, resultHandler, errorMessageHandler, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Trade onTakeOfferRequested(Coin amount, Offer offer) {
|
public Trade onTakeOfferRequested(Coin amount, Offer offer) {
|
||||||
Trade trade = createTrade(offer);
|
Trade trade = createTrade(offer);
|
||||||
trade.setTradeAmount(amount);
|
trade.setTradeAmount(amount);
|
||||||
|
@ -263,13 +254,39 @@ public class TradeManager {
|
||||||
closeTrade(trade, false);
|
closeTrade(trade, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Called from Offerbook (DHT)
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Called from Offerbook when offer gets removed from DHT
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public void onOfferRemovedFromRemoteOfferBook(Offer offer) {
|
public void onOfferRemovedFromRemoteOfferBook(Offer offer) {
|
||||||
requestIsOfferAvailableProtocolMap.remove(offer.getId());
|
cleanupCheckOfferAvailabilityProtocolMap(offer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Process new tradeMessages
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Routes the incoming messages to the responsible protocol
|
||||||
|
private void handleMessage(Message message, Peer sender) {
|
||||||
|
if (message instanceof RequestIsOfferAvailableMessage) {
|
||||||
|
String offerId = ((RequestIsOfferAvailableMessage) message).getOfferId();
|
||||||
|
checkNotNull(offerId);
|
||||||
|
|
||||||
|
ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = new ReportOfferAvailabilityMessage(offerId, isOfferOpen(offerId));
|
||||||
|
tradeMessageService.sendMessage(sender, reportOfferAvailabilityMessage, new SendMessageListener() {
|
||||||
|
@Override
|
||||||
|
public void handleResult() {
|
||||||
|
log.trace("ReportOfferAvailabilityMessage successfully arrived at peer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleFault() {
|
||||||
|
log.warn("Sending ReportOfferAvailabilityMessage failed.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -291,12 +308,14 @@ public class TradeManager {
|
||||||
offerBookService.removeOffer(openOffers.get(offerId).getOffer(),
|
offerBookService.removeOffer(openOffers.get(offerId).getOffer(),
|
||||||
() -> {
|
() -> {
|
||||||
if (openOffers.containsKey(offerId)) {
|
if (openOffers.containsKey(offerId)) {
|
||||||
openOffers.remove(offerId);
|
OpenOffer openOffer = openOffers.remove(offerId);
|
||||||
|
cleanupCheckOfferAvailabilityProtocolMap(openOffer.getOffer());
|
||||||
persistOpenOffers();
|
persistOpenOffers();
|
||||||
if (removeFromOffererAsBuyerProtocolMap && offererAsBuyerProtocolMap.containsKey(offerId)) {
|
if (removeFromOffererAsBuyerProtocolMap && offererAsBuyerProtocolMap.containsKey(offerId)) {
|
||||||
offererAsBuyerProtocolMap.get(offerId).cleanup();
|
offererAsBuyerProtocolMap.get(offerId).cleanup();
|
||||||
offererAsBuyerProtocolMap.remove(offerId);
|
offererAsBuyerProtocolMap.remove(offerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
resultHandler.handleResult();
|
resultHandler.handleResult();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -400,7 +419,6 @@ public class TradeManager {
|
||||||
offererAsBuyerProtocolMap.remove(trade.getId());
|
offererAsBuyerProtocolMap.remove(trade.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!failed) {
|
if (!failed) {
|
||||||
closedTrades.put(trade.getId(), trade);
|
closedTrades.put(trade.getId(), trade);
|
||||||
persistClosedTrades();
|
persistClosedTrades();
|
||||||
|
@ -410,51 +428,19 @@ public class TradeManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
private void cleanupCheckOfferAvailabilityProtocolMap(Offer offer) {
|
||||||
// Process new tradeMessages
|
if (checkOfferAvailabilityProtocolMap.containsKey(offer.getId())) {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
CheckOfferAvailabilityProtocol protocol = checkOfferAvailabilityProtocolMap.get(offer.getId());
|
||||||
|
protocol.cancel();
|
||||||
// TODO remove
|
protocol.cleanup();
|
||||||
// Routes the incoming messages to the responsible protocol
|
checkOfferAvailabilityProtocolMap.remove(offer.getId());
|
||||||
private void handleNewMessage(Message message, Peer sender) {
|
|
||||||
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName());
|
|
||||||
log.trace("handleNewMessage: sender = " + sender);
|
|
||||||
|
|
||||||
|
|
||||||
if (message instanceof OfferMessage) {
|
|
||||||
OfferMessage offerMessage = (OfferMessage) message;
|
|
||||||
// Before starting any take offer activity we check if the offer is still available.
|
|
||||||
if (offerMessage instanceof RequestIsOfferAvailableMessage) {
|
|
||||||
// That message arrives at the offerer and he returns if the offer is still available (if there is no trade already created with that offerId).
|
|
||||||
String offerId = offerMessage.getOfferId();
|
|
||||||
checkNotNull(offerId);
|
|
||||||
boolean isOfferOpen = getTrade(offerId) == null;
|
|
||||||
// no handling of results or faults needed
|
|
||||||
IsOfferAvailableResponse.run(sender, tradeMessageService, offerId, isOfferOpen);
|
|
||||||
}
|
|
||||||
else if (offerMessage instanceof IsOfferAvailableResponseMessage) {
|
|
||||||
// That message arrives at the taker in response to a previous requestIsOfferAvailable call.
|
|
||||||
// It might be that the offer got removed form the offer book, so lets check if its still there.
|
|
||||||
if (requestIsOfferAvailableProtocolMap.containsKey(offerMessage.getOfferId())) {
|
|
||||||
RequestIsOfferAvailableProtocol protocol = requestIsOfferAvailableProtocolMap.get(offerMessage.getOfferId());
|
|
||||||
protocol.handleIsOfferAvailableResponseMessage((IsOfferAvailableResponseMessage) offerMessage);
|
|
||||||
requestIsOfferAvailableProtocolMap.remove(offerMessage.getOfferId());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.info("Offer might have been removed in the meantime. No protocol found for offer with ID:" + offerMessage.getOfferId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.error("Incoming offerMessage not supported. " + offerMessage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isOfferOpen(String offerId) {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
// Don't use openOffers as the offer gets removed async from DHT, but is added sync to pendingTrades
|
||||||
// Setters
|
return !pendingTrades.containsKey(offerId) && !closedTrades.containsKey(offerId);
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Getters
|
// Getters
|
||||||
|
@ -493,16 +479,4 @@ public class TradeManager {
|
||||||
persistence.write(this, "closedTrades", (Map<String, Trade>) new HashMap<>(closedTrades));
|
persistence.write(this, "closedTrades", (Map<String, Trade>) new HashMap<>(closedTrades));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Trade getTrade(String tradeId) {
|
|
||||||
if (pendingTrades.containsKey(tradeId)) {
|
|
||||||
return pendingTrades.get(tradeId);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.offer;
|
||||||
|
|
||||||
|
import io.bitsquare.network.Peer;
|
||||||
|
import io.bitsquare.offer.Offer;
|
||||||
|
import io.bitsquare.trade.TradeMessageService;
|
||||||
|
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
||||||
|
import io.bitsquare.util.handlers.ResultHandler;
|
||||||
|
import io.bitsquare.util.tasks.SharedModel;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class CheckOfferAvailabilityModel extends SharedModel {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CheckOfferAvailabilityModel.class);
|
||||||
|
|
||||||
|
private final Offer offer;
|
||||||
|
private final TradeMessageService tradeMessageService;
|
||||||
|
private final ResultHandler resultHandler;
|
||||||
|
|
||||||
|
private Peer peer;
|
||||||
|
private OfferMessage message;
|
||||||
|
|
||||||
|
public CheckOfferAvailabilityModel(Offer offer, TradeMessageService tradeMessageService, ResultHandler resultHandler) {
|
||||||
|
this.offer = offer;
|
||||||
|
this.tradeMessageService = tradeMessageService;
|
||||||
|
this.resultHandler = resultHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getter/setter
|
||||||
|
public Offer getOffer() {
|
||||||
|
return offer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeMessageService getTradeMessageService() {
|
||||||
|
return tradeMessageService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Peer getPeer() {
|
||||||
|
return peer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPeer(Peer peer) {
|
||||||
|
this.peer = peer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(OfferMessage message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfferMessage getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultHandler getResultHandler() {
|
||||||
|
return resultHandler;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.offer;
|
||||||
|
|
||||||
|
import io.bitsquare.network.Message;
|
||||||
|
import io.bitsquare.network.Peer;
|
||||||
|
import io.bitsquare.offer.Offer;
|
||||||
|
import io.bitsquare.trade.protocol.offer.messages.ReportOfferAvailabilityMessage;
|
||||||
|
import io.bitsquare.trade.protocol.offer.tasks.GetPeerAddress;
|
||||||
|
import io.bitsquare.trade.protocol.offer.tasks.RequestIsOfferAvailable;
|
||||||
|
import io.bitsquare.util.tasks.TaskRunner;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
||||||
|
|
||||||
|
public class CheckOfferAvailabilityProtocol {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CheckOfferAvailabilityProtocol.class);
|
||||||
|
|
||||||
|
private CheckOfferAvailabilityModel model;
|
||||||
|
private boolean isCanceled;
|
||||||
|
private TaskRunner<CheckOfferAvailabilityModel> sequence;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public CheckOfferAvailabilityProtocol(CheckOfferAvailabilityModel model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanup() {
|
||||||
|
model.getTradeMessageService().removeMessageHandler(this::handleMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Called from UI
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void onCheckOfferAvailability() {
|
||||||
|
model.getTradeMessageService().addMessageHandler(this::handleMessage);
|
||||||
|
|
||||||
|
sequence = new TaskRunner<>(model,
|
||||||
|
() -> {
|
||||||
|
log.debug("sequence at onCheckOfferAvailability completed");
|
||||||
|
},
|
||||||
|
(message, throwable) -> {
|
||||||
|
log.error(message);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
sequence.addTasks(
|
||||||
|
GetPeerAddress.class,
|
||||||
|
RequestIsOfferAvailable.class
|
||||||
|
);
|
||||||
|
sequence.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel() {
|
||||||
|
isCanceled = true;
|
||||||
|
sequence.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Incoming message handling
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void handleMessage(Message message, Peer sender) {
|
||||||
|
if (!isCanceled) {
|
||||||
|
if (message instanceof ReportOfferAvailabilityMessage) {
|
||||||
|
ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = (ReportOfferAvailabilityMessage) message;
|
||||||
|
nonEmptyStringOf(reportOfferAvailabilityMessage.getOfferId());
|
||||||
|
|
||||||
|
if (model.getOffer().getState() != Offer.State.OFFER_REMOVED) {
|
||||||
|
if (reportOfferAvailabilityMessage.isOfferOpen())
|
||||||
|
model.getOffer().setState(Offer.State.OFFER_AVAILABLE);
|
||||||
|
else
|
||||||
|
model.getOffer().setState(Offer.State.OFFER_NOT_AVAILABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model.getResultHandler().handleResult();
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,18 +15,18 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.trade.protocol.trade.offerer.messages;
|
package io.bitsquare.trade.protocol.offer.messages;
|
||||||
|
|
||||||
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
public class IsOfferAvailableResponseMessage implements Serializable, OfferMessage {
|
public class ReportOfferAvailabilityMessage implements Serializable, OfferMessage {
|
||||||
private static final long serialVersionUID = 6177387534187739018L;
|
private static final long serialVersionUID = 6177387534187739018L;
|
||||||
private final String offerId;
|
private final String offerId;
|
||||||
private final boolean isOfferOpen;
|
private final boolean isOfferOpen;
|
||||||
|
|
||||||
public IsOfferAvailableResponseMessage(String offerId, boolean isOfferOpen) {
|
public ReportOfferAvailabilityMessage(String offerId, boolean isOfferOpen) {
|
||||||
this.offerId = offerId;
|
this.offerId = offerId;
|
||||||
this.isOfferOpen = isOfferOpen;
|
this.isOfferOpen = isOfferOpen;
|
||||||
}
|
}
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.trade.protocol.trade.taker.messages;
|
package io.bitsquare.trade.protocol.offer.messages;
|
||||||
|
|
||||||
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.offer.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.network.Peer;
|
||||||
|
import io.bitsquare.trade.listeners.GetPeerAddressListener;
|
||||||
|
import io.bitsquare.trade.protocol.offer.CheckOfferAvailabilityModel;
|
||||||
|
import io.bitsquare.util.tasks.Task;
|
||||||
|
import io.bitsquare.util.tasks.TaskRunner;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class GetPeerAddress extends Task<CheckOfferAvailabilityModel> {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(GetPeerAddress.class);
|
||||||
|
|
||||||
|
public GetPeerAddress(TaskRunner taskHandler, CheckOfferAvailabilityModel model) {
|
||||||
|
super(taskHandler, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void run() {
|
||||||
|
model.getTradeMessageService().getPeerAddress(model.getOffer().getMessagePublicKey(), new GetPeerAddressListener() {
|
||||||
|
@Override
|
||||||
|
public void onResult(Peer peer) {
|
||||||
|
log.trace("Found peer: " + peer.toString());
|
||||||
|
|
||||||
|
model.setPeer(peer);
|
||||||
|
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailed() {
|
||||||
|
failed("DHT lookup for peer address failed.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,36 +15,37 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
package io.bitsquare.trade.protocol.offer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.network.Peer;
|
|
||||||
import io.bitsquare.trade.TradeMessageService;
|
|
||||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.messages.RequestIsOfferAvailableMessage;
|
import io.bitsquare.trade.protocol.offer.CheckOfferAvailabilityModel;
|
||||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
import io.bitsquare.trade.protocol.offer.messages.RequestIsOfferAvailableMessage;
|
||||||
|
import io.bitsquare.util.tasks.Task;
|
||||||
|
import io.bitsquare.util.tasks.TaskRunner;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class RequestIsOfferAvailable {
|
public class RequestIsOfferAvailable extends Task<CheckOfferAvailabilityModel> {
|
||||||
private static final Logger log = LoggerFactory.getLogger(RequestIsOfferAvailable.class);
|
private static final Logger log = LoggerFactory.getLogger(RequestIsOfferAvailable.class);
|
||||||
|
|
||||||
public static void run(ErrorMessageHandler errorMessageHandler,
|
public RequestIsOfferAvailable(TaskRunner taskHandler, CheckOfferAvailabilityModel model) {
|
||||||
Peer peer, TradeMessageService tradeMessageService, String offerId) {
|
super(taskHandler, model);
|
||||||
log.trace("Run RequestIsOfferAvailable task");
|
}
|
||||||
|
|
||||||
tradeMessageService.sendMessage(peer, new RequestIsOfferAvailableMessage(offerId),
|
@Override
|
||||||
|
protected void run() {
|
||||||
|
model.getTradeMessageService().sendMessage(model.getPeer(), new RequestIsOfferAvailableMessage(model.getOffer().getId()),
|
||||||
new SendMessageListener() {
|
new SendMessageListener() {
|
||||||
@Override
|
@Override
|
||||||
public void handleResult() {
|
public void handleResult() {
|
||||||
log.trace("RequestIsOfferAvailableMessage successfully arrived at peer");
|
log.trace("RequestIsOfferAvailableMessage successfully arrived at peer");
|
||||||
// nothing to do
|
complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleFault() {
|
public void handleFault() {
|
||||||
log.error("RequestIsOfferAvailableMessage did not arrive at peer");
|
failed("Sending RequestIsOfferAvailableMessage failed.");
|
||||||
errorMessageHandler.handleErrorMessage("RequestIsOfferAvailableMessage did not arrive at peer");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Bitsquare.
|
|
||||||
*
|
|
||||||
* Bitsquare 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.
|
|
||||||
*
|
|
||||||
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
|
||||||
|
|
||||||
import io.bitsquare.network.Peer;
|
|
||||||
import io.bitsquare.trade.TradeMessageService;
|
|
||||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.messages.IsOfferAvailableResponseMessage;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class IsOfferAvailableResponse {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(IsOfferAvailableResponse.class);
|
|
||||||
|
|
||||||
public static void run(Peer peer,
|
|
||||||
TradeMessageService tradeMessageService,
|
|
||||||
String offerId,
|
|
||||||
boolean isOfferOpen) {
|
|
||||||
log.trace("Run RespondToIsOfferAvailable task");
|
|
||||||
IsOfferAvailableResponseMessage message = new IsOfferAvailableResponseMessage(offerId, isOfferOpen);
|
|
||||||
tradeMessageService.sendMessage(peer, message, new SendMessageListener() {
|
|
||||||
@Override
|
|
||||||
public void handleResult() {
|
|
||||||
log.trace("RespondToIsOfferAvailableMessage successfully arrived at peer");
|
|
||||||
// Nothing to do. Taker knows now offer available state.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleFault() {
|
|
||||||
log.error("RespondToIsOfferAvailableMessage did not arrive at peer");
|
|
||||||
// Ignore that. Taker might have gone offline
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Bitsquare.
|
|
||||||
*
|
|
||||||
* Bitsquare 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.
|
|
||||||
*
|
|
||||||
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.bitsquare.trade.protocol.trade.taker;
|
|
||||||
|
|
||||||
import io.bitsquare.network.Peer;
|
|
||||||
import io.bitsquare.offer.Offer;
|
|
||||||
import io.bitsquare.trade.TradeMessageService;
|
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.messages.IsOfferAvailableResponseMessage;
|
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.GetPeerAddress;
|
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.RequestIsOfferAvailable;
|
|
||||||
|
|
||||||
import java.security.PublicKey;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Responsible for the correct execution of the sequence of tasks, message passing to the peer and message processing
|
|
||||||
* from the peer.
|
|
||||||
* That class handles the role of the taker as the Bitcoin seller.
|
|
||||||
* It uses sub tasks to not pollute the main class too much with all the async result/fault handling.
|
|
||||||
* Any data from incoming messages as well data used to send to the peer need to be validated before further processing.
|
|
||||||
*/
|
|
||||||
public class RequestIsOfferAvailableProtocol {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(RequestIsOfferAvailableProtocol.class);
|
|
||||||
|
|
||||||
|
|
||||||
// provided data
|
|
||||||
private final Offer offer;
|
|
||||||
private final TradeMessageService tradeMessageService;
|
|
||||||
|
|
||||||
// derived
|
|
||||||
private final String offerId;
|
|
||||||
private final PublicKey offererMessagePublicKey;
|
|
||||||
|
|
||||||
// written/read by task
|
|
||||||
private Peer peer;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Constructor
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public RequestIsOfferAvailableProtocol(Offer offer,
|
|
||||||
TradeMessageService tradeMessageService) {
|
|
||||||
this.offer = offer;
|
|
||||||
this.tradeMessageService = tradeMessageService;
|
|
||||||
offerId = offer.getId();
|
|
||||||
offererMessagePublicKey = offer.getMessagePublicKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
|
||||||
getPeerAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. GetPeerAddress
|
|
||||||
// Async
|
|
||||||
// In case of an error: Don't repeat call for now, maybe in production repeat once.
|
|
||||||
private void getPeerAddress() {
|
|
||||||
log.debug("getPeerAddress called");
|
|
||||||
GetPeerAddress.run(this::onResultGetPeerAddress, this::handleErrorMessage, tradeMessageService, offererMessagePublicKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* private void onGetPeerAddressFault(String errorMessage) {
|
|
||||||
GetPeerAddress.run(this::onResultGetPeerAddress, this::handleErrorMessage, tradeMessageService, offererMessagePublicKey);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
// 2. RequestTakeOffer
|
|
||||||
// Async
|
|
||||||
// In case of an error: Don't repeat call for now, maybe in production repeat once.
|
|
||||||
public void onResultGetPeerAddress(Peer peer) {
|
|
||||||
log.debug("onResultGetPeerAddress called");
|
|
||||||
this.peer = peer;
|
|
||||||
|
|
||||||
RequestIsOfferAvailable.run(this::handleErrorMessage, peer, tradeMessageService, offerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* private void onRequestIsOfferAvailableFault(String errorMessage) {
|
|
||||||
RequestIsOfferAvailable.run(this::handleErrorMessage, peer, tradeMessageService, offerId);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// generic
|
|
||||||
private void handleErrorMessage(String errorMessage) {
|
|
||||||
offer.setState(Offer.State.OFFER_NOT_AVAILABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Incoming message from peer
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void handleIsOfferAvailableResponseMessage(IsOfferAvailableResponseMessage offerMessage) {
|
|
||||||
if (offer.getState() != Offer.State.OFFER_REMOVED) {
|
|
||||||
if (offerMessage.isOfferOpen())
|
|
||||||
offer.setState(Offer.State.OFFER_AVAILABLE);
|
|
||||||
else
|
|
||||||
offer.setState(Offer.State.OFFER_NOT_AVAILABLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -47,7 +47,6 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
||||||
|
|
||||||
|
|
||||||
public class SellerAsTakerProtocol {
|
public class SellerAsTakerProtocol {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SellerAsTakerProtocol.class);
|
private static final Logger log = LoggerFactory.getLogger(SellerAsTakerProtocol.class);
|
||||||
|
|
||||||
|
|
|
@ -18,15 +18,11 @@
|
||||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
import io.bitsquare.network.Peer;
|
import io.bitsquare.network.Peer;
|
||||||
import io.bitsquare.trade.TradeMessageService;
|
|
||||||
import io.bitsquare.trade.listeners.GetPeerAddressListener;
|
import io.bitsquare.trade.listeners.GetPeerAddressListener;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerModel;
|
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerModel;
|
||||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
|
||||||
import io.bitsquare.util.tasks.Task;
|
import io.bitsquare.util.tasks.Task;
|
||||||
import io.bitsquare.util.tasks.TaskRunner;
|
import io.bitsquare.util.tasks.TaskRunner;
|
||||||
|
|
||||||
import java.security.PublicKey;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -49,32 +45,9 @@ public class GetPeerAddress extends Task<SellerAsTakerModel> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailed() {
|
public void onFailed() {
|
||||||
failed("DHT lookup for peer address failed.", null);
|
failed("DHT lookup for peer address failed.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void run(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler,
|
|
||||||
TradeMessageService tradeMessageService, PublicKey messagePublicKey) {
|
|
||||||
log.trace("Run GetPeerAddress task");
|
|
||||||
tradeMessageService.getPeerAddress(messagePublicKey, new GetPeerAddressListener() {
|
|
||||||
@Override
|
|
||||||
public void onResult(Peer peer) {
|
|
||||||
log.trace("Received peer = " + peer.toString());
|
|
||||||
resultHandler.onResult(peer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailed() {
|
|
||||||
log.error("DHT lookup for peer address failed.");
|
|
||||||
errorMessageHandler.handleErrorMessage("DHT lookup for peer address failed.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ResultHandler {
|
|
||||||
void onResult(Peer peer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,8 @@ public class TaskRunner<T extends SharedModel> {
|
||||||
private Class<? extends Task> currentTask;
|
private Class<? extends Task> currentTask;
|
||||||
private Class<? extends Task> previousTask;
|
private Class<? extends Task> previousTask;
|
||||||
|
|
||||||
|
private boolean isCanceled;
|
||||||
|
|
||||||
public TaskRunner(T sharedModel, ResultHandler resultHandler, FaultHandler faultHandler) {
|
public TaskRunner(T sharedModel, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||||
this.sharedModel = sharedModel;
|
this.sharedModel = sharedModel;
|
||||||
this.resultHandler = resultHandler;
|
this.resultHandler = resultHandler;
|
||||||
|
@ -56,7 +58,7 @@ public class TaskRunner<T extends SharedModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void next() {
|
protected void next() {
|
||||||
if (!failed) {
|
if (!failed && !isCanceled) {
|
||||||
if (tasks.size() > 0) {
|
if (tasks.size() > 0) {
|
||||||
try {
|
try {
|
||||||
setCurrentTask(tasks.poll());
|
setCurrentTask(tasks.poll());
|
||||||
|
@ -74,6 +76,10 @@ public class TaskRunner<T extends SharedModel> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void cancel() {
|
||||||
|
isCanceled = true;
|
||||||
|
}
|
||||||
|
|
||||||
protected void setPreviousTask(Class<? extends Task> task) {
|
protected void setPreviousTask(Class<? extends Task> task) {
|
||||||
previousTask = task;
|
previousTask = task;
|
||||||
}
|
}
|
||||||
|
@ -103,4 +109,5 @@ public class TaskRunner<T extends SharedModel> {
|
||||||
failed = true;
|
failed = true;
|
||||||
faultHandler.handleFault(message, throwable);
|
faultHandler.handleFault(message, throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue