コルーチンで外部APIを並列的に呼び出してawaitAllで待つ

asyncで起動したコルーチンを使って外部APIを並列的に複数回呼び出して、結果をawaitAllで待つ処理の実装。

fun getTask(taskId: Int): Task {
    callApiInParallel()
}
// asyncとawaitAllを使って外部API呼び出しを並列化する関数
fun callApiInParallel() = runBlocking<Unit> {
    val time = System.currentTimeMillis()

    val deferredList: List<Deferred<Task?>> = listOf(
            async { getTaskDataAsync(1) },
            async { getTaskDataAsync(2) },
            async { getTaskDataAsync(3) }
    )

    val taskList = deferredList.awaitAll()

    println("Completed in ${System.currentTimeMillis() - time} ms")
    println(taskList)
}
// Repository層を呼び出してtaskデータを取得する関数
suspend fun getTaskDataAsync(taskId: Int): Task? {
    val startTime = System.currentTimeMillis()
    println("start $taskId")

    val response = taskRepository.getTask(taskId)

    val elapsedTime = System.currentTimeMillis() - startTime
    println("end   $taskId time=$elapsedTime ms")
    return response
}
// Repository層の外部API呼び出し関数
suspend fun getTask(taskId: Int): Task? {
    val uri = "$taskApiUrl/tasks/$taskId"
    val webClient = WebClient.builder()
            .baseUrl("http://localhost:50000")
            .build();

    val task: Task? = webClient
            .get()
            .uri(uri)
            .awaitExchange()
            .awaitBody<Task>()
    return task
}

結果

start 1
start 2
start 3
end   2 time=3014 ms
end   1 time=3016 ms
end   3 time=3013 ms
Completed in 3016 ms

[Task(taskId=1, title=タスクのタイトル, description=タスクの詳細説明, created=Sun Nov 22 15:30:55 JST 2020), Task(taskId=2, title=タスクのタイトル, description=タスクの詳細説明, created=Sun Nov 22 15:30:55 JST 2020), Task(taskId=3, title=タスクのタイトル, description=タスクの詳細説明, created=Sun Nov 22 15:30:55 JST 2020)]

コメントを残す

メールアドレスが公開されることはありません。

ABOUT US
little
15年以上プログラマーをしているエンジニアです。Kotlin, Java, Python, C++を使用したServerSideの開発に携わってきました。とりあえずやってみるスタイルで記事を更新していきます。