comparison slides/2018/01/30/slide.md @ 28:2e1724369e51

auto-Update generated slides by script
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Mon, 16 Apr 2018 09:57:17 +0900
parents slides/2018/20180130/slide.md@c0ec001d8a28
children
comparison
equal deleted inserted replaced
27:922caa454c1a 28:2e1724369e51
1 title: 分散フレームワークakkaの調査
2 author: Takahiro Shimizu
3 profile:
4 lang: Japanese
5
6
7 # 調査目的
8 * 先輩の修論の比較材料の為に行う
9 * 分散フレームワークの1つであるakkaがどのような書き方、及び処理なのかを調査する
10
11
12 # 今週の進捗
13 * ゼミ資料良い感じに作れる便利スクリプト作ってました
14 * akkaでインクリメトを行うプログラムを書いてました
15 * コンパイラ構成論も進めてました
16
17 # akkaのインクリメント
18
19 * akkaのインスタンスはprops経由で作成する
20 * 今回は1対1の通信なのでprops内には出力用のみ用意しました
21 * `system.terminate()` しないとsystemが動いたままになってしまう
22
23 ```scala
24 package IncrementSample
25
26
27 import akka.actor.{Actor, ActorLogging, ActorRef, ActorSystem, Props, TypedActor}
28
29
30 object Incrementer {
31 def props(printerActor:ActorRef): Props = Props(new Incrementer(printerActor))
32
33 final case class SendData(data:Int)
34 final case class SetActor(actor:ActorRef)
35 }
36
37 class Incrementer(printerActor: ActorRef) extends Actor {
38 import Incrementer._
39 import Printer._
40
41
42 var otherActor = ActorRef.noSender
43 val MAX_SIZE = 10
44
45 def receive = {
46 case SendData(data) =>
47 printerActor ! Println(data.toString)
48 if (data < MAX_SIZE) {
49 val send_data = data + 1
50 otherActor ! SendData(send_data)
51 }
52 case SetActor(actor :ActorRef) =>
53 otherActor = actor
54 }
55 }
56
57 object Printer {
58 def props: Props = Props[Printer]
59
60 final case class Println(message: String)
61 }
62
63 class Printer extends Actor with ActorLogging {
64 import Printer._
65
66 def receive = {
67 case Println(message) =>
68 log.info(s"Printer received (from ${sender()} ): $message")
69 }
70 }
71
72 object IncrementSample extends App {
73
74 import Incrementer._
75
76
77 val system: ActorSystem = ActorSystem("incrementSample")
78
79 val printer: ActorRef = system.actorOf(Printer.props,"printerActor")
80
81 val actorOne: ActorRef = system.actorOf(Incrementer.props(printer),"ActorOne")
82 val actorTwo: ActorRef = system.actorOf(Incrementer.props(printer),"ActorTwo")
83
84 actorOne ! SetActor(actorTwo)
85 actorTwo ! SetActor(actorOne)
86
87 val FIRST_DATA = 1
88
89 actorOne ! SendData(FIRST_DATA)
90 system.terminate()
91 }
92
93 ```
94
95
96 # Incrementer
97
98 * ActorRefの型の初期値が不明なので `ActorRef.noSender` でごまかす
99 * 別Actorに処理を投げる際は `otherActor ! Method` な書き方をする
100 * この際に `otherActor ! receive(Method)` と書くと自分自身を呼び出してしまう
101
102 ```scala
103 object Incrementer {
104 def props(printerActor:ActorRef): Props = Props(new Incrementer(printerActor))
105
106 final case class SendData(data:Int)
107 final case class SetActor(actor:ActorRef)
108 }
109
110 class Incrementer(printerActor: ActorRef) extends Actor {
111 import Incrementer._
112 import Printer._
113
114
115 var otherActor = ActorRef.noSender
116 val MAX_SIZE = 10
117
118 def receive = {
119 case SendData(data) =>
120 printerActor ! Println(data.toString)
121 if (data < MAX_SIZE) {
122 val send_data = data + 1
123 otherActor ! SendData(send_data)
124 }
125 case SetActor(actor :ActorRef) =>
126 otherActor = actor
127 }
128 }
129 ```
130
131 # 実行結果
132
133 ```
134 /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/bin/java "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=65202:/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Users/e155730/Canossa/working/cr/akka/increment-sample/target/scala-2.12/classes:/Users/e155730/.sbt/boot/scala-2.12.4/lib/scala-library.jar:/Users/e155730/.ivy2/cache/org.scala-lang.modules/scala-java8-compat_2.12/bundles/scala-java8-compat_2.12-0.8.0.jar:/Users/e155730/.ivy2/cache/com.typesafe.akka/akka-testkit_2.12/jars/akka-testkit_2.12-2.5.3.jar:/Users/e155730/.ivy2/cache/com.typesafe.akka/akka-actor_2.12/jars/akka-actor_2.12-2.5.3.jar:/Users/e155730/.ivy2/cache/com.typesafe/config/bundles/config-1.3.1.jar IncrementSample.IncrementSample
135 [INFO] [01/29/2018 16:45:05.275] [incrementSample-akka.actor.default-dispatcher-5] [akka://incrementSample/user/printerActor] Printer received (from Actor[akka://incrementSample/user/HogeActor#-884834315] ): 3
136 [INFO] [01/29/2018 16:45:05.276] [incrementSample-akka.actor.default-dispatcher-5] [akka://incrementSample/user/printerActor] Printer received (from Actor[akka://incrementSample/user/FooActor#-1325429432] ): 2
137 [INFO] [01/29/2018 16:45:05.276] [incrementSample-akka.actor.default-dispatcher-5] [akka://incrementSample/user/printerActor] Printer received (from Actor[akka://incrementSample/user/FooActor#-1325429432] ): 4
138 [INFO] [01/29/2018 16:45:05.277] [incrementSample-akka.actor.default-dispatcher-5] [akka://incrementSample/user/printerActor] Printer received (from Actor[akka://incrementSample/user/HogeActor#-884834315] ): 5
139 [INFO] [01/29/2018 16:45:05.277] [incrementSample-akka.actor.default-dispatcher-5] [akka://incrementSample/user/printerActor] Printer received (from Actor[akka://incrementSample/user/FooActor#-1325429432] ): 6
140 [INFO] [01/29/2018 16:45:05.277] [incrementSample-akka.actor.default-dispatcher-5] [akka://incrementSample/user/printerActor] Printer received (from Actor[akka://incrementSample/user/HogeActor#-884834315] ): 7
141 [INFO] [01/29/2018 16:45:05.277] [incrementSample-akka.actor.default-dispatcher-5] [akka://incrementSample/user/printerActor] Printer received (from Actor[akka://incrementSample/user/FooActor#-1325429432] ): 8
142 [INFO] [01/29/2018 16:45:05.278] [incrementSample-akka.actor.default-dispatcher-5] [akka://incrementSample/user/printerActor] Printer received (from Actor[akka://incrementSample/user/HogeActor#-884834315] ): 9
143 [INFO] [01/29/2018 16:45:05.278] [incrementSample-akka.actor.default-dispatcher-5] [akka://incrementSample/user/printerActor] Printer received (from Actor[akka://incrementSample/user/FooActor#-1325429432] ): 10
144 [INFO] [01/29/2018 16:45:05.278] [incrementSample-akka.actor.default-dispatcher-5] [akka://incrementSample/user/printerActor] Printer received (from Actor[akka://incrementSample/user/HogeActor#-884834315] ): fin
145 ```
146
147
148 # テスト
149
150 * Akkaの提供するTestKitライブラリを主に利用する
151 * actorを管理する `system` はTestKitがラップしたものを利用する
152 * またTestKitを利用するとシングルスレッドでakkaが処理を行うようになる
153 * Scalaテストは慣例でファイル名に `Specs`を含める(Scalaのテストフレームワークに由来)
154 * 出力テストを行う場合、出力を受け取るようのアクターを `TestPropbe()` で置き換えれば可能
155
156 ```
157 val printer: ActorRef = system.actorOf(Printer.props,"printerActor")
158 ```
159
160 ```
161 val testProbe = TestProbe()
162 ```
163
164 # Actorテスト
165
166 * Actorの内部にアクセスしたい場合 `system.actorOf(Actor.props,"name)` の書き方ではなく
167 `TestActorRef()` にする
168 * TestActorでラップするとActor内部の値を参照できるらしい(出来なかった)
169
170
171
172 ```
173 val actorOne: ActorRef = system.actorOf(Incrementer.props(printer),"ActorOne")
174 val actorTwo: ActorRef = system.actorOf(Incrementer.props(printer),"ActorTwo")
175 ```
176
177 ```
178 val actorOne = TestActorRef(Incrementer.props(testProbe.ref),"ActorOne")
179 val actorTwo = TestActorRef(Incrementer.props(testProbe.ref),"ActorTwo")
180 ```
181
182 # akkaのトポロジーサポート
183
184 - 大城くんに投げてます
185 - Graphと呼ばれる構造なら出来そうな気はしますが、StackOverflowでは無理と言われていた
186
187 # akkaのデータ圧縮
188
189 * akkaのstreamの[akka.stream.scaladsl.Compression](https://doc.akka.io/docs/akka/current/stream/stream-cookbook.html?language=scala#dealing-with-compressed-data-streams)でデータ圧縮が可能
190 * scala版の[API](https://doc.akka.io/api/akka/current/akka/stream/scaladsl/Compression$.html)