// BankAccount.scala package week52 import akka.actor.Actor import akka.event.LoggingReceive object BankAccount { case class Deposit(amount: BigInt) { require(amount > 0) } case class Withdraw(amount: BigInt) { require(amount > 0) } case object Done case object Failed } class BankAccount extends Actor { import BankAccount._ var balance = BigInt(0) def receive = LoggingReceive { case Deposit(amount) => balance += amount sender ! Done case Withdraw(amount) if amount <= balance => balance -= amount sender ! Done case _ => sender ! Failed } }
// WireTransfer.scala package week52 import akka.actor.Actor import akka.actor.ActorRef import akka.event.LoggingReceive object WireTransfer { case class Transfer(from: ActorRef, to: ActorRef, amount: BigInt) case object Done case object Failed } class WireTransfer extends Actor { import WireTransfer._ def receive = LoggingReceive { case Transfer(from, to, amount) => from ! BankAccount.Withdraw(amount) context.become(awaitFrom(to, amount, sender)) } def awaitFrom(to: ActorRef, amount: BigInt, customer: ActorRef): Receive = LoggingReceive { case BankAccount.Done => to ! BankAccount.Deposit(amount) context.become(awaitTo(customer)) case BankAccount.Failed => customer ! Failed context.stop(self) } def awaitTo(customer: ActorRef): Receive = LoggingReceive { case BankAccount.Done => customer ! Done context.stop(self) } }
// TransferMain.scala package week52 import akka.actor.Actor import akka.actor.Props import akka.event.LoggingReceive class TransferMain extends Actor { val accountA = context.actorOf(Props[BankAccount], "accountA") val accountB = context.actorOf(Props[BankAccount], "accountB") accountA ! BankAccount.Deposit(100) def receive = LoggingReceive { case BankAccount.Done => transfer(150) } def transfer(amount: BigInt): Unit = { val transaction = context.actorOf(Props[WireTransfer], "transfer") transaction ! WireTransfer.Transfer(accountA, accountB, amount) context.become(LoggingReceive { case WireTransfer.Done => println("success") context.stop(self) case WireTransfer.Failed => println("failed") context.stop(self) }) } }
时间: 2024-10-25 11:41:19