時計を壊せ

駆け出してからそこそこ経ったWebプログラマーの雑記

Akka 2.4を雑にためす: その1

※ メモです

Scalaもくもく会に参加した。 Gitterでわいわいしながら自分のペースでもくもくできてよかった。
第1回 Scalaもくもく会@Volare - connpass
第2回 Scalaもくもく会@Volare - connpass

ぼくは、Actorが使ってみたくてScalaでAkkaをためしてみた。 ドキュメント長すぎて読むのに気力と体力が要求されたので、 とりあえずドキュメントを読まずにサンプルコードを書き換えてみるという、 非常にカジュアルな試しかたをした。

まずはbuild.sbtを書く。

lazy val root = (project in file(".")).
  settings(
    name := "tut",
    version := "1.0",
    scalaVersion := "2.11.6",
    libraryDependencies += "com.typesafe.akka" % "akka-actor_2.11" % "2.4-SNAPSHOT",
    libraryDependencies +=  "org.scalaj" %% "scalaj-http" % "1.1.4",
    resolvers += "Akka Snapshot Repository" at "http://repo.akka.io/snapshots/"
  )

雑に1秒遅れてEchoするActorを書く。

import akka.actor.{Actor,ActorSystem,Props}
import akka.pattern.ask
import akka.pattern.gracefulStop
import akka.util.Timeout
import scala.concurrent.Future
import scala.concurrent.Await
import scala.concurrent.duration._

class DelayEchoActor extends Actor {
  def receive = {
    case msg: String =>
      Thread.sleep(1000)
      sender ! msg
  }
}

object HelloWorld {
  def main(args: Array[String]) = {
    var sys = ActorSystem("system")
    val echo = sys.actorOf(Props[DelayEchoActor])

    implicit val timeout = Timeout(10 seconds)

    val futures = scala.collection.mutable.ArrayBuffer.empty[Future[Any]]
    futures += echo ? "あれ?"
    futures += echo ? "文字列が"
    futures += echo ? "遅れて"
    futures += echo ? "流れて"
    futures += echo ? "くるよ?"

    for (future <- futures.toArray) {
      val res = Await.result(future, timeout.duration)
      res match {
        case msg: String => println(msg)
      }
    }

    sys.shutdown()
  }
}

動かしてみると、たしかに遅れて流れてくる。 では、並列に動かすには?

とりあえず、systemを複数作ってみる。ついでなのでHTTPでgoogleのトップページも雑に叩く。

import akka.actor.{Actor,ActorSystem,Props}
import akka.pattern.ask
import akka.pattern.gracefulStop
import akka.util.Timeout
import scala.concurrent.Future
import scala.concurrent.Await
import scala.concurrent.duration._
import scalaj.http._
import java.lang.Object

class DelayEchoActor extends Actor {
  def receive = {
    case msg: String =>
      import dispatch._, Defaults._
      Thread.sleep(1000)
      sender ! msg
  }
}

class HttpGetRequestActor extends Actor {
  def receive = {
    case url: String =>
      val response: HttpResponse[String] = Http(url).asString
      sender ! response
  }
}

object HelloWorld {
  def main(args: Array[String]) = {
    val echo1Sys = ActorSystem("echo1")
    val echo2Sys = ActorSystem("echo2")
    val http1Sys = ActorSystem("http1")
    val http2Sys = ActorSystem("http2")
    val echo1 = echo1Sys.actorOf(Props[DelayEchoActor])
    val echo2 = echo2Sys.actorOf(Props[DelayEchoActor])
    val http1 = http1Sys.actorOf(Props[HttpGetRequestActor])
    val http2 = http2Sys.actorOf(Props[HttpGetRequestActor])

    implicit val timeout = Timeout(10 seconds)

    val futures = scala.collection.mutable.ArrayBuffer.empty[Future[Any]]
    futures += echo1 ? "あれ?"
    futures += echo2 ? "文字列が"
    futures += echo1 ? "遅れて"
    futures += echo2 ? "流れて"
    futures += echo1 ? "くるよ?"
    futures += http1 ? "http://www.google.co.jp/"
    futures += http2 ? "http://www.google.co.jp/"

    for (future <- futures.toArray) {
      val res = Await.result(future, timeout.duration)
      res match {
        case response: HttpResponse[String] => println(response.body)
        case javaObject: Object => println(javaObject.toString())
      }
    }
  }
}

なるほど。並列に動く。 しかし、こんなめんどくさい感じなわけがないし、なんか、resに変なのがくるし、おかしい。(とりあえずjava.lang.Objectで受けてtoStringするという漢らしいことをしている。)

コードを追ってみるとActorSystem -> LocalActorRef -> ActorCell -> Deployerという要素が見えてきたがキリが無いので諦めてドキュメントに目を移す。 ドキュメントを斜め読みする。ふむ。なんかconfigというのがあるらしい。 akka.actor.deploymentnr-of-instancesというやつがいる。これか?

