Created
March 12, 2013 14:01
-
-
Save lshoo/5143097 to your computer and use it in GitHub Desktop.
经过内部actor后为什么收到反馈信息?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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