Skip to content

Instantly share code, notes, and snippets.

@sunny4381
Created February 26, 2013 11:24
Show Gist options
  • Save sunny4381/5037802 to your computer and use it in GitHub Desktop.
Save sunny4381/5037802 to your computer and use it in GitHub Desktop.
Play Framework の Iteratee/Enumerator/Enumeratee の使用例 ref: http://qiita.com/items/a711fa72db26c9263b3f
// 合計を計算する Iteratee (初期値は 0)
val initialValue: Int = 0
val sumIteratee: Iteratee[Int, Int] = Iteratee.fold(initialValue) { (total, e) => total + e }
// 1, 234, 455, 987 を要素にもつ Enumerator
val intEnumerator1: Enumerator[Int] = Enumerator(1, 234, 455, 987)
// intEnumerator1 の合計を計算する
val futureTotal1: Future[Int] = intEnumerator1.run(sumIteratee)
val total1: Int = Await.result(futureTotal1, Duration.Inf)
println("total=" + total1.toString)
// 431, 57, 668 を要素にもつ Enumerator
val intEnumerator2: Enumerator[Int] = Enumerator(431, 57, 668)
// intEnumerator2 の合計を計算する
val futureTotal2: Future[Int] = intEnumerator2.run(sumIteratee)
val total2: Int = Await.result(futureTotal2, Duration.Inf)
println("total=" + total2.toString)
total=1677
total=1156
val initialValue: Int = 0
val sumIteratee0: Iteratee[Int, Int] = Iteratee.fold(initialValue) { (total, e) => {
println("e=" + e.toString)
total + e
}
}
// feed しただけでは計算されない
val sumIteratee1 = Iteratee.flatten(sumIteratee0.feed(Input.El(1)))
val sumIteratee2 = Iteratee.flatten(sumIteratee1.feed(Input.El(234)))
val sumIteratee3 = Iteratee.flatten(sumIteratee2.feed(Input.El(455)))
val sumIteratee4 = Iteratee.flatten(sumIteratee3.feed(Input.El(987)))
// まだ計算されない
val futureTotal: Future[Int] = sumIteratee4.run
println("caclulate result")
val total = Await.result(futureTotal, Duration.Inf)
println("0+1+234+455+987=" + total.toString)
caclulate result
e=1
e=234
e=455
e=987
0+1+234+455+987=1677
val initialValue: Int = 0
val sumIteratee0: Iteratee[Int, Int] = Iteratee.fold(initialValue) { (total, e) => total + e }
val sumIteratee1 = Iteratee.flatten(sumIteratee0.feed(Input.El(1)))
val sumIteratee2 = Iteratee.flatten(sumIteratee1.feed(Input.Empty))
val sumIteratee3 = Iteratee.flatten(sumIteratee2.feed(Input.El(234)))
val sumIteratee4 = Iteratee.flatten(sumIteratee3.feed(Input.EOF))
val sumIteratee5 = Iteratee.flatten(sumIteratee4.feed(Input.El(455)))
val sumIteratee6 = Iteratee.flatten(sumIteratee5.feed(Input.El(987)))
// Input.Empty を feed した後に feed した値は計算される
println("0+1+234=" + Await.result(sumIteratee3.run, Duration.Inf))
// Input.EOF を feed して以降に feed した値は計算されない
println("0+1+234+455=" + Await.result(sumIteratee5.run, Duration.Inf))
println("0+1+234+455+987=" + Await.result(sumIteratee6.run, Duration.Inf))
0+1+234=235
0+1+234+455=235
0+1+234+455+987=235
// 500 ミリ秒ごとに文字列 "current time %s" を生成し続ける Enumerator
val stringGenerator: Enumerator[String] = Enumerator.generateM(
play.api.libs.concurrent.Promise.timeout(
Some("current time %s".format((new java.util.Date()))),
500
)
)
// コンソールに出力する Iteratee
val printIteratee: Iteratee[String, Unit] = Iteratee.foreach { println _ }
// 5 秒間だけ、stringGenerator が生成する要素それぞれに対して printIteratee を実行する
val future: Future[Unit] = stringGenerator.run(printIteratee)
Await.result(future, Duration(5, "seconds")
current time Tue Feb 26 11:55:58 JST 2013
current time Tue Feb 26 11:55:58 JST 2013
current time Tue Feb 26 11:55:59 JST 2013
current time Tue Feb 26 11:55:59 JST 2013
current time Tue Feb 26 11:56:00 JST 2013
current time Tue Feb 26 11:56:00 JST 2013
current time Tue Feb 26 11:56:01 JST 2013
current time Tue Feb 26 11:56:01 JST 2013
current time Tue Feb 26 11:56:02 JST 2013
current time Tue Feb 26 11:56:02 JST 2013
val initialValue: Int = 0
val sumIterator: Iteratee[Int, Int] = Iteratee.fold(initialValue) { (total, e) => total + e }
val futureSumIterator: Future[Iteratee[Int, Int]] = sumIterator.unflatten.map(_.it)
val sumIteratorAgain: Iteratee[Int, Int] = Iteratee.flatten(futureSumIterator)
val initialValue: Int = 0
var sumIteratee: Iteratee[Int, Int] = Iteratee.fold(initialValue) { (total, e) => total + e }
var futureSumIterator: Future[Iteratee[Int, Int]] = null
// 1 を Iteratee に与える
futureSumIterator = sumIteratee.feed(Input.El(1))
sumIteratee = Iteratee.flatten(futureSumIterator)
// 234 を Iteratee に与える
futureSumIterator = sumIteratee.feed(Input.El(234))
sumIteratee = Iteratee.flatten(futureSumIterator)
// 455 を Iteratee に与える
futureSumIterator = sumIteratee.feed(Input.El(455))
sumIteratee = Iteratee.flatten(futureSumIterator)
// 987 を Iteratee に与える
futureSumIterator = sumIteratee.feed(Input.El(987))
sumIteratee = Iteratee.flatten(futureSumIterator)
// 合計を計算する
val futureTotal: Future[Int] = sumIteratee.run
val total: Int = Await.result(futureTotal, Duration.Inf)
println("0+1+234+455+987=" + total.toString)
0+1+234+455+987=1677
val initialValue: Int = 0
var sumIteratee: Iteratee[Int, Int] = Iteratee.fold(initialValue) { (total, e) => total + e }
var futureSumIteratee: Future[Iteratee[Int, Int]] = null
// 1 を Iteratee に与える
futureSumIteratee = sumIteratee.feed(Input.El(1))
// 234 を Iteratee に与える
futureSumIteratee = futureSumIteratee.flatMap(_.feed(Input.El(234)))
// 455 を Iteratee に与える
futureSumIteratee = futureSumIteratee.flatMap(_.feed(Input.El(455)))
// 987 を Iteratee に与える
futureSumIteratee = futureSumIteratee.flatMap(_.feed(Input.El(987)))
// 合計を計算する
val totalFuture: Future[Int] = futureSumIteratee.flatMap(_.run)
val total = Await.result(totalFuture, Duration.Inf)
println("0+1+234+455+987=" + total.toString)
val initialValue: Int = 0
val sumIteratee0: Iteratee[Int, Int] = Iteratee.fold(initialValue) { (total, e) => total + e }
// sumIteratee0 に 1 を与える
val sumIteratee1: Iteratee[Int, Int] = Iteratee.flatten(sumIteratee0.feed(Input.El(1)))
// sumIteratee1 に 234 を与える
val sumIteratee2: Iteratee[Int, Int] = Iteratee.flatten(sumIteratee1.feed(Input.El(234)))
// sumIteratee2 に 583 を与える
val sumIteratee2_1: Iteratee[Int, Int] = Iteratee.flatten(sumIteratee2.feed(Input.El(583)))
// sumIteratee2 に 162 を与える
val sumIteratee2_2: Iteratee[Int, Int] = Iteratee.flatten(sumIteratee2.feed(Input.El(162)))
println("0=" + Await.result(sumIteratee0.run, Duration.Inf))
println("0+1=" + Await.result(sumIteratee1.run, Duration.Inf))
println("0+1+234=" + Await.result(sumIteratee2.run, Duration.Inf))
println("0+1+234+583=" + Await.result(sumIteratee2_1.run, Duration.Inf))
println("0+1+234+162=" + Await.result(sumIteratee2_2.run, Duration.Inf))
0=0
0+1=1
0+1+234=235
0+1+234+583=818
0+1+234+162=397
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment