Scala勉強日誌 - Akka その1
Scala勉強日誌 - Actor - 成らぬは人の為さぬなりけり
大分前にActorの勉強して、続きでAkkaの勉強しようと思ってて、完全に忘れていたので、
再開したいと思います。
(仕事で必要になって、勉強したので、メモしているだけ、、、)
今日のテーマは、、、
- SBTプロジェクトを作る
- AkkaのActorを書いてみる
- ActorからActorを呼び出して、結果を受け取ってみる
- Routerを使ってみる。
yagince/akka_practice · GitHub
例によって、環境は、、、
- OS:MacOSX10.8
- Scala : 2.10.0
- sbt :0.12.2
- Akka : 2.1.0
SBTプロジェクトを作る
まずは、プロジェクトを作ります。
今回は、全部ビルド定義ファイルは全部Scalaで書きたかったので、
こんな感じで作成
project/Build.scala
import sbt._ import Keys._ object BuildSettings { val buildOrganization = "yagince" val buildVersion = "0.0.1" val buildScalaVersion = "2.10.0" val buildSettings = Defaults.defaultSettings ++ Seq ( organization := buildOrganization, version := buildVersion, scalaVersion := buildScalaVersion ) } object Resolvers { val typeSafe = "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/" val otherResolvers = Seq(typeSafe) } object Dependencies { val akkaCore = "com.typesafe.akka" %% "akka-actor" % "2.1.0" } object AkkaPracticeBuild extends Build { import Resolvers._ import Dependencies._ import BuildSettings._ val dependencies = Seq ( akkaCore ) val project = Project ( "akka-practice", file("."), settings = buildSettings ++ Seq ( resolvers := otherResolvers, libraryDependencies ++= dependencies ) ) }
project/build.properties
sbt.version=0.12.2
AkkaのActorを書いてみる
では、早速書いてみます。
src/main/scala/akka/sample/AkkaExample01.scala
package akka.sample import actor.PrintActor import akka.actor.{Props, ActorSystem} object AkkaExample01 extends App { val system = ActorSystem("sample") val actor = system.actorOf(Props[PrintActor], "hoge") actor ! "HelloWorld!" system.shutdown }
package akka.sample import actor.PrintActor import akka.actor.{Props, ActorSystem} object AkkaExample01 extends App { val system = ActorSystem("sample") val actor = system.actorOf(Props[PrintActor], "hoge") actor ! "HelloWorld!" system.shutdown }
src/main/scala/akka/sample/actor/PrintActor.scala
package akka.sample.actor import akka.actor.Actor class PrintActor extends Actor { def receive = { case x => println(x) } }
実行結果
> run-main akka.sample.AkkaExample01 [info] Running akka.sample.AkkaExample01 HelloWorld! [success] Total time: 0 s, completed 2013/02/13 22:16:22
単純に渡したオブジェクトを出力するだけのアクターです。
これだけ見ても、scala標準Actorより記述量が少ないですね。
そして、シンプル!
素晴らしい。
ActorからActorを呼んで結果を受け取ってみる
Scala標準Actorの同期メソッドみたいのあるのかな??
無さそう???と思っていたら、
こんな風にするのが普通なのかな???
というわけで書いてみます。
package akka.sample import akka.actor.{ActorSystem, Actor, Props} import akka.routing.RoundRobinRouter object AkkaExample02 extends App { val system = ActorSystem("sample") val actor = system.actorOf(Props[Master]) actor ! 100 Thread.sleep(500) system.shutdown } class Master extends Actor { val actor = context.actorOf(Props[DoubleActor]) def receive = { case i:Int => actor ! i case Doubled(x) => println("received : %d".format(x)) } } class DoubleActor extends Actor { def receive = { case i:Int => sender ! Doubled(i*2) } } case class Doubled(i:Int)
senderへ結果を返して、呼び出し側のreceiveへメッセージパッシングする感じですかね?
確かに、これはシンプルで綺麗だ。
よくよく考えると、同期メソッドって必要ないんじゃなかろうか、、、
Routerを使ってみる
AkkaにはRouterという機能があるようです。
Actorのインスタンスを管理して、
Routerにメッセージ送信すると、
Actorへよしなにバランシングしながらメッセージを横流ししてくれるような感じでしょうか?
書いてみます。
package akka.sample import actor.{Doubled, DoubleActor} import akka.actor.{ActorSystem, Actor, Props} import akka.routing.RoundRobinRouter object AkkaExample02 extends App { val system = ActorSystem("sample") val actor = system.actorOf(Props[Master]) (0 to 10).foreach(actor ! _) Thread.sleep(100) system.shutdown } class Master extends Actor { val router = context.actorOf(Props[DoubleActor].withRouter(RoundRobinRouter(2))) def receive = { case i:Int => router ! i case Doubled(x) => println("received : %d".format(x)) } }
> run-main akka.sample.AkkaExample02 [info] Running akka.sample.AkkaExample02 received : 0 received : 2 received : 6 received : 10 received : 4 received : 14 received : 8 received : 18 received : 12 received : 16 received : 20 [success] Total time: 0 s, completed 2013/02/13 22:27:41
一個前の例のMasterクラスを書き換えて、
DoubleActorをRouterで管理するようにしてみました。
Routerの種類は
- akka.routing.RoundRobinRouter
- akka.routing.RandomRouter
- akka.routing.SmallestMailboxRouter
- akka.routing.BroadcastRouter
- akka.routing.ScatterGatherFirstCompletedRouter
- akka.routing.ConsistentHashingRouter
Routing (Scala) — Akka Documentation
これだけあるようです。
それぞれの違いは、また次回ということで、、、
さて、今日はここまでにします。