Skip to content
Snippets Groups Projects
Commit 40b677aa authored by Michael Kmoch's avatar Michael Kmoch
Browse files

2PC is working fine

parent c55ebc08
No related branches found
No related tags found
1 merge request!1Kmoch lewash
Showing
with 329 additions and 341 deletions
package fucoin;
import java.io.Serializable;
import java.util.HashMap;
import akka.actor.ActorRef;
import akka.actor.UntypedActor;
public abstract class AbstractNode extends UntypedActor implements Serializable {
// Returns the akka-style address as String, which
// could be converted to an ActorRef object later
public String getAddress() {
return getAddress(getSelf());
}
public String getAddress(ActorRef self) {
return self.path().toSerializationFormatWithAddress(self.path().address());
}
// The which receives Action objects
public abstract void onReceive(Object message);
// Holds references to neighbors that were in
// contact with this wallet during runtime;
// The key corresponds to the Wallet's name
private transient HashMap<String, ActorRef> knownNeighbors = new HashMap<String, ActorRef>();
// Holds references to neighbors this wallet
// synchronizes itself to (the Wallet object);
// The key corresponds to the Wallet's name
public transient HashMap<String, ActorRef> localNeighbors = new HashMap<String, ActorRef>();
// Holds all Wallets from network participants
// which synchronize their state (Wallet object)
// with us;
// The key corresponds to the Wallet's name
public transient HashMap<String, AbstractWallet> backedUpNeighbors = new HashMap<String, AbstractWallet>();
public transient HashMap<ActorRef, Integer> amounts = new HashMap<ActorRef, Integer>();
public boolean addKnownNeighbor(String key, ActorRef value) {
if(!knownNeighbors.containsKey(key)){
knownNeighbors.put(key,value);
return true;
}
return false;
}
public HashMap<String, ActorRef> getKnownNeighbors() {
return knownNeighbors;
}
public void log(String string) {
System.out.println(getSelf().path().name()+": "+string);
}
}
\ No newline at end of file
package fucoin;
import java.io.Serializable;
import java.util.HashMap;
public abstract class AbstractWallet extends AbstractNode{
import akka.actor.ActorRef;
import akka.actor.UntypedActor;
public abstract class AbstractWallet extends UntypedActor implements Serializable {
// Used to join the network (a pre known participant/Wallet must be known)
public static class ActionJoin implements Serializable {}
// Returns some neighbors that might be used as known
// and/or local neighbors
public class ActionJoinAnswer implements Serializable {
public final HashMap<String, ActorRef> someNeighbors = new HashMap<>();
}
// Used to push the state of my/a wallet to another participant
public static class ActionStoreOrUpdate implements Serializable {
public final AbstractWallet w;
public ActionStoreOrUpdate(AbstractWallet w) {
this.w = w;
}
}
// May be used to delete a stored Wallet on another participant
public static class ActionInvalidate implements Serializable {
final String name;
public ActionInvalidate(String name) {
this.name = name;
}
}
// Used to send (positive amount) or retreive money (negative amount)
public static class ActionReceiveTransaction implements Serializable {
final public int amount;
public ActionReceiveTransaction(int amount) {
this.amount = amount;
}
}
// Used to search a Wallet by name, i.e. when we want to
// perform a transaction on it
public static class ActionSearchWalletReference implements Serializable {
final String name;
final long ttl;
public ActionSearchWalletReference(String name, long ttl) {
this.name = name;
this.ttl=ttl;
}
}
// Used to return a Wallet reference (akka-style string which can
// be transformed to an ActorRef)
public static class ActionSearchWalletReferenceAnswer implements Serializable {
final String address;
final String name;
public ActionSearchWalletReferenceAnswer(String name,String address) {
this.address = address;
this.name=name;
}
}
// Used to search a Wallet by name, i.e. the own wallet if we just
// joined the network; If a receiving participant holds the stored Wallet,
// he returns it, otherwise, he might use gossiping methods to go on
// with the search;
// Note: You should also forward the sender (the participant who actually
// searches for this Wallet, so that it can be returnd the direct way)
public static class ActionSearchMyWallet implements Serializable {
final String name;
public ActionSearchMyWallet(String name) {
this.name = name;
}
}
// Used to return a searched Wallet
public static class ActionSearchMyWalletAnswer implements Serializable {
final AbstractWallet w;
public ActionSearchMyWalletAnswer(AbstractWallet w) {
this.w = w;
}
}
// Constructor
public AbstractWallet(String name) {
this.name = name;
}
// Constructor
public AbstractWallet(String name) {
this.name = name;
}
// Returns the name of this wallet, e.g. "Lieschen Müller"
public String getName() {
return this.name;
}
// Returns the akka-style address as String, which
// could be converted to an ActorRef object later
public abstract String getAddress();
// Performs housekeeping operations, e.g. pushes
// backedUpNeighbor-entries to other neighbors
public abstract void leave();
// The which receives Action objects
public abstract void onReceive(Object message);
// Holds references to neighbors that were in
// contact with this wallet during runtime;
// The key corresponds to the Wallet's name
public transient HashMap<String, ActorRef> knownNeighbors = new HashMap<String, ActorRef>();
// Holds references to neighbors this wallet
// synchronizes itself to (the Wallet object);
// The key corresponds to the Wallet's name
public transient HashMap<String, ActorRef> localNeighbors = new HashMap<String, ActorRef>();
// Holds all Wallets from network participants
// which synchronize their state (Wallet object)
// with us;
// The key corresponds to the Wallet's name
public transient HashMap<String, AbstractWallet> backedUpNeighbors = new HashMap<String, AbstractWallet>();
// The amount this wallet currently holds
public int amount;
// The name of this wallet (does never change, no
// duplicates in network assumed)
public final String name;
// The amount this wallet currently holds
public int amount;
}
\ No newline at end of file
}
......@@ -9,10 +9,7 @@ import akka.actor.ActorSystem;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import fucoin.actions.ActionInvokeLeave;
import fucoin.actions.ActionInvokeRevive;
import fucoin.actions.ActionInvokeSentMoney;
import fucoin.actions.ActionInvokeUpdate;
import fucoin.actions.join.ServerActionJoin;
import fucoin.supervisor.SuperVisor;
......@@ -27,11 +24,15 @@ public class Main {
ActorRef superVisorActor = system.actorOf(SuperVisor.props(),"SuperVisor");
List<ActorRef> activeActors = new ArrayList<ActorRef>();
ActorRef a1 = system.actorOf(Wallet.props(null,"","Main",superVisorActor),"Main");
//ActorRef a2 = system.actorOf(Wallet.props(a1,"Main","Main2",superVisorActor),"Main2");
ActorRef a2 = system.actorOf(Wallet.props(a1,"Main","Main2",superVisorActor),"Main2");
superVisorActor.tell(new ServerActionJoin("Main"), a1);
superVisorActor.tell(new ServerActionJoin("Main2"), a2);
//a2.tell(new ActionInvokeSentMoney("Main", 200), a2);
//activeActors.add(a1);
int maxrounds = 1000;
int maxactors = 100;
/*
int maxrounds = 100;
int maxactors = 10;
for(int actor=0; actor<maxactors;actor++){
activeActors.add(system.actorOf(Wallet.props(a1,"Main","Main"+actor,superVisorActor),"Main"+actor));
}
......@@ -46,13 +47,13 @@ public class Main {
List<ActorRef> removedActors = new ArrayList<ActorRef>();
for(ActorRef actor:activeActors){
if(Math.random()<0.6){
actor.tell(new ActionInvokeSentMoney("Main"+(int)Math.floor(Math.random()*10), (int) (Math.round(Math.random()*100)-50)), actor);
actor.tell(new ActionInvokeSentMoney("Main"+(int)Math.floor(Math.random()*maxactors), (int) (Math.round(Math.random()*100))), actor);
}
if(Math.random()<0.2){
removedActors.add(actor);
int offtime = timestep+(int)(Math.random()*6)+2;
offline.get(Math.min(offtime, maxrounds)).add(actor);
offline.get(Math.min(offtime, maxrounds-1)).add(actor);
}
}
activeActors.removeAll(removedActors);
......@@ -61,8 +62,7 @@ public class Main {
activeActors.add(actorName);
}
for(ActorRef removedActor : removedActors){
removedActor.tell(new ActionInvokeLeave(), removedActor);
removedActor.tell(new ActionInvokeLeave(), removedActor);
}
Thread.sleep(1000);
......@@ -72,5 +72,6 @@ public class Main {
}
superVisorActor.tell(new ActionInvokeUpdate(), superVisorActor);
*/
}
}
package fucoin;
import java.util.Map.Entry;
import java.util.concurrent.Semaphore;
import akka.actor.ActorRef;
import akka.actor.Props;
import fucoin.actions.ActionGetAmount;
import fucoin.actions.ActionGetAmountAnswer;
import fucoin.actions.ActionInvokeLeave;
import fucoin.actions.ActionInvokeRevive;
import fucoin.actions.ActionInvokeSentMoney;
import fucoin.actions.ActionInvokeSentMoney2;
import fucoin.actions.ClientAction;
import fucoin.actions.join.ActionJoin;
import fucoin.actions.join.ActionJoinAnswer;
import fucoin.actions.join.ServerActionJoin;
import fucoin.actions.persist.ActionInvokeLeave;
import fucoin.actions.persist.ActionInvokeRevive;
import fucoin.actions.transaction.ActionGetAmountAnswer;
import fucoin.actions.transaction.ActionInvokeSentMoney;
import fucoin.gui.IWalletControle;
import fucoin.gui.IWalletGuiControle;
......@@ -28,167 +27,32 @@ public class Wallet extends AbstractWallet implements IWalletControle{
this.preknownNeighbour=preknownNeighbour;
this.remoteSuperVisorActor=remoteSuperVisorActor;
}
@Override
public String getAddress() {
return getAddress(getSelf());
}
private String getAddress(ActorRef self) {
return self.path().toSerializationFormatWithAddress(self.path().address());
}
public void send(String name, int amount){
//System.out.println("search wallet"+name+" in "+knownNeighbors.keySet());
if(knownNeighbors.containsKey(name)){
addAmount(-amount);
knownNeighbors.get(name).tell(new ActionReceiveTransaction(amount), getSelf());
}else{
for(ActorRef neighbor : knownNeighbors.values()){
neighbor.tell(new ActionSearchWalletReference(name,System.currentTimeMillis()+10), getSelf());
}
try {
getContext().unwatch(getSelf());
Thread.sleep(200);
getContext().watch(getSelf());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//getContext().unwatch(getSelf());
getSelf().tell(new ActionInvokeSentMoney(name, amount), getSelf());
}
}
private void addAmount(int amount) {
public void addAmount(int amount) {
setAmount(this.amount+amount);
log(" My amount is now "+this.amount);
if(gui!=null){
gui.setAmount(this.amount);
}
}
@Override
public void leave() {
for(ActorRef neighbor : knownNeighbors.values()){
if(getSelf().compareTo(neighbor)!=0){
neighbor.tell(new ActionStoreOrUpdate(this), getSelf());
}
}
remoteSuperVisorActor.tell(new ActionStoreOrUpdate(this), getSelf());
isActive=false;
backedUpNeighbors.clear();
knownNeighbors.clear();
knownNeighbors.put(preknownNeighbourName,preknownNeighbour);
getSelf().tell(new ActionInvokeLeave(), getSelf());
}
@Override
public void onReceive(Object message) {
log(getSender().path().name()+" invokes "+getSelf().path().name()+" to do "+message.getClass().getSimpleName());
log(message.getClass().getSimpleName());
//log(getSender().path().name()+" invokes "+getSelf().path().name()+" to do "+message.getClass().getSimpleName());
if(message instanceof ActionInvokeRevive){
isActive=true;
preknownNeighbour.tell(new ActionJoin(), getSelf());
((ActionInvokeRevive) message).doAction(this);
}
if(!isActive)return;
if(!isActive&&!(message instanceof ActionInvokeRevive))return;
//System.out.println(message);
if(message instanceof ActionJoin){
ActionJoinAnswer aja = new ActionJoinAnswer();
aja.someNeighbors.putAll(knownNeighbors);
getSender().tell(aja, getSelf());
}else if(message instanceof ActionJoinAnswer){
ActionJoinAnswer aja = (ActionJoinAnswer) message;
for(Entry<String, ActorRef> neighbor : knownNeighbors.entrySet()){
addKnownNeighbor(neighbor.getKey(),neighbor.getValue());
neighbor.getValue().tell(new ActionSearchMyWallet(name), getSelf());
}
}else if(message instanceof ActionSearchMyWallet){
ActionSearchMyWallet asmw = (ActionSearchMyWallet) message;
//If I know that somebody is searching himself,
//I can store him under the searched wallet name
addKnownNeighbor(asmw.name, getSender());
AbstractWallet storedWallet = backedUpNeighbors.get(asmw.name);
log(" "+knownNeighbors);
if(storedWallet!=null){
getSender().tell(new ActionSearchMyWalletAnswer(storedWallet), getSelf());
}
}else if(message instanceof ActionSearchMyWalletAnswer){
ActionSearchMyWalletAnswer asmwa = (ActionSearchMyWalletAnswer) message;
setAmount(asmwa.w.amount);
getSender().tell(new ActionInvalidate(name), getSelf());
}else if(message instanceof ActionInvalidate){
ActionInvalidate ai = (ActionInvalidate) message;
backedUpNeighbors.remove(ai.name);
}else if(message instanceof ActionSearchWalletReference){
ActionSearchWalletReference aswr = (ActionSearchWalletReference) message;
System.out.println("I search for you"+aswr.name);
if(this.name.equals(aswr.name)){
getSender().tell(new ActionSearchWalletReferenceAnswer(aswr.name,getAddress()),getSelf());
}else if(backedUpNeighbors.containsKey(aswr.name)){
getSender().tell(new ActionSearchWalletReferenceAnswer(aswr.name,backedUpNeighbors.get(aswr.name).getAddress()),getSelf());
} else if(knownNeighbors.containsKey(aswr.name)){
getSender().tell(new ActionSearchWalletReferenceAnswer(aswr.name,getAddress(knownNeighbors.get(aswr.name))),getSelf());
} else if (System.currentTimeMillis()<aswr.ttl){
//for(ActorRef actor : knownNeighbors.values()){
// actor.tell(aswr,getSelf());
//}
//Because Sender is maybe unknown
//getSender().tell(aswr, getSelf());
}
}else if(message instanceof ActionSearchWalletReferenceAnswer){
ActionSearchWalletReferenceAnswer aswra = (ActionSearchWalletReferenceAnswer) message;
ActorRef target = getContext().actorSelection(aswra.address).anchor();
addKnownNeighbor(aswra.name,target);
}else if(message instanceof ActionInvokeSentMoney){
ActionInvokeSentMoney aism = (ActionInvokeSentMoney) message;
send(aism.name, aism.amount);
}else if(message instanceof ActionInvokeSentMoney2){
if(knownNeighbors.containsKey(name)){
addAmount(-amount);
knownNeighbors.get(name).tell(new ActionReceiveTransaction(amount), getSelf());
}
}else if(message instanceof ActionReceiveTransaction){
ActionReceiveTransaction art = (ActionReceiveTransaction) message;
System.out.println(message.getClass().getSimpleName()+" "+art.amount);
addAmount(art.amount);
}else if(message instanceof ActionStoreOrUpdate){
ActionStoreOrUpdate asou = (ActionStoreOrUpdate) message;
backedUpNeighbors.put(asou.w.name, asou.w);
}else if(message instanceof ActionGetAmount){
ActionGetAmountAnswer agaa = new ActionGetAmountAnswer(getAddress(),getName(),amount);
getSender().tell(agaa, getSelf());
}else if(message instanceof ActionInvokeLeave){
leave();
}else if(message instanceof ActionInvokeRevive){
}else{
unhandled(message);
System.err.println("Unexpected Error: "+message+" not handeld");
}
}
private void addKnownNeighbor(String key, ActorRef value) {
if(!knownNeighbors.containsKey(key)){
System.out.println(knownNeighbors.keySet()+" does not contain "+key);
knownNeighbors.put(key,value);
if(gui!=null){
gui.addKnownAddress(key);
}
System.out.println(key+"-->"+value);
if(message instanceof ClientAction){
((ClientAction) message).doAction(this);
}
}
private void log(String string) {
System.out.println(getSelf()+": "+string);
}
@Override
......@@ -198,22 +62,23 @@ public class Wallet extends AbstractWallet implements IWalletControle{
gui.setAddress(getAddress());
}
String path = "akka.tcp://Core@127.0.0.1:1234/user/Main";
System.out.println(getContext().provider().getExternalAddressFor(getSelf().path().address()));
//System.out.println(getContext().provider().getExternalAddressFor(getSelf().path().address()));
//log("my address should be "+getAddress());
//log(""+preknownNeighbour);
//knownNeighbors.put(getName(),getSelf());
System.out.println(knownNeighbors);
//System.out.println(knownNeighbors);
if(preknownNeighbour!=null){
knownNeighbors.put(preknownNeighbourName,preknownNeighbour);
addKnownNeighbor(preknownNeighbourName,preknownNeighbour);
preknownNeighbour.tell(new ActionJoin(), getSelf());
ActionJoinAnswer aja = new ActionJoinAnswer();
aja.someNeighbors.putAll(knownNeighbors);
aja.someNeighbors.putAll(getKnownNeighbors());
aja.someNeighbors.put(name, getSelf());
preknownNeighbour.tell(aja, getSelf());
}
setAmount(100);
remoteSuperVisorActor.tell(new ActionJoin(), getSelf());
//setAmount(100);
//remoteSuperVisorActor.tell(new ServerActionJoin(name), getSelf());
}
@Override
......@@ -241,14 +106,7 @@ public class Wallet extends AbstractWallet implements IWalletControle{
this.gui=gui;
}
Semaphore mutex = new Semaphore(1);
public void setAmount(int amount){
try {
mutex.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.amount = amount;
if(remoteSuperVisorActor != null){
remoteSuperVisorActor.tell(new ActionGetAmountAnswer(getAddress(), getName(), amount), getSelf());
......@@ -256,7 +114,60 @@ public class Wallet extends AbstractWallet implements IWalletControle{
if(gui!=null){
gui.setAmount(this.amount);
}
mutex.release();
}
public ActorRef getPreknownNeighbour() {
return preknownNeighbour;
}
public ActorRef getRemoteSuperVisorActor() {
return remoteSuperVisorActor;
}
public IWalletGuiControle getGui() {
return gui;
}
public String getPreknownNeighbourName() {
return preknownNeighbourName;
}
public boolean isActive() {
return isActive;
}
@Override
public boolean addKnownNeighbor(String key, ActorRef value) {
log(key+" is newNeighbor?"+!getKnownNeighbors().containsKey(key));
if(getKnownNeighbors().containsKey(key)||key.equals(name)){
return false;
}
boolean newNeighbor = super.addKnownNeighbor(key, value);
if(gui!=null&&newNeighbor){
gui.addKnownAddress(key);
}
return newNeighbor;
}
public void setPreknownNeighbour(ActorRef preknownNeighbour) {
this.preknownNeighbour = preknownNeighbour;
}
public void setRemoteSuperVisorActor(ActorRef remoteSuperVisorActor) {
this.remoteSuperVisorActor = remoteSuperVisorActor;
}
public void setPreknownNeighbourName(String preknownNeighbourName) {
this.preknownNeighbourName = preknownNeighbourName;
}
public void setActive(boolean isActive) {
this.isActive = isActive;
}
@Override
public void send(String address, int amount) {
getSelf().tell(new ActionInvokeSentMoney(address, amount), getSelf());
}
}
......@@ -24,8 +24,8 @@ public class WalletCreator implements Creator<Wallet> {
public Wallet create() throws Exception {
Wallet wallet = new Wallet(preknownNeighbour,preknownNeighbourName, walletName,remoteSuperVisorActor);
// IWalletGuiControle gui = new WalletGui(wallet);
// wallet.setGui(gui);
IWalletGuiControle gui = new WalletGui(wallet);
wallet.setGui(gui);
return wallet;
}
......
package fucoin.actions;
import fucoin.AbstractNode;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
public abstract class Action<T extends AbstractNode> {
private ActorRef self;
public final void doAction(T abstractNode){
this.self=abstractNode.getSelf();
onAction(abstractNode.getSender(),abstractNode.getSelf(),abstractNode.getContext(),abstractNode);
}
protected abstract void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, T abstractNode);
public void log(String string) {
System.out.println(self.path().name()+": "+string);
}
}
package fucoin.actions;
public class ActionGetAmount {
}
package fucoin.actions;
public class ActionInvokeLeave {
}
package fucoin.actions;
public class ActionInvokeRevive {
}
package fucoin.actions;
import java.io.Serializable;
public class ActionInvokeSentMoney implements Serializable{
public final String name;
public final int amount;
public ActionInvokeSentMoney(String name, int amount) {
this.name=name;
this.amount = amount;
}
}
package fucoin.actions;
import java.io.Serializable;
public class ActionInvokeSentMoney2 implements Serializable{
public final String name;
public final int amount;
public ActionInvokeSentMoney2(String name, int amount) {
this.name=name;
this.amount = amount;
}
}
package fucoin.actions;
public class ActionInvokeUpdate {
}
package fucoin.actions;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
import fucoin.Wallet;
public abstract class ClientAction extends Action<Wallet>{
@Override
protected abstract void onAction(ActorRef sender, ActorRef self,
UntypedActorContext context, Wallet abstractNode);
}
package fucoin.actions.join;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
import fucoin.AbstractNode;
//Used to join the network (a pre known participant/Wallet must be known)
public class ActionJoin extends GeneralAction{
@Override
protected void onAction(ActorRef sender, ActorRef self,
UntypedActorContext context, AbstractNode node) {
ActionJoinAnswer aja = new ActionJoinAnswer();
aja.someNeighbors.putAll(node.getKnownNeighbors());
sender.tell(aja, self);
}
}
package fucoin.actions.join;
import java.util.HashMap;
import java.util.Map.Entry;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
import fucoin.Wallet;
import fucoin.actions.ClientAction;
import fucoin.actions.persist.ActionSearchMyWallet;
// Returns some neighbors that might be used as known
// and/or local neighbors
public class ActionJoinAnswer extends ClientAction{
public final HashMap<String, ActorRef> someNeighbors = new HashMap<>();
protected void onAction(ActorRef sender, ActorRef self,
UntypedActorContext context, Wallet wallet) {
log("someNeighbors:"+someNeighbors);
for(Entry<String, ActorRef> neighbor : someNeighbors.entrySet()){
wallet.addKnownNeighbor(neighbor.getKey(),neighbor.getValue());
}
for(Entry<String, ActorRef> neighbor : someNeighbors.entrySet()){
neighbor.getValue().tell(new ActionSearchMyWallet(wallet.getName()), self);
}
}
}
package fucoin.actions.join;
import fucoin.AbstractNode;
import fucoin.actions.Action;
public abstract class GeneralAction extends Action<AbstractNode> {
}
package fucoin.actions.join;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
import fucoin.AbstractNode;
import fucoin.Wallet;
import fucoin.actions.ClientAction;
public abstract class Join extends ClientAction{
}
package fucoin.actions.join;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
import fucoin.actions.transaction.ActionInvokeDistributedCommitedTransfer;
import fucoin.actions.transaction.SuperVisorAction;
import fucoin.supervisor.SuperVisor;
public class ServerActionJoin extends SuperVisorAction {
private String name;
public ServerActionJoin(String name) {
this.name = name;
}
@Override
protected void onAction(ActorRef sender, ActorRef self,
UntypedActorContext context, SuperVisor node) {
ActionJoinAnswer aja = new ActionJoinAnswer();
aja.someNeighbors.putAll(node.getKnownNeighbors());
sender.tell(aja, self);
node.addKnownNeighbor(name, sender);
self.tell(
new ActionInvokeDistributedCommitedTransfer(self, sender, 100),
sender);
}
}
package fucoin.actions.persist;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
import fucoin.AbstractNode;
import fucoin.Wallet;
// May be used to delete a stored Wallet on another participant
public class ActionInvalidate extends Persist{
public final String name;
public ActionInvalidate(String name) {
this.name = name;
}
@Override
protected void onAction(ActorRef sender, ActorRef self,
UntypedActorContext context, Wallet wallet) {
wallet.backedUpNeighbors.remove(name);
}
}
package fucoin.actions.persist;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
import fucoin.Wallet;
public class ActionInvokeLeave extends Persist{
@Override
protected void onAction(ActorRef sender, ActorRef self,
UntypedActorContext context, Wallet wallet) {
for(ActorRef neighbor : wallet.getKnownNeighbors().values()){
if(self.compareTo(neighbor)!=0){
neighbor.tell(new ActionStoreOrUpdate(wallet), self);
}
}
wallet.setActive(false);
wallet.backedUpNeighbors.clear();
wallet.getKnownNeighbors().clear();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment