Remove offer on close app

This commit is contained in:
Manfred Karrer 2015-03-26 17:05:35 +01:00
parent 2f911101ba
commit 689d60b854
10 changed files with 100 additions and 26 deletions

View File

@ -17,22 +17,24 @@
package io.bitsquare;
import com.google.common.collect.Sets;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import static com.google.common.base.Preconditions.checkNotNull;
public abstract class BitsquareModule extends AbstractModule {
private static final Logger log = LoggerFactory.getLogger(BitsquareModule.class);
protected final Environment env;
private final Set<BitsquareModule> modules = Sets.newHashSet();
private final List<BitsquareModule> modules = new ArrayList();
protected BitsquareModule(Environment env) {
checkNotNull(env, "Environment must not be null");
@ -41,6 +43,7 @@ public abstract class BitsquareModule extends AbstractModule {
protected void install(BitsquareModule module) {
super.install(module);
log.trace("install " + module.getClass().getSimpleName());
modules.add(module);
}
@ -65,5 +68,6 @@ public abstract class BitsquareModule extends AbstractModule {
* @param injector the Injector originally initialized with this module
*/
protected void doClose(Injector injector) {
log.trace("doClose " + getClass().getSimpleName());
}
}

View File

@ -40,11 +40,15 @@ import java.io.File;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import static com.google.inject.name.Names.named;
class BitsquareAppModule extends BitsquareModule {
private static final Logger log = LoggerFactory.getLogger(BitsquareAppModule.class);
private final Stage primaryStage;
@ -65,44 +69,46 @@ class BitsquareAppModule extends BitsquareModule {
bind(Environment.class).toInstance(env);
bind(UpdateProcess.class).in(Singleton.class);
install(networkModule());
install(bitcoinModule());
// ordering is used for shut down sequence
install(tradeModule());
install(cryptoModule());
install(tradeMessageModule());
install(arbitratorModule());
install(offerModule());
install(arbitratorMessageModule());
install(p2pModule());
install(bitcoinModule());
install(guiModule());
}
protected ArbitratorModule arbitratorMessageModule() {
return new TomP2PArbitratorModule(env);
}
protected P2PModule networkModule() {
return new TomP2PModule(env);
}
protected BitcoinModule bitcoinModule() {
return new BitcoinModule(env);
protected TradeModule tradeModule() {
return new TradeModule(env);
}
protected CryptoModule cryptoModule() {
return new CryptoModule(env);
}
protected TradeModule tradeMessageModule() {
return new TradeModule(env);
protected ArbitratorModule arbitratorModule() {
return new TomP2PArbitratorModule(env);
}
protected OfferModule offerModule() {
return new TomP2POfferModule(env);
}
protected P2PModule p2pModule() {
return new TomP2PModule(env);
}
protected BitcoinModule bitcoinModule() {
return new BitcoinModule(env);
}
protected GuiModule guiModule() {
return new GuiModule(env, primaryStage);
}
@Override
protected void doClose(Injector injector) {
log.trace("doClose " + getClass().getSimpleName());
}
}

View File

@ -24,12 +24,15 @@ import com.google.inject.Singleton;
import java.io.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import static com.google.inject.name.Names.named;
public class BitcoinModule extends BitsquareModule {
private static final Logger log = LoggerFactory.getLogger(BitcoinModule.class);
public BitcoinModule(Environment env) {
super(env);
@ -56,6 +59,7 @@ public class BitcoinModule extends BitsquareModule {
@Override
protected void doClose(Injector injector) {
log.trace("doClose "+getClass().getSimpleName());
injector.getInstance(WalletService.class).shutDown();
}
}

View File

@ -279,7 +279,6 @@ public class Offer implements Serializable {
", fiatPrice=" + fiatPrice +
", amount=" + amount +
", minAmount=" + minAmount +
", p2pSigPubKey=" + p2pSigPubKey +
", fiatAccountType=" + fiatAccountType +
", bankAccountCountry=" + bankAccountCountry +
", securityDeposit=" + securityDeposit +

View File

@ -33,6 +33,8 @@ public interface OfferBookService extends DHTService {
void removeOffer(Offer offer, ResultHandler resultHandler, FaultHandler faultHandler);
void removeOfferAtShutDown(Offer offer);
void addListener(Listener listener);
void removeListener(Listener listener);

View File

@ -157,6 +157,23 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo
}
}
public void removeOfferAtShutDown(Offer offer) {
log.debug("removeOfferAtShutDown " + offer);
Number160 locationKey = Number160.createHash(offer.getCurrencyCode());
try {
final Data offerData = new Data(offer);
log.trace("Remove offer from DHT requested. Removed data: [locationKey: " + locationKey +
", hash: " + offerData.hash().toString() + "]");
FutureRemove futureRemove = removeProtectedDataFromMap(locationKey, offerData);
writeInvalidationTimestampToDHT(offer.getCurrencyCode());
futureRemove.awaitUninterruptibly(1000);
log.trace("isRemoved? " + futureRemove.isRemoved());
} catch (IOException e) {
e.printStackTrace();
log.error("Remove offer from DHT failed. Error: " + e.getMessage());
}
}
public void getOffers(String currencyCode) {
Number160 locationKey = Number160.createHash(currencyCode);
log.trace("Get offers from DHT requested for locationKey: " + locationKey);

View File

@ -29,11 +29,15 @@ import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.name.Names;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import static io.bitsquare.p2p.tomp2p.BootstrappedPeerBuilder.*;
public class TomP2PModule extends P2PModule {
private static final Logger log = LoggerFactory.getLogger(TomP2PModule.class);
public static final String BOOTSTRAP_NODE_NAME_KEY = "bootstrap.node.name";
public static final String BOOTSTRAP_NODE_IP_KEY = "bootstrap.node.ip";
public static final String BOOTSTRAP_NODE_PORT_KEY = "bootstrap.node.port";
@ -71,6 +75,7 @@ public class TomP2PModule extends P2PModule {
@Override
protected void doClose(Injector injector) {
log.trace("doClose " + getClass().getSimpleName());
// First shut down AddressService to remove address from DHT
injector.getInstance(AddressService.class).shutDown();
injector.getInstance(BootstrappedPeerBuilder.class).shutDown();

View File

@ -197,10 +197,10 @@ public class FileManager<T> {
* Shut down auto-saving.
*/
public void shutdown() {
if (serializable != null)
/* if (serializable != null)
log.debug("shutDown " + serializable.getClass().getSimpleName());
else
log.debug("shutDown");
log.debug("shutDown");*/
executor.shutdown();
try {

View File

@ -95,6 +95,7 @@ public class TradeManager {
private final TradeList<OffererTrade> openOfferTrades;
private final TradeList<Trade> pendingTrades;
private final TradeList<Trade> closedTrades;
private boolean shutDownRequested;
///////////////////////////////////////////////////////////////////////////////////////////
@ -122,6 +123,10 @@ public class TradeManager {
this.openOfferTrades = new TradeList<>(storageDir, "OpenOfferTrades");
this.pendingTrades = new TradeList<>(storageDir, "PendingTrades");
this.closedTrades = new TradeList<>(storageDir, "ClosedTrades");
// In case the app did get killed the shutDown from the modules is not called, so we use a shutdown hook
Thread shutDownHookThread = new Thread(TradeManager.this::shutDown, "TradeManager:ShutDownHook");
Runtime.getRuntime().addShutdownHook(shutDownHookThread);
}
@ -129,10 +134,30 @@ public class TradeManager {
// Public API
///////////////////////////////////////////////////////////////////////////////////////////
public void shutDown() {
if (!shutDownRequested) {
log.debug("shutDown");
shutDownRequested = true;
// we remove own offers form offerbook when we go offline
for (OffererTrade offererTrade : openOfferTrades) {
Offer offer = offererTrade.getOffer();
offerBookService.removeOfferAtShutDown(offer);
}
}
}
// When all services are initialized we create the protocols for our open offers and persisted not completed pendingTrades
// OffererAsBuyerProtocol listens for take offer requests, so we need to instantiate it early.
public void onAllServicesInitialized() {
for (OffererTrade offererTrade : openOfferTrades) {
Offer offer = offererTrade.getOffer();
// we add own offers to offerbook when we go online again
offerBookService.addOffer(offer,
() -> log.debug("Successful removed open offer from DHT"),
(message, throwable) -> log.error("Remove open offer from DHT failed. " + message));
OffererAsBuyerProtocol protocol = createOffererAsBuyerProtocol(offererTrade);
offererTrade.setProtocol(protocol);
}
@ -310,7 +335,7 @@ public class TradeManager {
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// Called from Offerbook when offer gets removed from DHT
///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -19,11 +19,16 @@ package io.bitsquare.trade;
import io.bitsquare.BitsquareModule;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
public class TradeModule extends BitsquareModule {
private static final Logger log = LoggerFactory.getLogger(TradeModule.class);
public TradeModule(Environment env) {
super(env);
@ -33,4 +38,11 @@ public class TradeModule extends BitsquareModule {
protected void configure() {
bind(TradeManager.class).in(Singleton.class);
}
@Override
protected void doClose(Injector injector) {
log.trace("doClose " + getClass().getSimpleName());
// First shut down AddressService to remove address from DHT
injector.getInstance(TradeManager.class).shutDown();
}
}