Mercurial > hg > Members > anatofuz > slides
comparison slides/20180130/slide.md @ 15:80767afba59c
auto-Update generated slides by script
author | Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 30 Jan 2018 19:09:40 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
14:deecd8254ba8 | 15:80767afba59c |
---|---|
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) |