Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Monixと常駐プログラムの勘どころ
Search
Ishikawa Ryuto
December 13, 2024
Programming
980
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Monixと常駐プログラムの勘どころ
【オフライン】Scalaわいわい勉強会 #4【東京】
https://scala-tokyo.connpass.com/event/335477/
Ishikawa Ryuto
December 13, 2024
More Decks by Ishikawa Ryuto
See All by Ishikawa Ryuto
Scalaが支える4RAPの認証認可基盤
stoneream
0
96
Other Decks in Programming
See All in Programming
PHPプロジェクトの結合バランスを可視化する #php_night
kajitack
0
230
業務時間外もAIに働いてもらう話
colorful12
3
10k
高専、大学編入、そして未踏へ〜プロダクト開発とキャリアの歩み - Technical College, University Transfer, and On to “Mitou” / My Journey in Product Development and Career
pkmiya
0
140
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
190
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
890
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
160
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
6
2.5k
XHTMLが残したもの
yosuke_furukawa
PRO
2
420
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
3
340
ALB ログから Trace を気合で繋げる技術
fohte
7
880
in-process GraphQL のすすめ #ginzajs
izumin5210
4
1.5k
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
680
Featured
See All Featured
Designing Experiences People Love
moore
143
24k
Become a Pro
speakerdeck
PRO
31
6.2k
Evolving SEO for Evolving Search Engines
ryanjones
0
280
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Discover your Explorer Soul
emna__ayadi
2
1.3k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.8k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
490
Google's AI Overviews - The New Search
badams
0
1.6k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.9k
Thoughts on Productivity
jonyablonski
76
5.4k
Balancing Empowerment & Direction
lara
6
1.3k
Transcript
Monixと 常駐プログラムの 勘どころ 2024/12/13 Ishikawa Ryuto
自己紹介 石川 龍斗 (Ishikawa Ryuto) @stoneream 株式会社FOLIO (2023~) バックエンドエンジニアとしてScalaを書いている Scala歴は5年目くらい
「常駐プログラム」って何? 文字通り「一度起動したらそのまま立ち上げておくプログラム 」 背景として... 「Spotify アーティストの新曲を巡回・通知くん」を作った 主な機能 • フォロー中アーティストの取り込み (バッチ)
• アーティストのリリースを巡回 (毎日) • Discordへの通知 (随時) 以降、「巡回くん」
今日のお話 Monixの書き心地が良かった • エラーハンドリング • リトライ処理 • 処理の並列実行 常駐プログラムが常駐してもらうためのの勘どころ •
設計として考慮しておくと良さそうなこと • 実装としてやっておくと良かったこと 巡回くんでの実例を交えて紹介! 何度か作り直している ... 「こうすれば良かった ...」の話
簡単にMonixについて
val t1 = Task[Int] { 10 } val t2 =
Task[Int] { 20 } // Task同士の合成が可能 val combinedTask = for { t1Result <- t1 t2Result <- t2 } yield t1Result + t2Result // 30 combinedTask.runToFuture.foreach(println) // 並列で実行が可能 val tasks = Task.parSequence(Seq(t1, t2)) // 10 // 20 tasks.runToFuture.foreach(println) 処理のかたまりを “Task” という単位で扱い抽象化
val t1 = Task[Int] { 10 } val t2 =
Task[Int] { 20 } // Task同士の合成が可能 val combinedTask = for { t1Result <- t1 t2Result <- t2 } yield t1Result + t2Result // 30 combinedTask.runToFuture.foreach(println) // 並列で実行が可能 val tasks = Task.parSequence(Seq(t1, t2)) // 10 // 20 tasks.runToFuture.foreach(println) Task は遅延評価
val t1 = Task[Int] { 10 } val t2 =
Task[Int] { 20 } // Task同士の合成が可能 val combinedTask = for { t1Result <- t1 t2Result <- t2 } yield t1Result + t2Result // 30 combinedTask.runToFuture.foreach(println) // 並列で実行が可能 val tasks = Task.parSequence(Seq(t1, t2)) // 10 // 20 tasks.runToFuture.foreach(println) 非同期に実行することも
簡単に Monix について 処理のかたまりを Task という単位で扱い抽象化 非同期処理をシンプルに書くための機能を提供してくれる リトライやエラーハンドリングのための機能が充実している点も魅力 (後述) Cats
Effect の一部機能は Monix の影響を受けている、らしい >> cats.effect.IOとmonix.eval.Taskはとてもよく似ていて、しかも私は両方の開発に携わることになった ので、Taskで決めた設計は結局IOでも採用することになった。 とはいえ、IOはシンプルで信頼性の高い、 純粋なリファレンス実装になるように設計されている。 (Monix vs Cats-Effect より deepL翻訳)
勘所 1
エラーは基本的には自動回復 当たり前ですが...。 考慮する観点は以下の2つ? エラーの種類 • リトライで問題ない • 自動復旧できない ◦ 想定内のエラー?
◦ 想定外のエラー? リトライの種類 • 即座 • n秒後 • しない リトライ回数の制限 処理全体のタイムアウト なども プロダクション環境下では 復旧のための参考情報になる
Monixにおけるエラーハンドリングとリトライ Taskで発生した例外は自動的に捕捉してくれる! 捕まえたエラーを良い感じに扱うメソッドがいくつか生えている ・Task#onErrorHandleWith[B >: A](f: (Throwable) => Task[B]): Task[B]
例外の型や内容から別のTaskを作成する ・Task#onErrorRestartIf(p: (Throwable) => Boolean): Task[A] 例外の型や内容が特定の条件にマッチした場合にリトライする・しない ・Task#onErrorRestart(maxRetries: Long): Task[A] エラー発生時に任意の回数まではリトライする
巡回くんの例
def retryWhenTooManyRequests[A](task: Task[A], maxRetries: Int): Task[A] = { task.onErrorHandleWith {
case e: TooManyRequestsException => if (maxRetries > 0) { val retryAfter = e.getRetryAfter retryWhenTooManyRequests(task, maxRetries - 1) .delayExecution(retryAfter.seconds) } else { Task.raiseError(e) } case e => Task.raiseError(e) } } レートリミットに引っかかった
def retryWhenTooManyRequests[A](task: Task[A], maxRetries: Int): Task[A] = { task.onErrorHandleWith {
case e: TooManyRequestsException => if (maxRetries > 0) { val retryAfter = e.getRetryAfter retryWhenTooManyRequests(task, maxRetries - 1) .delayExecution(retryAfter.seconds) } else { Task.raiseError(e) } case e => Task.raiseError(e) } } 例外情報に含まれる情報を 参考にリトライを試みる
def retryWhenTooManyRequests[A](task: Task[A], maxRetries: Int): Task[A] = { task.onErrorHandleWith {
case e: TooManyRequestsException => if (maxRetries > 0) { val retryAfter = e.getRetryAfter retryWhenTooManyRequests(task, maxRetries - 1) .delayExecution(retryAfter.seconds) } else { Task.raiseError(e) } case e => Task.raiseError(e) } } それ以外の例外は諦める 何回やっても駄目なときは諦める
勘所 2
処理は途中で落ちる、絶対に落ちる イチからやり直しはしたくない • メモリが足りなくなった • APIのレートリミットに引っかかった • 間違えてKillした ほしい機能 •
途中から処理を再開できるようにする • 不必要な処理の再実行の抑制する 全部 実際に起きた
巡回くんの例 「新着リリース巡回」機能の場合... 1. 巡回スケジュールを作成し、データベースに処理待ちとして積む 2. 処理待ちから数件ずつ取って処理する 設計する際は... 各タイミングでの時刻も保持することもポイント! • 処理を積んだタイミング
• 処理の開始 • 処理の正常終了・異常終了 処理が始まっていない! 終わっていない!など エラー検知に役立ちます
ありがとうございました
リンク集 Monix https://github.com/monix/monix Monix vs Cats-Effect https://monix.io/blog/2018/03/20/monix-vs-cats-effect.html softwaremill/retry https://github.com/softwaremill/retry Scala
Advent Calendar 2024 https://qiita.com/advent-calendar/2024/scala FOLIO Advent Calendar 2024 https://adventar.org/calendars/10315 こちらもぜひご覧ください m(_ _)m これもおすすめ