2016-10-21 5 views
0

私はAkkaなしのActorを実装する私の小さな研究を行っています ScalaでActorの実装が1つ見つかりました。 (How to implement actor model without Akka?ScalaでAkkaのないActorモデルを実装する

非常に簡単です。コメントを追加するには十分な評判がないので、この質問を作成します。 私は以下のようにActorを使用しているのだろうかと思います。

1 /メインスレッドからそのアクタをシャットダウンするにはどうすればよいですか?

2 /どのように親アクターのようにAkkaに類似した機能を追加して、リクエストを強制終了してメソッドにすることができますか?

import scala.concurrent._ 

trait Actor[T] { 
     implicit val context = ExecutionContext.fromExecutor(java.util.concurrent.Executors.newFixedThreadPool(1)) 
     def receive: T => Unit 
     def !(m: T) = Future { receive(m) } 
} 

これは

import scala.concurrent._ 

/** 
    * Created by hminle on 10/21/2016. 
    */ 
trait Message 
case class HelloMessage(hello: String) extends Message 
case class GoodByeMessage(goodBye: String) extends Message 

object State extends Enumeration { 
    type State = Value 
    val Waiting, Running, Terminating = Value 
} 

trait Actor[T] { 
    implicit val context = ExecutionContext.fromExecutor(java.util.concurrent.Executors.newFixedThreadPool(1)) 
    private var state: State.State = State.Waiting 
    def handleMessage: T => Unit ={ 
    if(state == State.Waiting) handleMessageWhenWaiting 
    else if(state == State.Running) handleMessageWhenRunning 
    else handleMessageWhenTerminating 
    } 
    def !(m: T) = Future {handleMessage(m)} 
    def handleMessageWhenWaiting: T => Unit 
    def handleMessageWhenRunning: T => Unit 
    def handleMessageWhenTerminating: T => Unit 
    def transitionTo(destinationState: State.State): Unit = { 
    this.state = destinationState 
    } 
} 

class Component1 extends Actor[Message]{ 
    def handleMessageWhenRunning = { 
    case HelloMessage(hello) => { 
     println(Thread.currentThread().getName + hello) 
    } 
    case GoodByeMessage(goodBye) => { 
     println(Thread.currentThread().getName + goodBye) 
     transitionTo(State.Terminating) 
    } 
    } 

    def handleMessageWhenWaiting = { 
    case m => { 
     println(Thread.currentThread().getName + " I am waiting, I am not ready to run") 
     transitionTo(State.Running) 
    } 
    } 

    def handleMessageWhenTerminating = { 
    case m => { 
     println(Thread.currentThread().getName + " I am terminating, I cannot handle any message") 
     //need to shutdown here 
    } 
    } 

} 
class Component2(component1: Actor[Message]) extends Actor[Message]{ 
    def handleMessageWhenRunning = { 
    case HelloMessage(hello) => { 
     println(Thread.currentThread().getName + hello) 
     component1 ! HelloMessage("hello 1") 
    } 
    case GoodByeMessage(goodBye) => { 
     println(Thread.currentThread().getName + goodBye) 
     component1 ! GoodByeMessage("goodbye 1") 
     transitionTo(State.Terminating) 
    } 
    } 

    def handleMessageWhenWaiting = { 
    case m => { 
     println(Thread.currentThread().getName + " I am waiting, I am not ready to run") 
     transitionTo(State.Running) 
    } 
    } 

    def handleMessageWhenTerminating = { 
    case m => { 
     println(Thread.currentThread().getName + " I am terminating, I cannot handle any message") 
     //need to shutdown here 
    } 
    } 
} 
object ActorExample extends App { 
    val a = new Component1 
    val b = new Component2(a) 
    b ! HelloMessage("hello World 2") 
    b ! HelloMessage("hello World 2, 2nd") 
    b ! GoodByeMessage("Good bye 2") 
    println(Thread.currentThread().getName) 
} 

答えて

0

あなたはscalazActor model実装を見て、そこからアイデアを取ることができます上記のコードに適応しようとしている私自身の例で、scalaz actorでのソースコードは、より洞察力のために簡単ですakka。あなたはアーキテクチャに関する選択の自由を持っています:あなたはAkkaのようなConcurrentLinkedQueueに基づいてメールボックスを使用でき、あなたの場合は将来のメカニズムを使用してscalazのようにAtomicReffernceのCASを使用できます。 IMO、あなたはそれがActorContextの変種だあなたの役者システムのコンテキストを書くので、あなたの問題の第一及び第二の項目を解決する必要があります。

val contextStack = new ThreadLocal[List[ActorContext]] 

とシャットダウンは次のようになります。

1.

case Kill      ⇒ throw new ActorKilledException("Kill") 
case PoisonPill     ⇒ self.stop() 

2.親俳優と同様の作業を保存するためには、それらに参照を格納する必要があります。

def parent: ActorRef 

すべての技術(CAS、メールボックス)の利点について言い表すのは難しいです。

関連する問題