package org.akka.essentials.stm.transactor.example;
import org.akka.essentials.stm.transactor.example.msg.AccountBalance;
import org.akka.essentials.stm.transactor.example.msg.AccountCredit;
import org.akka.essentials.stm.transactor.example.msg.AccountDebit;
import scala.concurrent.stm.Ref;
import scala.concurrent.stm.japi.STM;
import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.transactor.Coordinated;
public class AccountActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
String accountNumber;
//Use the scala STM Ref for state variables that need to
//participate in transactions
Ref.View<Float> balance = STM.newRef(Float.parseFloat("0"));
public AccountActor(String accNo, Float bal) {
this.accountNumber = accNo;
balance.set(bal);
}
@Override
public void onReceive(Object o) throws Exception {
if (o instanceof Coordinated) {
Coordinated coordinated = (Coordinated) o;
final Object message = coordinated.getMessage();
if (message instanceof AccountDebit) {
coordinated.atomic(new Runnable() {
public void run() {
AccountDebit accDebit = (AccountDebit) message;
//check for funds availability
if (balance.get() > accDebit.getAmount()) {
float bal = balance.get() - accDebit.getAmount();
balance.set(bal);
} else {
throw new IllegalStateException(
"Insufficient Balance");
}
}
});
} else if (message instanceof AccountCredit) {
coordinated.atomic(new Runnable() {
public void run() {
AccountCredit accCredit = (AccountCredit) message;
float bal = balance.get() + accCredit.getAmount();
balance.set(bal);
}
});
}
} else if (o instanceof AccountBalance) {
// reply with the account balance
sender().tell(new AccountBalance(accountNumber, balance.get()));
} else
unhandled(o);
}
}