comparison lib/template.md @ 10:d3d4db8a0e2c

rename
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Thu, 25 Jan 2018 17:33:51 +0900
parents 03ab44e80533
children 1b8fa3e9b962
comparison
equal deleted inserted replaced
9:80cee8f70ae8 10:d3d4db8a0e2c
6 6
7 # 調査目的 7 # 調査目的
8 * 先輩の修論の比較材料の為に行う 8 * 先輩の修論の比較材料の為に行う
9 * 分散フレームワークの1つであるakkaがどのような書き方、及び処理なのかを調査する 9 * 分散フレームワークの1つであるakkaがどのような書き方、及び処理なのかを調査する
10 10
11 # 調査内容 11 # hoge
12 * akkaのmac osx,ubuntu上の導入 12 * foo
13 * [公式チュートリアル](https://developer.lightbend.com/guides/akka-quickstart-java/)の例題を行う 13 * puyo
14 * 今回はJavaで実行した
15
16 # 環境構築
17
18 * 公式からzipファイルで提供されているので落とす
19 * 例題はGradleで実行できるように作成されているので `$ gradle run` を実行可能.
20
21 # akkaの分散処理
22
23 * akkaはアクターモデルを採用したフレームワーク
24 * アクターモデルでは「アクター」と呼ばれるオブジェクト同士がメッセージ通信を行うことで並列処理を実現する(イベント・ドリブン)
25 * publicなAPIを持っていない為,強力な分離機能を持っており、複数のJVMなどでも連携可能
26 * 環境透過性
27 * 軽量
28 * JVM上で動き、ScalaとJavaをサポートしている
29
30 # 例題(Hello,World)
31
32 * 今回は公式チュートリアルにある、複数のアクターが挨拶をするHello Worldの例題を実行する
33 * <img src="https://developer.lightbend.com/guides/akka-quickstart-java/images/hello-akka-architecture.png">
34
35 * 実行結果
36
37 ```
38 $ gradle run
39 Starting a Gradle Daemon (subsequent builds will be faster)
40
41 > Task :run
42 >>> Press ENTER to exit <<<
43 [INFO] [01/16/2018 15:33:05.871] [helloakka-akka.actor.default-dispatcher-4] [akka://helloakka/user/printerActor] Howdy, Akka
44 [INFO] [01/16/2018 15:33:05.872] [helloakka-akka.actor.default-dispatcher-4] [akka://helloakka/user/printerActor] Howdy, Lightbend
45 [INFO] [01/16/2018 15:33:05.872] [helloakka-akka.actor.default-dispatcher-4] [akka://helloakka/user/printerActor] Good day, Play
46 [INFO] [01/16/2018 15:33:05.872] [helloakka-akka.actor.default-dispatcher-4] [akka://helloakka/user/printerActor] Hello, Java
47 ```
48
49 # Hello World Actors
50
51 * 例題のActorrは3種類のmessageを利用する
52
53 * `WhoToGreet`
54 * greetingの受取用オブジェクト
55 * `Greet`
56 * greetingの実行用
57 * `Greeting`
58 * `greeting`にメッセージを含める為の命令
59
60 * 複数のスレッドで共有をする必要がある為、メッセージはimmutableでなければならない
61
62
63 # Greeter Actor
64
65 * `Greeter` のコンストラクタは、送信用メッセージと出力用のActorのリファレンスを必要とする
66 * mainの中ではGreeterは複数呼ばれている
67
68 ```
69 package com.lightbend.akka.sample;
70
71 import akka.actor.AbstractActor;
72 import akka.actor.ActorRef;
73 import akka.actor.Props;
74 import com.lightbend.akka.sample.Printer.Greeting;
75
76 public class Greeter extends AbstractActor {
77 static public Props props(String message, ActorRef printerActor) {
78 return Props.create(Greeter.class, () -> new Greeter(message, printerActor));
79 }
80
81 static public class WhoToGreet {
82 public final String who;
83
84 public WhoToGreet(String who) {
85 this.who = who;
86 }
87 }
88
89 static public class Greet {
90 public Greet() {
91 }
92 }
93
94 private final String message;
95 private final ActorRef printerActor;
96 private String greeting = "";
97
98 public Greeter(String message, ActorRef printerActor) {
99 this.message = message;
100 this.printerActor = printerActor;
101 }
102
103 @Override
104 public Receive createReceive() {
105 return receiveBuilder()
106 .match(WhoToGreet.class, wtg -> {
107 this.greeting = message + ", " + wtg.who;
108 })
109 .match(Greet.class, x -> {
110 printerActor.tell(new Greeting(greeting), getSelf());
111 })
112 .build();
113 }
114 }
115 ```
116
117 # Printer Actor
118
119 * `Logging.getLogger(getContext().getSystem(), this);` で各Actorが `log.info()` に追記していく
120 * `Greeting` とlogsに対してhandleを所持している
121
122 ```
123 package com.lightbend.akka.sample;
124
125 import akka.actor.AbstractActor;
126 import akka.actor.ActorRef;
127 import akka.actor.Props;
128 import akka.event.Logging;
129 import akka.event.LoggingAdapter;
130
131 public class Printer extends AbstractActor {
132 static public Props props() {
133 return Props.create(Printer.class, () -> new Printer());
134 }
135
136 static public class Greeting {
137 public final String message;
138
139 public Greeting(String message) {
140 this.message = message;
141 }
142 }
143
144 private LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
145
146 public Printer() {
147 }
148
149 @Override
150 public Receive createReceive() {
151 return receiveBuilder()
152 .match(Greeting.class, greeting -> {
153 log.info(greeting.message);
154 })
155 .build();
156 }
157 }
158 ```
159
160
161 # Actorを作る
162
163 * akkaはインスタンスを作る際に `new` を使わない。これはakkaのインスタンスがリファレンスである為 (`akka.actor.ActorRef`)である。
164 * その為、軽量かつ柔軟にシステムに組み込むことが可能である
165 * akkaのActorは `akka.actor.ActorSystem` が管理する。(factoryなどとも呼ばれる)
166 * 例題では次のようにakkaのインスタンスを作成している。
167
168 ```
169 public class AkkaQuickstart {
170 public static void main(String[] args) {
171 final ActorSystem system = ActorSystem.create("helloakka");
172 try {
173 //#create-actors
174 final ActorRef printerActor =
175 system.actorOf(Printer.props(), "printerActor");
176 final ActorRef howdyGreeter =
177 system.actorOf(Greeter.props("Howdy", printerActor), "howdyGreeter");
178 final ActorRef helloGreeter =
179 system.actorOf(Greeter.props("Hello", printerActor), "helloGreeter");
180 final ActorRef goodDayGreeter =
181 system.actorOf(Greeter.props("Good day", printerActor), "goodDayGreeter");
182 //#create-actors
183 ```
184
185 # メッセージ送信
186
187 * akkaのメッセージ送信は `ActorRef`の`tell`メソッドを呼ぶ。
188
189 ```
190 howdyGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender());
191 howdyGreeter.tell(new Greet(), ActorRef.noSender());
192
193 howdyGreeter.tell(new WhoToGreet("Lightbend"), ActorRef.noSender());
194 howdyGreeter.tell(new Greet(), ActorRef.noSender());
195
196 helloGreeter.tell(new WhoToGreet("Java"), ActorRef.noSender());
197 helloGreeter.tell(new Greet(), ActorRef.noSender());
198
199 goodDayGreeter.tell(new WhoToGreet("Play"), ActorRef.noSender());
200 goodDayGreeter.tell(new Greet(), ActorRef.noSender());
201 ```
202
203 * `Greeter` Actrorは `Printer` Actorにメッセージを送信している
204
205 ```
206 printerActor.tell(new Greeting(greeting), getSelf());
207 ```
208
209 # テスト
210
211 * Javaで使われているのでテストはJUnitを利用できる
212 * akkaaでは `akka.test.javadsl.TestKit` が用意されており, TestKit が推奨されている。
213 * 詳しくは[公式ドキュメント](https://doc.akka.io/docs/akka/current/testing.html?language=java)を見ろということらしい…
214
215 ```
216 `ckage com.lightbend.akka.sample;
217
218 import akka.actor.ActorRef;
219 import akka.actor.ActorSystem;
220 import akka.testkit.javadsl.TestKit;
221 import com.lightbend.akka.sample.Greeter.*;
222 import com.lightbend.akka.sample.Printer.*;
223
224 import static org.junit.Assert.assertEquals;
225
226 import org.junit.AfterClass;
227 import org.junit.BeforeClass;
228 import org.junit.Test;
229
230 public class AkkaQuickstartTest {
231 static ActorSystem system;
232
233 @BeforeClass
234 public static void setup() {
235 system = ActorSystem.create();
236 }
237
238 @AfterClass
239 public static void teardown() {
240 TestKit.shutdownActorSystem(system);
241 system = null;
242 }
243
244 @Test
245 public void testGreeterActorSendingOfGreeting() {
246 final TestKit testProbe = new TestKit(system);
247 final ActorRef helloGreeter = system.actorOf(Greeter.props("Hello", testProbe.getRef()));
248 helloGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender());
249 helloGreeter.tell(new Greet(), ActorRef.noSender());
250 Greeting greeting = testProbe.expectMsgClass(Greeting.class);
251 assertEquals("Hello, Akka", greeting.message);
252 }
253 }
254 ```