やさしいIteratee入門
Play Framework 2 Meetup
@kawachi
2014/5/24
データ分析関連書籍

翻訳やってます。
Scala, Play, iOS,

Ruby, Rails,
Java, C, Python,
Javascript, Haxe etc.
Scala, Play 関連
2011年 プロトタイプ作成にPlay! 1 採用

(少しだけ)
2012年~ Scalaをメインとして使用
2013年末~ Play 2 で開発
サービス課題をサクッとチェック
事前登録受付中 http://logbook.strikingly.com/
Logbook
ScalaMatsuri
9月6~7日
日本最大のScala Conference
ただいまSponsor募集中!
http://scalamatsuri.org
対象
• 今日の話は Play 2.3.0-RC1 を基にしています
• Scala です
• えーと、Java の方いらっしゃいますか?
今日の内容
1. Iteratee の概要
2. Iteratee 3つの特徴
3. 身近な Iteratee
Iteratee?
• Websocket の説明を読んでいると突然出てくるアレ
• マニュアル内 Advanced topics の最初の項目
• 純粋関数型世界からきた概念
• 2008年に提唱された
• http://okmij.org/ftp/Streams.html
Iteratee を知っておくべき理由
• WebSocket/Comet の実装に必要
• Play のいろんなところで使われている
• わかんないと気持ち悪い (ですよね?)
Iteratee を学びたての

James Roper さん曰く (2012/11)
• “Well I just learnt iteratees, and although I'm
feeling more and more comfortable with
functional programming every day, I still
think like an imperative programmer at
heart. This made learning iteratees very
difficult for me.”
• Typesafe 社で Play の tech lead やってる人も

難しいっていってた
http://jazzy.id.au/default/2012/11/06/iteratees_for_imperative_programmers.html
今日の目的
Iteratee のイメージをつかむ。
Iteratee が出てきた時に驚かない体を作る。
ストリーミングモデル
読み込み
/生成
処理
出力
結果
Iteratee
Input
(小分けしたデータ)
Enumerator
ストリーミングモデル
読み込み
/生成
処理
出力
結果
IterateeEnumerator
変換
Enumeratee
Input
(小分けしたデータ)
Iteratee の状態と状態遷移
• Cont — 引き続き Input[E] を処理する
• Done — 結果がでた
• Error — エラーが起きた
Inputをひとつ処理する毎に
状態遷移
Cont
Done Error
Iteratee は状態をもつ
Iteratee ライブラリの3大要素
play.api.libs.iteratee
Iteratee
Enumerator
Enumeratee
今日の内容
1. Iteratee の概要
2. Iteratee 3つの特徴
3. 身近な Iteratee
3つの特徴
• Immutable
• Non-blocking
• Composable
Immutable?
でも状態があるよ?
Immutable で状態を変更するには…
Immutable collection を思い出してみよう。
!
val a1 = List(1, 2, 3)
val a2 = a1 ++ List(4, 5, 6)
もとのa1は変更されずそのまま。
新しい collection が生成される。
Immutable!
Cont 状態の Iteratee は

Input を引数にとって
次の Iteratee を返す
関数をもつ
1 Input 毎に
別の Iteratee が
生成される
Done か Error になったら
それ以上入力を受け取らない
Cont
Cont
Done
コード見たほうが分かりやすい?
sealed trait Step[E, +A]
!
object Step {
case class Done[+A, E](a: A, remaining: Input[E]) extends Step[E, A]
case class Cont[E, +A](k: Input[E] => Iteratee[E, A]) extends Step[E, A]
case class Error[E](msg: String, input: Input[E]) extends Step[E, Nothing]
}
Non-blocking
IterateeEnumerator
Iteratee
Iteratee
…
Iteratee に Input を流し込み、将来の Iteratee を得る
trait Enumerator[E] {
def apply[A](i: Iteratee[E, A]): Future[Iteratee[E, A]]
}
blockしない
混乱しがちなこと
• Iteratee には

状態がわかっているもの (StepIteratee)と、

将来状態がわかるもの(FutureIteratee)がある
• Future[Iteratee] は