となったところで、電池が切れそう。

結論

ドキュメント読んでから使え。

支援

Vol.3もあるようです:

第3回 Scalaもくもく会@Volare - connpass

気が向いたらその2も書く。

情熱と仕事と休息

仕事をやっていると、無条件で楽しいときもあれば、苦しいときもある。 苦しいときに、めげずに前向きに仕事をするためには情熱が必要だ。 情熱があれば、苦しいときでもがんばれるし、ときにはすごい力を発揮出来るかもしれない。

人はそれぞれ、違うところに情熱を燃やしている。 ときには、情熱を燃やすところががチームや組織の目指すところと衝突することもある。 そんな状況が続いてしまうと、疲れてしまい、情熱はやがて枯れてしまう。 人によっては、情熱を枯らさないために、環境を変えるという選択もするかもしれない。 一度枯らした情熱に再度火を灯すためには、とてもエネルギーを使うから。

だから、情熱を枯らさないように、疲れたら気軽に休むのが大事だと思う。 気軽に休めない環境を作ってしまうとみんな不幸になると思う。 だから、みんな気軽に休んで、気軽に休める環境を作っていくと、みんな幸せになれるんじゃないかな。 逆に、休みにくい環境を作ってしまうと、最終的には、情熱が枯れても逃げられない人だけが残った無気力な組織になってしまうと思う。

情熱を枯らしてしまうまえに、疲れたら臆せず休んで、情熱が回復したら、また仕事に打ち込む。 そんな働き方をしませんか。だれとなく。

きょうは会社休みます。 1 (マーガレットコミックスDIGITAL)

きょうは会社休みます。 1 (マーガレットコミックスDIGITAL)

っていうアフィ記事でした。

追記: ※自分や自分の環境の話じゃないです。自分の環境は気軽に休めていい感じなので、そんな環境がもっと一般的になればいいなと思って書きました。

JavaでDH鍵交換の初期化ベクトルを生成する

20億のデバイスでDH鍵交換の初期化ベクトルを生成できます。
以下のような具合のJavaコードをCreateDiffieHellmanIv.javaとして保存しましょう。

import java.security.AlgorithmParameterGenerator;
import javax.crypto.spec.DHParameterSpec;

public class CreateDiffieHellmanIv {
    public static void main (String[] args) throws Exception {
        int bitlen = 1024;
        if (args.length == 1) {
            bitlen = Integer.valueOf(args[0]).intValue();
        }
        System.out.println("Generating DiffieHellman initialization vector... " + "bitlen:" + String.valueOf(bitlen));

        AlgorithmParameterGenerator gen = AlgorithmParameterGenerator.getInstance("DH");
        gen.init(bitlen);

        DHParameterSpec spec = (DHParameterSpec)gen.generateParameters().getParameterSpec(DHParameterSpec.class);
        System.out.println("P: " + String.valueOf(spec.getP()));
        System.out.println("G: " + String.valueOf(spec.getG()));
    }
}

コンパイルします。

javac CreateDiffieHellmanIv.java

実行します。

java CreateDiffieHellmanIv

生成されます。

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
Generating DiffieHellman initialization vector... bitlen:1024
P: 145092357773036288785759831358363532457242150558361433565637207115514679411584100914869369530346476337051157705709858973344162440367967367833131503361926409583294585834757269998763188665426891871955393171079827134223234474237577100562967866893704671731464827466258191400928247383857555225260521584462646243757
G: 12076877650358872723433720596980214708516091408794486767543845481119286250958515342123571307476546309975921911735092979287081062213826767342459759424622360942234980320288127473825416480708591619721965721848952913500501787074997260325092958513471288533670082527450298168344704575797601113639175082590501897125

べんり。

YosemiteでAndroid StudioがJVMを見つけられずに起動出来ない問題の対処法

こういう具合のlaunchctlで読む用のplistを書いておいて、launchctl loadしてやるとよいっぽい。

setenv STUDIO_JDK on loaded.

いちいち全部の環境でsetupするのめんどくさいのでこんな具合で簡単に入るようにした。 launchctlの仕様よく分かってないのでなんか間違ってるかも。

curl -fsSL -o $HOME/Library/LaunchAgents/karupanerura.startup.android-studio.plist https://gist.githubusercontent.com/karupanerura/2bcf574f2ea514c92393/raw/78808e08270bb5fd23e79b81d4f8d52f8b617846/karupanerura.startup.android-studio.plist
launchctl load $HOME/Library/LaunchAgents/karupanerura.startup.android-studio.plist

参考:
http://qiita.com/neiraza/items/fdde2f922daa47b85bcd
java - Android Studio was unable to find a valid Jvm (Related to MAC OS) - Stack Overflow