2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
Scala ZIOをバッチ処理で使ってみた (全1記事)
リンクをコピー
記事をブックマーク
リチャード伊真岡氏:「Scala ZIOをバッチ処理で使ってみた」という発表をします。リチャード伊真岡と申します。マーベリック株式会社というところで働いています。
今日一番大事なことを最初に言おうと思います。発表の内容はどうでもいいので、私の名前だけ覚えていってもらえば満足です。
(会場笑)
ということで大事なことは済んだので、本題に移っていきたいと思います。
Scala ZIOの話なんですけど、この人はScalaのZIOというライブラリの作者でJohn De Goesさんという人です。
この関数型の最大のメリットの1つのtestabilityの話をブログでしているんですね。「"Functional programming ordinarily gives us the incredible ability to easily test our software."」。けっこう強いステートメントですね。
もう1人のDaniel Spiewakさん。
関数型界隈ですごく有名な方で、この人もすごく強いことを言っています。「"I would argue that the whole point of functional programming in general is testing"」と、かなり強いことを言っています。
というわけでみなさんもご存知かと思いますが、純粋関数はtestabilityが高い。インプットはだいたいアウトプットが出てくるだけなので、テストを書く時にはその予測されるアウトプットと比べればよいと。
ただ、実際のプログラムは副作用が入ってくるので「副作用はテストをするのが難しいですね」という話になります。
副作用を含むコードがあって、副作用と純粋関数呼び出しが混ぜこぜになるとテストはやりにくいので、ここで関数型のテクニックを使いましょう!
そうすると、ZIOもこの流れに沿うんですけど、descriptionとinterpreterの分離ということでいきます。
色分けをすると、descriptionというのはScalaでやるとfor文をよく使うんですけど、プログラムを実際に走らせるコードじゃなくて、「こういう処理をします」という記述、descriptionだけをやります。
この部分はfor文を通過しただけではプログラムがは走らないんですね。このfor文をprogramDescriptionというvalに束縛して、unsafeRunというところに渡して初めてプログラムが走るというテクニックを使って書きます。
上のほうでプログラムを記述するdescriptionである木構造のようなものを作っています。それで、それを走らせて初めて副作用が発生するということです。
ちょっとここで動くから見てもらいたいんですけど……。
(アニメーションが流れる)
こういう木構造が出てきて、これをランタイムと組み合わせると初めて動きます。いいでしょう?
(会場笑)
次のスライドに行くかな? 行かない?
(会場笑)
ごめんなさい。次のスライドに行きますね。動画に凝り過ぎてスライドが……つい動かしたくなっただけです。ごめんなさい。これ1時間半ぐらい掛けて作ったんです。
(会場笑)
つい動かしたくなっちゃいました。ごめんなさい(笑)。
こういうdescriptionとinterpreterを分離してコードを書くテクニックで、Free MonadやTagless Finalと呼ばれるテクニックがあります。ZIOもその流れに沿っています。
なんですけど、とくにTagless Finalについて、ZIOの作者の人のJohn De Goesさんがちょっと批判をしているんですね。
「テストはそんな簡単じゃないよ、綺麗にならないよ」と。testabilityが良くならないという話をしていました。
なぜかと言うと、さっき言ったようにdescriptionを関数型で記述する、つまりツリー構造のデータを作ってもそのツリー構造が期待したアウトプットと比較できないわけですね。
例えばprintln、出力をするというコードが含まれる副作用を書いたとして、期待されるコードと動作とどう比較するかみたいなことがあって、それが比較できない。それでこういう話のブログを書いて「ちょっと問題がありますよ」みたいな話をしています。
そこで「ZIOが良いんじゃないか」という話をこの作者の人がしています。
Tagless Finalなどに比べてtestabilityが向上するんじゃないかという話をしていて、かつ、非関数型プログラマにも馴染みやすいというのは、このZIOというライブラリの大きな開発動機の1つになっています。
これを我々マーベリックがバッチ処理のところで使ってみたという話をしていきます。
ZIOの入門みたいなところで、こういう戻り値型がたくさん出てくるわけですね。R、E、Aとありまして、右からいきます。
右のAが、処理が成功したときに返ってくる型です。次の真ん中のEはFailure Type。これはThrowableであったり、それを継承したものであったり、処理が失敗したときのExceptionが起こったときに投げられる型です。最後の左はEnvironment Typeと、ZIOの中では呼んでいます。ZIOってDependency Injectionを関数型と組み合わせることができて、そのDependency Injectionを表す型になります。ちょっとこれは後で説明します。
それで、我々が誇る素晴らしいプロダクトの「Cirqua」というものがあります。
Cirquaはインフィード広告と呼ばれるプロダクトです。
せっかくなのでプロダクトの動きを見ていきます。スマホとかでWebページを表示すると、広告が表示される領域があるんですね。ここで読み込まれた広告配信サーバに要求を送って、広告が返ってきます。
広告が表示されたあとにクリックされたら、その後トラッキングサーバというところにそのクリックされたというのが送られて、広告主ページでさらに商品を買うなどのユーザーの行動が継続されたら、それもトラッキングサーバに送られます。
トラッキングサーバというのは、そういうユーザーの行動を逐一計測しております。当然計測したらデータ処理の処理フローに流すわけですね。
最終的には、AWSのAthenaを使ってクエリを走らせて集計しています。このAthenaのクエリはバッチ処理で走らせておりまして、このバッチ処理のコードはCirquaという我々のプロダクトの中では独立しています。独立をしているので、ZIOという新しいライブラリを試すのにも良いだろうということで、我々はまずはここから導入をしてみました。
それで、さっき言ったZIOの戻り値型のEnvironment Type、ここはDIを使います。ここをうまく使いこなすことがキーになってくる感じなんですね。ここを説明していきます。
DIを使っていくので、まずはDIすべきコンポーネントを特定していきましょう。
今回はいくつか例を挙げていますけど、ConfigであったりAWSを使うのでS3であったり、あるいはデータベースでAthenaとか、そういうDIとして使うコンポーネントを特定します。
ZIOのブログとしても例として出てくるんですけど、cake patternを使ってDIをやっていきます。
cake patternを少し紹介します。サービスと呼ばれるトレイトを作って、それを囲むコンポーネントと呼ばれるようなトレイトを付けます。
そのプロダクションの実装とテストの実装を作っていきます。
ちょっとZIOのはいろいろあるんですけど、だいたいこんな感じでやるのがcake patternです。S3の場合だったらS3のコンポーネントとか、AthenaとかConfigとかいろいろなコンポーネントを積み重ねて、右のコードにあるextendsでwithとやって、cakeが層のように重なっていくのでcake patternと呼ばれています。
僕的にはどちらかと言うとおまんじゅうに見えるので、おまんじゅうっぽく「アッタカイヨー」という感じですね。
あんまりウケない。
(会場笑)
これはバッチ処理の中のコードです。
ちょっと省略してあまり詳細を載せていないですけど、loggerの処理を呼び出してデータベースコンポーネントの処理を呼び出す。1つ1つのコンポーネントがさっき言ったDIで使うコンポーネントですね。それで、Athenaのコンポーネントを呼び出している。
この戻り値型、普通は書かないところは書かなくてもいいんですけど、あえて書くとさっき言ったようなコンポーネントで重なったcakeがEnvironment Typeになっているわけですね。
Throwableだったりのエラーの型があって、最後のBatchResultというのが成功したときに返ってくる型です。この1つ1つの構文の中の処理がまたfor文で入れ子構造になっていて、こういうかたちで書いていくことができます。
ちなみに「cake patternはアンチパターンじゃないのか」と言う人がScala界にはよくいるんですけど、ZIOの作者によると、右下の小さい構文に入ってくるとwithでくっついているcakeの層が薄くなるので、小さいfor文の中を見ればそんなに依存性が大きくなくてリファクタリングもしやすい。だから「そんなにアンチパターンじゃないだろ」というのが作者の見解です。
ここまでの話の中でEffect(副作用)が発生するところはDIを使うと。DIを使ってテストをするのでtestabilityが向上するという話をしたんですけど、ちょっとここで私はよくわからなくなりました。というのは、関数型プログラミングでtestabilityが向上するという話で2番目に出てきたDaniel Spiewakさん。
これは動画の中から抜き出したんですけど、この人、testabilityの向上の話をしているのはAlgebraic Laws、代数的規則と言ったらいいんですか? その話をしていて、別にDIの話とかはしていないんです。
プログラムが満たすべきルールを型クラスが満たすべきルールとして定義しているみたいな話があったんですけど。
これはすごいツッコミ待ちのスライドなので、ぜひ強い人からツッコんでほしいんですけど。
そういう型クラスが満たすべきルールを、うまく数学的に定義して、いい感じにテストをしようみたいな話をしていたはずなので、これはTagless FinalとかZIOがその副作用に対する数学的規則を定義できないという意味では、ZIOはTagless Finalと変わらないので、これでZIOによってTagless Finalよりtestabilityが向上するというのがよくわかりませんでした。
この話は実はZIOの作者の人もしていて「"Tagless-final type classes do not,in general, have algebraic laws."」。代数的規則はTagless Finalでは成り立たないという話をしています。
ここまではわかるんですけど、私がこの先でわからなかったのは「Tagless FinalでZIOに変えて使ってもこれは一緒だから、なぜtestabilityが向上するのかわからなかった」という話なんですね。
今までの話で出てきたことをまとめます。
ZIOはおもしろいライブラリだと思うんですけど、testabilityという1点に関してはちょっとTagless finalとFree Monadに比べて良いところがあるというのを理解できませんでした。なのでツッコミというか教えてくれる人がいたらうれしいなという感じなんですけど。
なので、ZIOでどうやってテストをうまく書くかというと、DIの使い方とかモックの使い方となると、それは関数型のメリットなんだろうか。関数型のメリットではなくて、それぞれのDIの使い方とかテクニックとかそういう話になってしまう気がしました。
テストという点から離れると、ZIOには他にもメリットがたくさんあるライブラリなので、非関数型プログラムよりも馴染みやすくて、それ以外のメリットあるという話ならZIOの導入の動機にもなるということで、ここでZIOの他のメリットを……まとめる時間がなかったので、すみません。ここでトークを終わります。
(会場笑)
ありがとうございます。
(会場拍手)
関連タグ:
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05