いいものをつくろう

CTOの日記

parallel programming

Actorとは?をakka quickstartの例題から学ぶ

投稿日:

早速ですが、

abstract class ActorRef {

  def ! (msg: Any)(implicit sender: ActorRef = Actor.noSender): Unit
  def tell(msg: Any, sender: ActorRef) = this.!(msg)(sender) 
}

むむ

ここの解釈が、どうも混乱する。sender は送り主なのに tellでメッセージを送られているように見えるし。。

akkaのソースをみることにする

 

まずはgetting startedからHelloWorldサンプルをダンロードし

中身をみるところから。動画のないようはだいぶ割愛されたスニペットなので。

重要なことの切り出し

① アクターは、メッセージを必ず一個ずつ処理するので、スレッド同士の競合はない。

Note how this Actor manages the counter by changing the behavior for each Greeted reply rather than using any variables. No concurrency guards such as synchronized or AtomicInteger are needed since an actor instance processes one message at a time.

https://developer.lightbend.com/guides/akka-quickstart-scala/define-actors.html

② アクターはspawnでしか生成されずに、アクター自身ではなく、その参照が返される。参照という間接性が、分散システムにおいては大いに功を奏す。

The power of location transparency

In Akka you can’t create an instance of an Actor using the new keyword. Instead, you create Actor instances using a factory spawn methods. Spawn does not return an actor instance, but a reference, akka.actor.typed.ActorRef, that points to the actor instance. This level of indirection adds a lot of power and flexibility in a distributed system.  https://developer.lightbend.com/guides/akka-quickstart-scala/create-actors.html

つまりはActorRefというのが、同一マシンの1プロセスだろうが、リモートノードだろうが抽象化してくている

ということが嬉しいのです

また必要によってはtopology(どうのようにActorが配置されているか)を動的に変更したり、できるようです。そがゆえに、だめなactorはクラッシュさせても、自動的に回復するような、そんなこともできるそうです。

If needed, the runtime can optimize the system by changing an Actor’s location or the entire application topology while it is running. This enables the “let it crash” model of failure management in which the system can heal itself by crashing faulty Actors and restarting healthy ones.

いつもおもっていたActorSystemとは何ぞや?

Guardian actorとっていますが、用はほんとに最初のActorを生成するためのアクターである程度の初期化とか終了処理とかを担っているのでしょう。

The Akka ActorSystem

An ActorSystem is the intial entry point into Akka, usually only one is created per application. An ActorSystem has a name and a guardian actor. The bootstrap of your application is typically done within the guardian actor.

The Hello World guardian actor is GreeterMain.

で基本Actorはspawnで生まれるんだって。

次に

③ アクターはメッセージを受け取るまでは何もしない。Actorはイベント駆動です、というかメッセージ駆動です。

Actors are reactive and message driven. An Actor doesn’t do anything until it receives a message

④ メッセージはmailboxに投げ込まれて、終わりなので非同期である。とどのつまりmailboxとカッコよく読んでいるがmessage queueである。

 the sender puts the message in the recipient’s mailbox and is free to do other work. The Actor’s mailbox is essentially a message queue with ordering semantics.

ここでActorとスレッドはどう違うのか?という疑問が湧いた。この疑問はactorは処理をしていない間リソースを食うのか?いいえ、それはないです、という内容読んでいる時に浮かんだ

素晴らしい回答をくれているstackoverflowを見つけたので共有したい

Actorは、ひとつの非同期コミュニケーションの抽象化した概念で、スレッドで実現しようが、されまいがあまり関係ない。

wow

メッセージを受け取り、それに対する処理をするということ。メッセージは1Actorにつき1メッセージづつ処理されること。で、内部の処理としては先程mailboxはmessage queueだよ、と出てきたように、Actorを見事に図示してくれている。ということで単に、queueと、メッセージ受けたと時の処理が書かれている、だけのentity, objectである。

https://stackoverflow.com/questions/47248820/difference-in-definition-of-actors-vs-threads

そして、メッセージを処理するときに同一Threadで行うとか、thread poolから取ってくるとか

が実行されるわけです。こういうイメージ一枚あると、全然理解が違ってきます。

https://stackoverflow.com/questions/47248820/difference-in-definition-of-actors-vs-threads

 

これ!の読み方はbangとかtellとか、というらしんですが

greeterMain ! SayHello("Charles")

は、SayHelloというメッセージをgreeterMainに送る

というのが、全て理解した人の読み方なのだけど、オブジェクト指向って基本左から右へ

英語の文法のようい読めるものだから、それに反していてい、とてもとても読みづらい。

なので

greeterMainがSayHelloをqueued-upする

greeterMain ! SayHello("Charles")

と読みます。

私はqueued-upとよんだほうがideomaticだと思いますし、なれるまで

そうしたい。

 

先ほども言ったようにアクタシステムっていうのはガーディアンアクターであり、アプリケーションを bootstrap するためのアクターである。典型的にこのアクターは`Behaviors.setup`を呼び出すことで設定されます 

 

 

 

以上です

-parallel programming

Copyright© CTOの日記 , 2020 All Rights Reserved.