コルーチンを使用したジョブの並列実行

ファヤズC

コルーチンを使用して複数のジョブを並行して実行したい。これは私が思いついたコードです。
2つのクエリがあります:

  • 呼び出し元のスレッドで完了コールバックが発生するようにするにはどうすればよいですか?

  • コードは、通常のスレッドで使用していたコールバックパターンのようになりました。コルーチンの読みやすさの利点を実現するために、デザインの変更を提案してください。

class ParallelExecutor {

    suspend fun <OUTPUT> execute(
        jobs: List<suspend () -> OUTPUT>,
        onTimeout: (jobIndex: Int) -> OUTPUT,
        onFailure: (jobIndex: Int, exception: Throwable) -> OUTPUT,
        onCompletion: suspend (jobIndex: Int, result: OUTPUT) -> Unit,
        timeout: Long,
        onFullCompletion: suspend () -> Unit = {},
        invokeDispatcher: CoroutineDispatcher = Dispatchers.Default
    ) {
        withContext(invokeDispatcher) {
            var counter = 0
            val listenJobs = mutableListOf<Deferred<OUTPUT>>()

            jobs.forEachIndexed { index, job ->
                val listenJob = async {

                    try {
                        job()
                    } catch (e: Exception) {
                        onFailure(index, e)
                    }
                }
                listenJobs.add(listenJob)
            }

            listenJobs.forEachIndexed { index, job ->
                launch {
                    val output = try {
                        withTimeout(timeout) {
                            job.await()
                        }
                    } catch (e: TimeoutCancellationException) {
                        onTimeout(index)
                    }
                    onCompletion(index, output)
                    if (++counter == listenJobs.size) {
                        onFullCompletion()
                    }
                }
            }
        }
    }
}
マルコ・トポルニック

コードをかなり単純化できるように思えます。最初にすべてのasyncジョブを起動し、次にそれらを待機するためにさらにジョブを起動する2段階のイディオムは必要ありませんlaunch同じブロック内でジョブとコールバックに委任することができます。そうすれば、コールバックは呼び出し元のディスパッチャーで自然に呼び出され、変更されたコンテキスト内でジョブ自体のみを呼び出すことができますinvokeDispatcher

onFullCompletion呼び出しの下の呼び出し側に属するコードの一部のように見えexecuteます。以来execute、例外をスローしません、あなたはいずれかを必要としないtry-finally、それを取得します。

suspend fun <OUTPUT> execute(
    jobs: List<suspend () -> OUTPUT>,
    onTimeout: (jobIndex: Int) -> OUTPUT,
    onFailure: (jobIndex: Int, exception: Throwable) -> OUTPUT,
    onCompletion: suspend (jobIndex: Int, result: OUTPUT) -> Unit,
    timeout: Long,
    invokeDispatcher: CoroutineDispatcher = Dispatchers.Default
) {
    coroutineScope {
        jobs.mapIndexed { index, job ->
            launch {
                val output = try {
                    withTimeout(timeout) {
                        withContext(invokeDispatcher) {
                            job()
                        }
                    }
                } catch (e: TimeoutCancellationException) {
                    onTimeout(index)
                } catch (e: Exception) {
                    onFailure(index, e)
                }
                onCompletion(index, output)
            }
        }
    }
}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

2つのジョブを並行して実行し、別のジョブがkotlinコルーチンの使用を終了するのを待つ方法

分類Dev

シングルスパークコンテキストを使用してApache Sparkで並行ジョブ(アクション)を実行する方法

分類Dev

forループを使用した並列jenkinsジョブ

分類Dev

複数のブロッキングIOコルーチンを並行して実行する方法

分類Dev

ワーカー/マスターコンセプトを使用したslurmを使用して、異なるノードで異なる独立した並列ジョブを実行するにはどうすればよいですか?

分類Dev

コルーチン内で2つのKotlinコルーチンを並行して実行します

分類Dev

Kotlinコルーチンを使用したジョブのすべてのステータスを知る

分類Dev

Hyperledger Fabric、並列チェーンコードの実行を停止します

分類Dev

最後に完了したジョブ実行コンテキストの春のバッチを取得します

分類Dev

実行不可能な並列Pythonを介してFortranサブルーチンを実行する

分類Dev

ms-Accessモジュールサブルーチンを実行するためのPythonコード

分類Dev

Laravelはcronジョブなしでスケジュールされたコマンドを実行します

分類Dev

ゴルーチンを実行するときの並行性と並列性

分類Dev

Daskを使用してyarnで並列化されたPythonジョブを実行する方法は?

分類Dev

asyncioコルーチンを使用して関数を並行して実行しますか?

分類Dev

Quartzスケジューラ-並列ジョブ実行を許可します

分類Dev

mapreduceジョブの並列実行

分類Dev

階層を使用した並列UNIXジョブの送信

分類Dev

モデル並列実行を使用したtf.Estimatorの例

分類Dev

GNUmakeを使用した並列ビルドの実行

分類Dev

長いcronジョブが並行して実行されるのを防ぐための一般的なソリューション?

分類Dev

hadoopとjavaコマンドを使用したmap-reduceジョブの実行の違い

分類Dev

ジョブ実行時のコルーチンコールバックが10秒より長い

分類Dev

アイドル状態のワーカーに並列Rでジョブを実行させる方法は?

分類Dev

バッチ用にPythonプロセスを(マルチプロセッシングのプールを使用して)並列で実行します

分類Dev

最初のジョブがコンコースで失敗したときに2番目のジョブを実行しないでください

分類Dev

終了しないリターンを使用したリモートジョブの実行

分類Dev

複数のコンシューマーを持つジョブ キューが同じジョブを 2 回実行しました

分類Dev

jestを使用してモックされたreadlineモジュールのコールバック内でアサーションを実行する

Related 関連記事

  1. 1

    2つのジョブを並行して実行し、別のジョブがkotlinコルーチンの使用を終了するのを待つ方法

  2. 2

    シングルスパークコンテキストを使用してApache Sparkで並行ジョブ(アクション)を実行する方法

  3. 3

    forループを使用した並列jenkinsジョブ

  4. 4

    複数のブロッキングIOコルーチンを並行して実行する方法

  5. 5

    ワーカー/マスターコンセプトを使用したslurmを使用して、異なるノードで異なる独立した並列ジョブを実行するにはどうすればよいですか?

  6. 6

    コルーチン内で2つのKotlinコルーチンを並行して実行します

  7. 7

    Kotlinコルーチンを使用したジョブのすべてのステータスを知る

  8. 8

    Hyperledger Fabric、並列チェーンコードの実行を停止します

  9. 9

    最後に完了したジョブ実行コンテキストの春のバッチを取得します

  10. 10

    実行不可能な並列Pythonを介してFortranサブルーチンを実行する

  11. 11

    ms-Accessモジュールサブルーチンを実行するためのPythonコード

  12. 12

    Laravelはcronジョブなしでスケジュールされたコマンドを実行します

  13. 13

    ゴルーチンを実行するときの並行性と並列性

  14. 14

    Daskを使用してyarnで並列化されたPythonジョブを実行する方法は?

  15. 15

    asyncioコルーチンを使用して関数を並行して実行しますか?

  16. 16

    Quartzスケジューラ-並列ジョブ実行を許可します

  17. 17

    mapreduceジョブの並列実行

  18. 18

    階層を使用した並列UNIXジョブの送信

  19. 19

    モデル並列実行を使用したtf.Estimatorの例

  20. 20

    GNUmakeを使用した並列ビルドの実行

  21. 21

    長いcronジョブが並行して実行されるのを防ぐための一般的なソリューション?

  22. 22

    hadoopとjavaコマンドを使用したmap-reduceジョブの実行の違い

  23. 23

    ジョブ実行時のコルーチンコールバックが10秒より長い

  24. 24

    アイドル状態のワーカーに並列Rでジョブを実行させる方法は?

  25. 25

    バッチ用にPythonプロセスを(マルチプロセッシングのプールを使用して)並列で実行します

  26. 26

    最初のジョブがコンコースで失敗したときに2番目のジョブを実行しないでください

  27. 27

    終了しないリターンを使用したリモートジョブの実行

  28. 28

    複数のコンシューマーを持つジョブ キューが同じジョブを 2 回実行しました

  29. 29

    jestを使用してモックされたreadlineモジュールのコールバック内でアサーションを実行する

ホットタグ

アーカイブ