Iteratee (FutureIteratee) に

変換できる (Iteratee.flatten())
Iteratee
StepIteratee FutureIteratee
Enumerator.apply() の結果は
Iteratee とみなせる
IterateeEnumerator
Iteratee
(FutureIteratee)
Iteratee.flatten()
結果Aの計算も Non-blocking
IterateeEnumerator
Iteratee
Iteratee
…
A
trait Iteratee {
def run: Future[A]
}
blockしない
Composable
• 小さなコンポーネントを組み合せて

より大きなコンポーネントをつくること
Enumerator.apply(Iteratee)
Iteratee[E,A]
E
Enumerator[E]
Iteratee[E,A]
(FutureIteratee)
Iteratee.flatten()
E
A
A
E E
|>>
Enumeratee.compose(Enumeratee)
Enumeratee[B,C]
A
Enumeratee[A,B]
A B B C C
Enumeratee[A,C]
A A C C
><>
Enumerator.through(Enumeratee)
Enumeratee[A,B]
A
Enumerator[A]
A B B
Enumerator[B]
B B
&>
Enumeratee.transform(Iteratee)
Iteratee[B,C]
A
Enumeratee[A,B]
A B B
C
Iteratee[A,C]
A A
C
&>>
Enumerator.andThen (Enumerator)
E
Enumerator[E]
EEnumerator[E]
1
2
ひとつめの Enumerator が
終わったら、ふたつめ
Enumerator[E]
E E
>>>
Enumerator.interleave(Enume
rator)
E
Enumerator[E]
EEnumerator[E]
ふたつを織り交ぜて出力する
Enumerator[E]
E E
>-
記号API
• |>>, |>>|, &>, >-, >>> などの記号がある
• Methodを呼び出しているだけ
• その都度定義をみても大丈夫
例:
def |>>[A](i: Iteratee[E, A]): Future[Iteratee[E, A]] = apply(i)
今日の内容
1. Iteratee の概要
2. Iteratee 3つの特徴
3. 身近な Iteratee
Iteratee が

Play のどんなところで

使われているかみてみましょう
身近なIteratee (WebSocket)
ドキュメント内のサンプルコード
def socket = WebSocket.using[String] { request =>
// Log events to the console
val in = Iteratee.foreach[String](println).map { _ =>
println("Disconnected")
}
// Send a single 'Hello!' message
val out = Enumerator("Hello!")
(in, out)
} (Iteratee[E, _], Enumerator[E])
身近なIteratee (WebSocket)
Browser
Play
Enumerator
Iteratee
WebSocket
ここは自分で頑張る
Actor based web socket API
• Play 2.3 から入る
• 自分で頑張る部分を手助けしてくれる
ドキュメント内のサンプルコード
def socket = WebSocket.acceptWithActor[String, String] {
request => out =>
MyWebSocketActor.props(out)
}
RequestHeader
ActorRef (出力担当Actor)
Props (入力担当Actorの設定)
Actor based web socket API
Browser
Play
Enumerator
Iteratee
出力Actor
入力Actor
Props
ここは自分で頑張る
身近なIteratee (Result)
def index = Action {
Ok("hello")
}
!
case class Result(
header: ResponseHeader,
body: Enumerator[Array[Byte]])
これは Result 型
身近なIteratee (Result)
Browser
Play
Enumerator
HTTP request
身近なIteratee (Result)
Ok.chunked() で chunked response が返せる。
送信開始時に全データ Content-Length を知らなくて
いいから嬉しい(こともある)。
!
def index = Action {
Ok.chunked(
Enumerator.fromFile(new File("1gb.file")))
}
身近なIteratee (BodyParser)
trait BodyParser[A] extends

(RequestHeader =>

Iteratee[Array[Byte], Either[Result, A]])
BodyParser は RequestHeader を取って Iteratee を返す関数
def save = Action(parse.text) { request =>
Ok("Got: " + request.body)
}
これが BodyParser。

