# HG changeset patch # User Takahiro SHIMIZU # Date 1516803792 -32400 # Node ID 03ab44e80533bca45b416e44425b956aea51a038 # Parent 9175e77652b30695b8f61a0d10972e47e67c87e3 add make script diff -r 9175e77652b3 -r 03ab44e80533 .hgignore --- a/.hgignore Tue Jan 23 19:26:41 2018 +0900 +++ b/.hgignore Wed Jan 24 23:23:12 2018 +0900 @@ -21,4 +21,4 @@ themes/**/*.ttf themes/**/*.otf themes/**/*.woff -Utils/local +lib/Slideshow/local/* diff -r 9175e77652b3 -r 03ab44e80533 lib/Slideshow/Util.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/Slideshow/Util.pm Wed Jan 24 23:23:12 2018 +0900 @@ -0,0 +1,76 @@ +package Slideshow::Util; +use strict; +use warnings; +use utf8; + +use Carp qw/ croak /; + +use base 'Exporter'; +use FindBin; +use lib "$FindBin::Bin/local/lib/perl5"; + +use Time::Piece; +use feature 'say'; +use Path::Tiny; + +our @EXPORT = qw/ + new + set_template +/; + +sub set_template { + my $template = shift; + my $file = path($template); + return $file; +} + +sub new { + my ($template,$root_directory_name) = @_; + my $root_dir = path($root_directory_name); + my $t = localtime; + + my $day_dir = $root_dir->child($t->strftime('%Y%m%d')); + $day_dir->mkpath; + + my $slide = $day_dir->child('slide.md'); + $slide->touch; + # $slide->copy($template); + $template->copy($slide); +} + +sub make_recently { + +} + +sub make_pinpoint { + +} + + +sub upload { + + use Capture::Tiny; + my ($stdout,$stderr,$exit) = capture { + system("hg addremove"); + system("hg add"); + }; + + unless($stderr){ + say $stdout; + } else { + croak "didn't commit"; + } + + ($stdout,$stderr,$exit) = capture { + system('hg commit -m "auto-Update generated slides by script"'); + }; + + unless($stderr){ + say "$stdout"; + } else { + say $stderr; + croak "didn't push"; + } +} + +1; diff -r 9175e77652b3 -r 03ab44e80533 lib/Slideshow/cpanfile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/Slideshow/cpanfile Wed Jan 24 23:23:12 2018 +0900 @@ -0,0 +1,4 @@ +requires 'Path::Tiny'; +requires 'YAML::XS'; +requires 'perl', '5.008001'; + diff -r 9175e77652b3 -r 03ab44e80533 lib/template.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/template.md Wed Jan 24 23:23:12 2018 +0900 @@ -0,0 +1,254 @@ +title: 分散フレームワークakkaの調査 +author: Takahiro Shimizu +profile: +lang: Japanese + + +# 調査目的 +* 先輩の修論の比較材料の為に行う +* 分散フレームワークの1つであるakkaがどのような書き方、及び処理なのかを調査する + +# 調査内容 +* akkaのmac osx,ubuntu上の導入 +* [公式チュートリアル](https://developer.lightbend.com/guides/akka-quickstart-java/)の例題を行う +* 今回はJavaで実行した + +# 環境構築 + +* 公式からzipファイルで提供されているので落とす +* 例題はGradleで実行できるように作成されているので `$ gradle run` を実行可能. + +# akkaの分散処理 + +* akkaはアクターモデルを採用したフレームワーク + * アクターモデルでは「アクター」と呼ばれるオブジェクト同士がメッセージ通信を行うことで並列処理を実現する(イベント・ドリブン) + * publicなAPIを持っていない為,強力な分離機能を持っており、複数のJVMなどでも連携可能 + * 環境透過性 + * 軽量 +* JVM上で動き、ScalaとJavaをサポートしている + +# 例題(Hello,World) + +* 今回は公式チュートリアルにある、複数のアクターが挨拶をするHello Worldの例題を実行する +* + +* 実行結果 + +``` +$ gradle run +Starting a Gradle Daemon (subsequent builds will be faster) + + > Task :run + >>> Press ENTER to exit <<< + [INFO] [01/16/2018 15:33:05.871] [helloakka-akka.actor.default-dispatcher-4] [akka://helloakka/user/printerActor] Howdy, Akka + [INFO] [01/16/2018 15:33:05.872] [helloakka-akka.actor.default-dispatcher-4] [akka://helloakka/user/printerActor] Howdy, Lightbend + [INFO] [01/16/2018 15:33:05.872] [helloakka-akka.actor.default-dispatcher-4] [akka://helloakka/user/printerActor] Good day, Play + [INFO] [01/16/2018 15:33:05.872] [helloakka-akka.actor.default-dispatcher-4] [akka://helloakka/user/printerActor] Hello, Java +``` + +# Hello World Actors + +* 例題のActorrは3種類のmessageを利用する + +* `WhoToGreet` + * greetingの受取用オブジェクト +* `Greet` + * greetingの実行用 +* `Greeting` + * `greeting`にメッセージを含める為の命令 + +* 複数のスレッドで共有をする必要がある為、メッセージはimmutableでなければならない + + +# Greeter Actor + +* `Greeter` のコンストラクタは、送信用メッセージと出力用のActorのリファレンスを必要とする +* mainの中ではGreeterは複数呼ばれている + +``` +package com.lightbend.akka.sample; + +import akka.actor.AbstractActor; +import akka.actor.ActorRef; +import akka.actor.Props; +import com.lightbend.akka.sample.Printer.Greeting; + +public class Greeter extends AbstractActor { + static public Props props(String message, ActorRef printerActor) { + return Props.create(Greeter.class, () -> new Greeter(message, printerActor)); + } + + static public class WhoToGreet { + public final String who; + + public WhoToGreet(String who) { + this.who = who; + } + } + + static public class Greet { + public Greet() { + } + } + + private final String message; + private final ActorRef printerActor; + private String greeting = ""; + + public Greeter(String message, ActorRef printerActor) { + this.message = message; + this.printerActor = printerActor; + } + + @Override + public Receive createReceive() { + return receiveBuilder() + .match(WhoToGreet.class, wtg -> { + this.greeting = message + ", " + wtg.who; + }) + .match(Greet.class, x -> { + printerActor.tell(new Greeting(greeting), getSelf()); + }) + .build(); + } +} +``` + +# Printer Actor + +* `Logging.getLogger(getContext().getSystem(), this);` で各Actorが `log.info()` に追記していく +* `Greeting` とlogsに対してhandleを所持している + +``` +package com.lightbend.akka.sample; + +import akka.actor.AbstractActor; +import akka.actor.ActorRef; +import akka.actor.Props; +import akka.event.Logging; +import akka.event.LoggingAdapter; + +public class Printer extends AbstractActor { + static public Props props() { + return Props.create(Printer.class, () -> new Printer()); + } + + static public class Greeting { + public final String message; + + public Greeting(String message) { + this.message = message; + } + } + + private LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this); + + public Printer() { + } + + @Override + public Receive createReceive() { + return receiveBuilder() + .match(Greeting.class, greeting -> { + log.info(greeting.message); + }) + .build(); + } +} +``` + + +# Actorを作る + +* akkaはインスタンスを作る際に `new` を使わない。これはakkaのインスタンスがリファレンスである為 (`akka.actor.ActorRef`)である。 + * その為、軽量かつ柔軟にシステムに組み込むことが可能である +* akkaのActorは `akka.actor.ActorSystem` が管理する。(factoryなどとも呼ばれる) +* 例題では次のようにakkaのインスタンスを作成している。 + +``` +public class AkkaQuickstart { + public static void main(String[] args) { + final ActorSystem system = ActorSystem.create("helloakka"); + try { + //#create-actors + final ActorRef printerActor = + system.actorOf(Printer.props(), "printerActor"); + final ActorRef howdyGreeter = + system.actorOf(Greeter.props("Howdy", printerActor), "howdyGreeter"); + final ActorRef helloGreeter = + system.actorOf(Greeter.props("Hello", printerActor), "helloGreeter"); + final ActorRef goodDayGreeter = + system.actorOf(Greeter.props("Good day", printerActor), "goodDayGreeter"); + //#create-actors +``` + +# メッセージ送信 + +* akkaのメッセージ送信は `ActorRef`の`tell`メソッドを呼ぶ。 + +``` +howdyGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender()); +howdyGreeter.tell(new Greet(), ActorRef.noSender()); + +howdyGreeter.tell(new WhoToGreet("Lightbend"), ActorRef.noSender()); +howdyGreeter.tell(new Greet(), ActorRef.noSender()); + +helloGreeter.tell(new WhoToGreet("Java"), ActorRef.noSender()); +helloGreeter.tell(new Greet(), ActorRef.noSender()); + +goodDayGreeter.tell(new WhoToGreet("Play"), ActorRef.noSender()); +goodDayGreeter.tell(new Greet(), ActorRef.noSender()); +``` + +* `Greeter` Actrorは `Printer` Actorにメッセージを送信している + +``` +printerActor.tell(new Greeting(greeting), getSelf()); +``` + +# テスト + +* Javaで使われているのでテストはJUnitを利用できる +* akkaaでは `akka.test.javadsl.TestKit` が用意されており, TestKit が推奨されている。 +* 詳しくは[公式ドキュメント](https://doc.akka.io/docs/akka/current/testing.html?language=java)を見ろということらしい… + +``` +`ckage com.lightbend.akka.sample; + +import akka.actor.ActorRef; +import akka.actor.ActorSystem; +import akka.testkit.javadsl.TestKit; +import com.lightbend.akka.sample.Greeter.*; +import com.lightbend.akka.sample.Printer.*; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class AkkaQuickstartTest { + static ActorSystem system; + + @BeforeClass + public static void setup() { + system = ActorSystem.create(); + } + + @AfterClass + public static void teardown() { + TestKit.shutdownActorSystem(system); + system = null; + } + + @Test + public void testGreeterActorSendingOfGreeting() { + final TestKit testProbe = new TestKit(system); + final ActorRef helloGreeter = system.actorOf(Greeter.props("Hello", testProbe.getRef())); + helloGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender()); + helloGreeter.tell(new Greet(), ActorRef.noSender()); + Greeting greeting = testProbe.expectMsgClass(Greeting.class); + assertEquals("Hello, Akka", greeting.message); + } +} +``` diff -r 9175e77652b3 -r 03ab44e80533 slideshow.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/slideshow.pl Wed Jan 24 23:23:12 2018 +0900 @@ -0,0 +1,17 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use utf8; + + +use lib 'lib'; +use Slideshow::Util; +use Getopt::Long; + +my $new_flag; + +GetOptions("new" => \$new_flag) or die("Error at new flags"); + +if ($new_flag){ + new(set_template('lib/template.md'),"slides"); +}