KotlinとArrowで関数型プログラミング


概要

以下のウェビナーで紹介されるArrowライブラリのサンプルの一部を紹介します。
https://www.youtube.com/watch?v=IDMmmrRhUvQ&ab_channel=KotlinbyJetBrains

サンプルに使用するArrowのバージョンは 1.0.1

Arrow fx

Scheduler

特定の結果の取得するまで・している限り処理を行う際に利用できる。
以下ので例では外部API通信を行い、3回までリトライします。計4回の試行で全て失敗した際は S3GenerateSignedURLError型になり、一回でも成功した際はSignedURL型にマップされます。

Schedule
    .recurs<Either<S3GenerateSignedURLError, SignedURL>>(3)
    .zipRight(Schedule.doWhile { it.isLeft() })
    .repeat {
        s3Driver
            .generatePreSignedUrl("bucket", "key")
    }

Circuit breaker

マイクロサービスアーキテクチャで特定のサービスの負荷によるカスケード障害を防ぐためのパターンとしてサーキットブレイカーをArrow fxで容易に実現できる。

以下の例では定義したサーキットブレイカーで実行される処理は設定による制御が入る。この場合は2回の失敗の際に、2秒のタイムアウトが伴う(多箇所からのサーキットブレイカー経由の通信は行われない)。

@OptIn(ExperimentalTime::class)
val circuitBreaker = CircuitBreaker.of(
    maxFailures = 2,
    resetTimeout = Duration.seconds(2),
    exponentialBackoffFactor = 2.0,
    maxResetTimeout = Duration.seconds(60)
)
circuitBreaker.protectOrThrow {
    coreDriver.importantApi()
}

*例ではその場でインスタンス化しているが、実際はシングルトンとして生成する

組み合わせ

上記のにパターンで重要なシステムに対して負荷をかけずにリトライを試行することができる

Schedule
    .recurs<Either<ApiError, Result>>(3)
    .zipRight(Schedule.doWhile { it.isLeft() })
    .repeat {
        circuitBreaker.protectOrThrow {
            coreDriver.importantApi()
        }
    }