指定しなければ parse.anyContent
parse された body
Play
身近なIteratee (BodyParser)
BodyParser
RequestHeader
Iteratee
Input[Array[Byte]]
①
②
A
HTTP request の body を
小分けしたもの
Request.body ができた
③HTTP request
まとめ
• Iteratee はストリーミング処理API
• Enumerator → Enumeratee → Iteratee
• Cont, Done, Error 状態をもつ
• Immutable, Non-blocking, Composable
• Play のいろんなところで使われている
ご清聴ありがとうございました
やさしかった…ですね?

More Related Content

PDF
Introduction to Iteratees (Scala)
KEY
Play2の裏側
PDF
一番簡単なWebSocketの試し方
PDF
Dslからのコードジェネレーションで楽々play開発
PDF
FP習熟度レベルとFSharpxのIteratee
PDF
JavaからScalaへ
PDF
こわくないよ❤️ Playframeworkソースコードリーディング入門
PDF
Play jjug2012spring
Introduction to Iteratees (Scala)
Play2の裏側
一番簡単なWebSocketの試し方
Dslからのコードジェネレーションで楽々play開発
FP習熟度レベルとFSharpxのIteratee
JavaからScalaへ
こわくないよ❤️ Playframeworkソースコードリーディング入門
Play jjug2012spring

Similar to やさしいIteratee入門 (20)

PDF
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
PDF
scala-kaigi1-sbt
PDF
Play ja 3_update
PDF
Trait in scala
PDF
Scala EE 7 Essentials
PDF
The state of sbt 0.13, sbt server, and sbt 1.0 (ScalaMatsuri ver)
PDF
HeapStats @ Seasar Conference 2015 LT
PDF
Scalaでのプログラム開発
PPTX
Spring frameworkが大好きなおはなし
PPTX
LL2021 Java update
PDF
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
PDF
Laravel / Lumen 次の一歩
PPTX
Java Day Tokyo 2014 まとめ (chen)
PDF
R5 3 type annotation
PPTX
Jakarta EE + MicroProfile との付き合い方
PPTX
ASP.NET Core WebAPIでODataを使おう
PDF
All I learned while working on a Scala OSS project for over six years #ScalaM...
PDF
WebSocket+Akka(Remote)+Play 2.1 Java
PDF
パターンでわかる! .NET Coreの非同期処理
PDF
JavaOne 2015 JDK Update (Jigsaw) #j1jp
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
scala-kaigi1-sbt
Play ja 3_update
Trait in scala
Scala EE 7 Essentials
The state of sbt 0.13, sbt server, and sbt 1.0 (ScalaMatsuri ver)
HeapStats @ Seasar Conference 2015 LT
Scalaでのプログラム開発
Spring frameworkが大好きなおはなし
LL2021 Java update
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Laravel / Lumen 次の一歩
Java Day Tokyo 2014 まとめ (chen)
R5 3 type annotation
Jakarta EE + MicroProfile との付き合い方
ASP.NET Core WebAPIでODataを使おう
All I learned while working on a Scala OSS project for over six years #ScalaM...
WebSocket+Akka(Remote)+Play 2.1 Java
パターンでわかる! .NET Coreの非同期処理
JavaOne 2015 JDK Update (Jigsaw) #j1jp
Ad

More from Takashi Kawachi (12)

PDF
例外のlogを快適に
PDF
MacroPyがすごい
PDF
Silhouette intro
PDF
最小 Hello World! チャレンジ
PDF
Sbt doctest
PDF
Elastic beanstalk と Docker と Play
PDF
Sbt lock1
PDF
Haskell超初心者勉強会20
PDF
Haskell超初心者勉強会17
PDF
Haskell超初心者勉強会14
PDF
Haskell超初心者勉強会11
PDF
Scalaでの例外処理
例外のlogを快適に
MacroPyがすごい
Silhouette intro
最小 Hello World! チャレンジ
Sbt doctest
Elastic beanstalk と Docker と Play
Sbt lock1
Haskell超初心者勉強会20
Haskell超初心者勉強会17
Haskell超初心者勉強会14
Haskell超初心者勉強会11
Scalaでの例外処理
Ad

やさしいIteratee入門