SlideShare uma empresa Scribd logo
1 de 30
Baixar para ler offline
MONIX TASKが便利だという話
Taisuke Oe ( )@OE_uia
今日話すこと
Monix version 2.3.3
主にMonix Taskの話をします。
Monix Observable, Iterantは出てきません。
MONIXとは
JVM Scala及びScala.js向け並行プログラミング用ライブラリ
当初はScala向けReactiveXの実装からスタートした
現在ではTypelevelプロジェクトとして、関数型プログラミング用ライブラリと深く統合している
Monix2系まではcoreではなくCats及びScalaz向けモジュールをそれぞれ提供していた
Monix3系からCatsに依存している
Monix TaskはScalaz Taskにインスパイアされている
単純なMONIX TASKの使い方
import monix.execution.Scheduler.Implicits.global
import monix.eval.Task
import scala.util.{Success, Failure}
val sumTask = Task{println("side effect!");1+2}
val cancelable = sumTask.runOnComplete {
case Success(value) => println(s"result:$value")
case Failure(ex) => println("Oh-no!")
}
//side effect!
//result:3
//もし気が変わってキャンセルしたければ:
//cancelable.cancel()
cancelableなので:
Task.chooseFirstOfList により、競争状態のTaskのうち最初に完了したもの以外をキャンセル
timeout を設定可能
TASK.APPLYは非同期な遅延評価
Task#apply
val sumTask = Task(1+2)
参考:SCALA標準のFUTURE.APPLYの実装は先行評価
import scala.concurrent._
import ExecutionContext.Implicits.global
Future{println("side effect!") ; 1+2}
//side effect!
Future.foreach(println)
//3
RUNONCOMPLETE / RUNASYNC
val cancelable = sumTask.runOnComplete {
case Success(value) => println(s"result:$value")
case Failure(ex) => println("Oh-no!")
}
//side effect!
//result:3
遅延評価Taskを実行する
引数として、完了時のCallbackを登録できる
戻り値として、Cancelableを返す
TASKインスタンスの評価方法
以下の2軸について変わるので、マトリックスで整理しましょう
実行モデル: 同期 or 非同期
評価戦略: 先行評価 or 遅延評価
TASKインスタンス生成と評価方法の関係
非同期 同期
遅延評価 apply
先行評価
基本は遅延評価。
val task = Task.eval{println("side effect!");1+2}
task.runAsync.foreach(println)
//side effect!
//3
Task.evalのエイリアスとして、(scalaz Taskのメソッド名と同じ)Task.delayも用意されている。
遅延評価した値をメモ化可能
val task = Task.evalOnce{println("side effect!");1+2}
task.runAsync.foreach(println)
//side effect!
//3
task.runAsync.foreach(println)
//3
Task.eval(...).memoizeと等価。
成功値のみメモ化することも可
var effect = 0
val task = Task.eval{
effect += 1
if(effect < 2) throw new RuntimeException("boom!")
effect
}.memoizeOnSuccess
val callback:Try[Int] => Unit = {
case Success(value) => println(value)
case Failure(ex) => println(ex)
}
task.runOnComplete(callback) //java.lang.RuntimeException: boom!
task.runOnComplete(callback) //2
task.runOnComplete(callback) //2
TASKインスタンス生成と評価方法の関係
非同期 同期
遅延評価 apply eval, delay, evalOnce
先行評価
評価済みの値をラップするため、先行評価もできる
val task = Task.now{println("side effect!");1+2}
//side effect!
task.runAsync.foreach(println)
//3
Scala標準のFuture.successful、scalaz TaskのTask.nowと同じ。
TASKインスタンス生成と評価方法の関係
非同期 同期
遅延評価 apply eval, delay, evalOnce
先行評価 now, pure
評価戦略を先行評価から遅延評価へ変更
val task = Task.defer(Task.now{println("side effect!");1+2})
task.runAsync.foreach(println)
//side effect!
//3
Task.deferのエイリアスとして、(Scalaz Taskのメソッド名と同じ)Task.suspendが用意されて
いる
TASKインスタンス生成と評価方法の関係
非同期 同期
遅延評価 apply eval, delay, evalOnce
先行評価 now, pure,failed
遅延
↑ : Task.defer / Task.suspend
先行
SCALA標準FUTUREからTASKインスタンス生成可
import scala.concurrent.Future
import monix.execution.Scheduler.Implicits.global
val task = Task.fromFuture(Future{println("side effect!");1+2})
//side effect!
task.runAsync.foreach(println)
//3
Task.fromFutureだと、(Futureが先行評価なので)先行評価される非同期Taskインスタンス
が生成。
SCALA標準FUTUREからTASKインスタンス生成可(遅延評価したい)
import scala.concurrent.Future
import monix.eval.Task
val task = Task.deferFutureAction{
implicit scheduler =>
Future{println("side effect!");1+2}
}
import monix.execution.Scheduler.Implicits.global
task.runAsync.foreach(println)
//side effect!
//3
Futureを生成する関数をTask.deferFutureActionでラップすると、 遅延評価される非同期
Taskインスタンスが生成可能。
TASKインスタンス生成と評価方法の関係
非同期 同期
遅延評価 apply, deferFutureAction eval, delay, evalOnce
先行評価 fromFuture now, pure,raiseError
遅延
↑ : Task.defer / Task.suspend
先行
コールバック関数からTASKを生成
import monix.eval.{Task, Callback}
import monix.execution.Scheduler
import scala.concurrent.duration._
import scala.util.{Success,Failure}
class HttpClient(handler:HttpHandler){
def get(url:String):Unit = handler.onSuccess(s"body mock from `$url`")
}
class HttpHandler(callback:Callback[String]){
def onSuccess(body:String):Unit = callback(Success(body))
def onFailure(ex:Throwable):Unit = callback(Failure(ex))
}
val task = Task.create[String]{
(scheduler,callback) =>
scheduler.scheduleOnce(1 second){
new HttpClient(new HttpHandler(callback)).get("https://google.com/"
}
}
task.runAsync.foreach(println)
Task.createのエイリアスとして、(scalaz Taskのメソッド名と同じ) Task.asyncも用意されてい
る。
TASKインスタンス生成と評価方法の関係
非同期 同期
遅延評価 apply, create, async, evalOnce, deferFutureAction eval, delay, evalOnce
先行評価 fromFuture now, pure
遅延
↑ : Task.defer / Task.suspend
先行
TASK#EXECUTEWITHFORKによる非同期化
val task = Task.eval{
println(s"side effect at:${Thread.currentThread.getName}")
1+2
}
task.runAsync.foreach(println)
//side effect at:run-main-0
//3
val asyncTask = task.executeWithFork
asyncTask.runAsync.foreach(println)
//side effect at:scala-execution-context-global-59
//3
executeOn で実行するSchedulerを明示的に指定できる
Monix 3系では executeAsync にrenameされた
TASKインスタンス生成と評価方法の関係
非同期 同期
遅延評価 apply, create, async, evalOnce, deferFutureAction eval, delay, evalOnce
先行評価 fromFuture now, pure
遅延
↑ : Task.defer / Task.suspend
先行
非同期 ← 同期 : executeWithFork / executeOn
非同期 → 同期 : coeval
実行モデル
SCALA標準FUTUREの実行モデル
object Future{
def apply[T](t: =>T)(implicit executor:ExecutionContext):Future[T]
}
trait Future[+T] extends Awaitable[T]{
def flatMap[S](f: T => Future[S])(implicit executor:ExecutionContext):Future
}
Future.apply, Future# atMap等の各関数が暗黙の引数としてとる ExecutionContext の実装によって決まる。
すなわち、 atMapによる合成ごとにContext Switchが発生する。
MONIX TASKの実行モデル
Task.runAsync,runOnCompleteが暗黙の引数としてとるmonix.execution.Schedulerの実装によって決まる。
Task# atMapによる合成では Context Switchが起きない
Task#executeOnやTask#asyncBoundaryにより非同期境界を指定し、runAsync するときに実行モデルを決定できる。
MONIX TASKにおけるCONTEXT SWITCH
val start = Task(println(s"start at:${Thread.currentThread.getName}"))
val imHere = Task.eval(println(s"I'm here:${Thread.currentThread.getName}
val composed = for{
_ <- start
_ <- imHere.executeOn(Scheduler.io(name = "io"))
_ <- imHere.asyncBoundary
_ <- imHere
} yield ()
composed.runAsync(Callback.empty)
/*
* start at:scala-execution-context-global-205
* I'm here:io-206
* I'm here:io-206
* I'm here:scala-execution-context-global-205
*/
MONIX TASKのまとめ
デフォルトが遅延評価なので、immutableかつ参照透過で扱いやすい。
TaskのrunAsync/runOnCompleteでThreadPoolを渡す設計となっており、柔軟にContext Switchを制御可能。実効性能上有
利。
cancelableや、Scala標準Futureとのinteropなど、何かと痒いところに手が届く
Monix3系からCatsに依存してしまっている。
失敗型が Throwable であるため、エラーを独自定義型の戻り値で表現したい場合使いにくい。

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
あなたのチームの「いい人」は機能していますか?
あなたのチームの「いい人」は機能していますか?あなたのチームの「いい人」は機能していますか?
あなたのチームの「いい人」は機能していますか?
 
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
 
Humble Object Patternな話
Humble Object Patternな話Humble Object Patternな話
Humble Object Patternな話
 
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?
 
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
 
マスターデータの キャッシュシステムの改善の話
マスターデータの キャッシュシステムの改善の話マスターデータの キャッシュシステムの改善の話
マスターデータの キャッシュシステムの改善の話
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターン
 
シリコンバレーの「何が」凄いのか
シリコンバレーの「何が」凄いのかシリコンバレーの「何が」凄いのか
シリコンバレーの「何が」凄いのか
 
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
 
Spring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作るSpring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作る
 
Railsで作るBFFの功罪
Railsで作るBFFの功罪Railsで作るBFFの功罪
Railsで作るBFFの功罪
 
Re: ゼロから始める監視設計
Re: ゼロから始める監視設計Re: ゼロから始める監視設計
Re: ゼロから始める監視設計
 

Semelhante a Monix Taskが便利だという話

JavaFX 2.0 - リッチクライアントのためのUI基盤
JavaFX 2.0 - リッチクライアントのためのUI基盤JavaFX 2.0 - リッチクライアントのためのUI基盤
JavaFX 2.0 - リッチクライアントのためのUI基盤
Yuichi Sakuraba
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行
guest5f4320
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
papamitra
 

Semelhante a Monix Taskが便利だという話 (20)

C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive Extensions
 
React+redux+saga 03
React+redux+saga 03React+redux+saga 03
React+redux+saga 03
 
Composable Callbacks & Listeners
Composable Callbacks & ListenersComposable Callbacks & Listeners
Composable Callbacks & Listeners
 
Lt 111217
Lt 111217Lt 111217
Lt 111217
 
Trait in scala
Trait in scalaTrait in scala
Trait in scala
 
Rx swift,Repro framewolrk
Rx swift,Repro framewolrkRx swift,Repro framewolrk
Rx swift,Repro framewolrk
 
Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRuby
 
2019年度 CaaS ワークショップ @ NTTコム
2019年度 CaaS ワークショップ @ NTTコム2019年度 CaaS ワークショップ @ NTTコム
2019年度 CaaS ワークショップ @ NTTコム
 
JavaFX 2.0 - リッチクライアントのためのUI基盤
JavaFX 2.0 - リッチクライアントのためのUI基盤JavaFX 2.0 - リッチクライアントのためのUI基盤
JavaFX 2.0 - リッチクライアントのためのUI基盤
 
AWS Lambda Update
AWS Lambda UpdateAWS Lambda Update
AWS Lambda Update
 
Embulk 20150411
Embulk 20150411Embulk 20150411
Embulk 20150411
 
Openresty
OpenrestyOpenresty
Openresty
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDE
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行
 
Scala2.8への移行
Scala2.8への移行Scala2.8への移行
Scala2.8への移行
 
MoteMote Compiler Plugin
MoteMote Compiler PluginMoteMote Compiler Plugin
MoteMote Compiler Plugin
 
CLRH_120414_WFTDD
CLRH_120414_WFTDDCLRH_120414_WFTDD
CLRH_120414_WFTDD
 
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミング
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
 
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますElixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
 

Mais de Taisuke Oe

How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
Taisuke Oe
 

Mais de Taisuke Oe (11)

プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」
 
How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
 
How to get along with implicits
How to get along with implicits How to get along with implicits
How to get along with implicits
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミット
 
Real World Android Akka - 日本語版
Real World Android Akka - 日本語版Real World Android Akka - 日本語版
Real World Android Akka - 日本語版
 
AuxパターンをDottyで解決する
AuxパターンをDottyで解決するAuxパターンをDottyで解決する
AuxパターンをDottyで解決する
 
Real World Android Akka
Real World Android AkkaReal World Android Akka
Real World Android Akka
 
Real world android akka
Real world android akkaReal world android akka
Real world android akka
 
多相な関数の定義から学ぶ、型クラスデザインパターン
多相な関数の定義から学ぶ、型クラスデザインパターン多相な関数の定義から学ぶ、型クラスデザインパターン
多相な関数の定義から学ぶ、型クラスデザインパターン
 
Android BLEのつらみを予防するTips
Android BLEのつらみを予防するTipsAndroid BLEのつらみを予防するTips
Android BLEのつらみを予防するTips
 
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
 

Monix Taskが便利だという話