消息
我們在前面僅僅討論了ActorRef的QuoteRequest,並沒有看到message的類!這裏將介紹,代碼如下:
package me.rerun.akkanotes.messaging.protocols object TeacherProtocol{ case class QuoteRequest() case class QuoteResponse(quoteString:String) }
正如你說知,QuoteRequest是用來給TeacherActor發送消息的;而Actor將會用QuoteResponse來響應。
DISPATCHER AND A MAILBOX
ActorRef取出消息並放到Dispatcher中。在這種模式下,當我們創建了ActorSystem 和ActorRef,Dispatcher和MailBox也將會創建。讓我們來看看這到底是什麼:
如果想及時瞭解Spark、Hadoop或者Hbase相關的文章,歡迎關注微信公共帳號:iteblog_hadoop
1、MailBox
每個Actor都有一個MailBox(後面我們將看到一個特殊情況)。在我們之前的模型中,每個Teacher也有一個MailBox。Teacher需要檢查MailBox並處理其中的message。MailBox中有個隊列並以FIFO方式儲存和處理消息。
2、Dispatcher
Dispatcher做一些很有趣的事。從圖中可以看到,Dispatcher好像只是僅僅將message從ActorRef 傳遞到MailBox中。但是在這背後有件很奇怪的事:Dispatcher 包裝了一個 ExecutorService (ForkJoinPool 或者 ThreadPoolExecutor).它通過ExecutorService運行 MailBox。代碼片段如下:
protected[akka] override def registerForExecution(mbox: Mailbox, ...): Boolean = { ... try { executorService execute mbox ... }
什麼?你說是你來運行Mailbox?是的,我們前面已經看到Mailbox的隊列中持有所有的消息。用executorService 運行Mailbox也一樣。Mailbox必須是一個線程。代碼中有大量的Mailbox的聲明和構造函數,代碼片段如下:
private[akka] abstract class Mailbox(val messageQueue: MessageQueue) extends SystemMessageQueue with Runnable
Teacher Actor
當MailBox的run方法被運行,它將從隊列中取出消息,並傳遞到Actor進行處理。該方法最終在你將消息tell到ActorRef 中的時候被調用,在目標Actor其實是個receive 方法。TeacherActor 是基本的類,並且擁有一系列的quote,很明顯,receive 方法是用來處理消息的。代碼片段如下:
package me.rerun.akkanotes.messaging.actormsg1 import scala.util.Random import akka.actor.Actor import me.rerun.akkanotes.messaging.protocols.TeacherProtocol._ /* * Your Teacher Actor class. * * The class could use refinement by way of * using ActorLogging which uses the EventBus of the Actor framework * instead of the plain old System out * */ class TeacherActor extends Actor { val quotes = List( "Moderation is for cowards", "Anything worth doing is worth overdoing", "The trouble is you think you have time", "You never gonna know if you never even try") def receive = { case QuoteRequest => { import util.Random //Get a random Quote <span id="0_nwp" style="width: auto; height: auto; float: none;"><a id="0_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Eiteblog%2Ecom%2Farchives%2F1157&p=baidu&c=news&n=10&t=tpclicked3_hc&q=56075110_cpr&k=from&k0=%BA%AF%CA%FD&kdi0=8&k1=from&kdi1=8&k2=%C9%F9%C3%F7&kdi2=8&sid=3e015b27b737017d&ch=0&tu=u1887734&jk=a4fb3426f22ead16&cf=29&fv=16&stid=9&urlid=0&luki=2&seller_id=1&di=128" target="_blank" mpid="0" style="text-decoration: none;"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">from</span></a></span> the list and construct a response val quoteResponse=QuoteResponse(quotes(Random.nextInt(quotes.size))) println (quoteResponse) } } }
TeacherActor的receive只匹配一種消息:QuoteRequest ,receive方法主要做以下幾件事:
1、匹配QuoteRequest;
2、從quotes中隨機取出一個quote;
3、構造一個QuoteResponse;
4、在控制檯打印QuoteResponse