Skip to content

Instantly share code, notes, and snippets.

@lshoo
Created March 12, 2013 14:01
Show Gist options
  • Save lshoo/5143097 to your computer and use it in GitHub Desktop.
Save lshoo/5143097 to your computer and use it in GitHub Desktop.
经过内部actor后为什么收到反馈信息?
package programmingscala.Chapter09.jaxmagazine09
import concurrent.{Promise, ExecutionContext}
import scala.concurrent.duration._
import akka.actor._
import akka.pattern.ask
import akka.util.Timeout
import java.util.concurrent.TimeoutException
case class GetCustomerAccountBalances(id: Long)
// AccountBalances
case class AccountBalances(
val checking: Option[List[(Long, BigDecimal)]],
val saving: Option[List[(Long, BigDecimal)]],
val moneyMarket: Option[List[(Long, BigDecimal)]]
)
case class CheckingAccountBalances(
val balances: Option[List[(Long, BigDecimal)]]
)
case class SavingAccountBalances(
val balances: Option[List[(Long, BigDecimal)]]
)
case class MoneyMarketAccountBalances(
val balances: Option[List[(Long, BigDecimal)]]
)
// AccountProxies
class SavingAccountProxy extends Actor {
def receive = {
case GetCustomerAccountBalances(id: Long) =>
sender ! SavingAccountBalances(Some(List((1, 150000), (2, 29000))))
}
}
class CheckingAccountProxy extends Actor {
def receive = {
case GetCustomerAccountBalances(id: Long) =>
sender ! CheckingAccountBalances(Some(List((3, 15000))))
}
}
class MoneyMarketAccountProxy extends Actor {
def receive = {
case GetCustomerAccountBalances(id: Long) =>
sender ! MoneyMarketAccountBalances(Some(List((1, 300000))))
}
}
// Account Retriever
// Account Retriever version 2, 3
class AccountBalanceRetrieverModified(
savingsAccounts: ActorRef,
checkingAccounts: ActorRef,
moneyMarketAccounts: ActorRef
) extends Actor {
override def preStart() {
println("AccountBalanceRetrieverFinal started")
}
def receive = {
case GetCustomerAccountBalances(id) => {
println("Received a GetCustomerAccountBalance event: " + id)
val originalSender = sender
implicit val ec: ExecutionContext = context.dispatcher
context.actorOf(Props(new Actor() {
val promisedResult = Promise[AccountBalances]()
var checkingBalances, savingsBalances, mmBalances: Option[List[(Long, BigDecimal)]] = None
def receive = {
case CheckingAccountBalances(balances) => {
checkingBalances = balances
collectBalances
}
case SavingAccountBalances(balances) => {
savingsBalances = balances
collectBalances
}
case MoneyMarketAccountBalances(balances) => {
mmBalances = balances
collectBalances
}
}
def collectBalances = (checkingBalances, savingsBalances, mmBalances) match {
case (Some(c), Some(s), Some(m)) => {
if (promisedResult.trySuccess(AccountBalances(checkingBalances, savingsBalances, mmBalances))) {
originalSender ! promisedResult.future
println("CheckingBalance: " + c + ", savingsBalance: " + s + ", mmBalance: " + m)
context.stop(self)
}
}
case _ =>
}
savingsAccounts ! GetCustomerAccountBalances(id)
checkingAccounts ! GetCustomerAccountBalances(id)
moneyMarketAccounts ! GetCustomerAccountBalances(id)
context.system.scheduler.scheduleOnce(250 milliseconds) {
if (promisedResult.tryFailure(new TimeoutException()))
originalSender ! promisedResult.future
}
}))
}
}
}
class AccountBalancesReceiver(retriever: ActorRef) extends Actor {
def receive = {
case AccountBalances(checking, saving, moneyMarket) => {
println("Last AccountBalances: checking is " + checking.getOrElse(None) + " saving is " + saving.getOrElse(None) +
" moneyMarket is " + moneyMarket.getOrElse(None))
}
case GetCustomerAccountBalances(id: Long) => {
retriever ! GetCustomerAccountBalances(id)
}
}
}
object AccountBalancesApp extends App {
val system = ActorSystem("AccountBalancesSystem")
val checking = system.actorOf(Props[CheckingAccountProxy], name = "Checking")
val savings = system.actorOf(Props[SavingAccountProxy], name = "Savings")
val moneyMarket = system.actorOf(Props[MoneyMarketAccountProxy], name = "MoneyMarket")
val retriever = system.actorOf(Props(new AccountBalanceRetrieverModified(checking, savings, moneyMarket)), name = "AccountRetriever")
val receiver = system.actorOf(Props(new AccountBalancesReceiver(retriever)), name = "AccountReceiver")
receiver ! GetCustomerAccountBalances(1L) // Why can't receive the message for retriever?
receiver ! AccountBalances(Some(List((1, 20000))), Some(List((2, 30000))), Some(List((1, 900)))) // This is all right.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment