cats-effect-io について
副作用を明示し、並行処理を組み立てるための Scala 向け Cats Effect スキルです。エフェクト型、ブロッキング呼び出し、リソース初期化、実行境界の扱いを解説します。
主な機能
- 01副作用をエフェクト値としてモデル化
- 02時刻・乱数・可変オブジェクト生成の遅延
- 03最小限の Cats Effect 能力を選択
- 04キャンセルを考慮したブロッキング処理
- 05構造化並行処理と Dispatcher の利用
活用シーン
- 01エフェクトを使う Scala API の設計
- 02Java のブロッキング処理のラップ
- 03共有可変サービスの初期化
- 04コールバック形式 API との接続
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ alexandru/ skills --skill cats-effect-ioインストール後、Claude Code で/cats-effect-ioを入力して読み込まれたか確認します。
同梱ファイルreferences/cats-effect-io.mdscripts/verify-examples.scala
詳細
Cats Effect IO(Scala)
クイックスタート
- すべての副作用と非決定性の原因をエフェクト値として扱い、必要最小限の Cats Effect の機能を備えた
IO[A]、SyncIO[A]、またはF[A]を返します。 - 事前に計算した結果ではなく、副作用を伴う呼び出し自体をサスペンドします。
Instant.now()、乱数や UUID の生成、環境変数の読み取り、new Array[...]などの可変オブジェクトの割り当ては、IO(...)、Sync[F].delay、Clock、Random、またはエフェクトを返すファクトリーの中で行います。 - 共有される可変状態は、
IO/F/Resourceのファクトリーを通じて初期化し、得られた参照やサービスを引き渡します。コンストラクター、トップレベルの val、デフォルト引数にエフェクトを隠さないでください。 - Java のブロッキング処理の使用フェーズの呼び出しは、デフォルトで
IO.interruptible(またはSync[F].interruptible)でラップします。取得、ファイナライザー、および中断すべきでない操作にはblockingを使用します。 - リソースの取得と解放には
Resourceを使用し、プログラムのエントリーポイントにはIOAppを使用します。 - 手動でファイバーを管理するより、構造化並行処理(
parTraverse、parMapN、background、Supervisor)を優先します。 - アプリケーションコードやテストでは
unsafeRun*(unsafeRunSync、unsafeRunAndForgetなど)を使用しないでください。Cats Effect に準拠しないコールバック API と連携する場合は、Dispatcherを使用します。 - 概念、レシピ、FAQ の指針、および検証済みのサンプルについては、
references/cats-effect-io.mdを参照してください。 Resourceの詳細なガイダンスについては、cats-effect-resourceスキルを使用してください(インストール:npx skills add https://github.com/alexandru/skills --skill cats-effect-resource)。
ワークフロー
- 時刻、乱数、可変オブジェクトの割り当て、共有状態の読み書きなど、すべての副作用と非決定的な値を特定します。
- エフェクト型を選びます。具体型の
IO、または必要最小限の機能(Clock、Random、Sync、Async、Temporal、Concurrentなど)を備えた多相型のF[_]を選択します。 - 副作用を伴うコードを
IO(...)、IO.interruptible、IO.blocking、IO.async、または対応する型クラスの操作でラップします。 - 状態を持つサービスの初期化を、
F[A]またはResource[F, A]を返すcreate/resourceファクトリーに移します。 flatMap/for 内包表記やコレクション用コンビネーター(traverse、parTraverse)でエフェクトを合成します。- 並行処理プリミティブ(
Ref、Deferred、Queue、Semaphore、Supervisor)と構造化並行処理を使用し、ファイバーのリークを防ぎます。 - エフェクトの実行は境界(
IOApp、フレームワークのランタイム)に限定します。コールバック形式の API と連携する場合は、Dispatcherで橋渡しします。
副作用に関するルール(IO、SyncIO、および F[_]: Sync/Async に適用)
- 副作用を伴う関数はすべて、
IO(または Cats Effect の型クラス/機能を備えたF[_])でラップした結果を返す必要があります。 - 副作用には、すべての非決定性(呼び出し箇所が参照透過でないもの)が含まれます。
- あらゆる I/O(ファイル、ソケット、コンソール、データベース)。
Instant.now()、System.currentTimeMillis()、Random.nextInt()、UUID.randomUUID()。- 環境変数、システムプロパティ、クロック、乱数ソース、共有可変状態からの読み取り。
- アイデンティティや変更が外部に漏れる可能性がある、可変構造体(
Array、mutable.Map、Java コレクション、AtomicReference、キャッシュ)の割り当てや返却。
- ローカルに限定された非公開の可変処理は、可変ブロック全体がサスペンドされ、可変値が外部に漏れない場合に限り許容されます。
ブロッキング I/O に関するルール
- ブロッキング処理の使用フェーズの操作には、
IO.interruptible/Sync[F].interruptibleを優先します。これによりキャンセル時に基盤のスレッドを中断できる可能性が生まれ、ネットワークやソケット形式のブロッキング API に適したデフォルトになります。 interruptibleを使用する前に、すべての Java API が中断に従うという証明を求めないでください。中断を無視する API もあるため、キャンセルへの応答性が重要で、テストで中断だけでは不十分と判明した場合は、リソース固有のキャンセルプロトコルを追加します。- 取得、クリーンアップ、破棄(
Closeable#close、AutoCloseable#close)にはIO.blocking/Sync[F].blockingを使用します。このような処理で中断を試みると、ライフサイクルの状態が不明確になる可能性があります。
出力に関する期待事項
- シグネチャで副作用を明示してください(
IO/SyncIOまたはF[_]: Sync/Async)。ここでのガイダンスは、具体型のIOと多相型のF[_]のどちらにも同様に適用されます。 - 必要な操作をサポートする、最小限の型クラス制約を使用してください。
- 副作用は値として保持し、コンストラクターやトップレベルの
valで実行しないでください。 - Scala の例を追加または変更した場合は、同梱の
scripts/verify-examples.scalaスクリプトを更新してコンパイルしてください。
実行とテストのルール
- 本番コードとテストコードでは、
import cats.effect.unsafe.implicits.globalを含め、unsafeRun*を使用してはいけません。 - Cats Effect 以外のコールバックから副作用を実行する必要がある場合は、
Dispatcherを使用してください。 - 副作用を手動で実行するのではなく、
IO[Assertion]/F[Assertion]を返すなど、副作用をネイティブに扱えるテストスタイルを優先してください。 TestControlを使った仮想時間のテストでない限り、ユニットテストでIO.sleep/Thread.sleepを使用しないでください。
参考資料
- ドキュメントの概要とパターンについては、
references/cats-effect-io.mdを読み込んでください。 - 具体例については、
references/cats-effect-io.mdを参照してください。代表的なチェックはscripts/verify-examples.scalaです。 Resourceに特化したワークフローとパターンには、cats-effect-resourceスキルを使用してください(インストール方法:npx skills add https://github.com/alexandru/skills --skill cats-effect-resource)。
コメント
Markdown 対応