นากต้นฉบับรอไฟสถานะสามดวงติดครบก่อนรวบตะกร้าผลลัพธ์ตามลำดับ

Java CompletableFuture.allOf: รอครบได้ แต่ผลลัพธ์ต้องประกอบเอง

พี่โชว์Engineering

CompletableFuture.allOf คืน future ที่เสร็จเมื่อทุกงานเสร็จ แต่ชนิดผลลัพธ์เป็น Void ถ้าต้องการค่าจริงต้องเก็บ futures ต้นทางและประกอบผลหลัง barrier ผ่านครับ

import java.util.List;
import java.util.concurrent.CompletableFuture;

public class Main {
    static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> jobs) {
        CompletableFuture<Void> done = CompletableFuture.allOf(
                jobs.toArray(CompletableFuture[]::new));
        return done.thenApply(ignored -> jobs.stream()
                .map(CompletableFuture::join)
                .toList());
    }

    public static void main(String[] args) {
        var jobs = List.of(
                CompletableFuture.completedFuture("first"),
                CompletableFuture.completedFuture("second"));
        var result = sequence(jobs).join();
        assert result.equals(List.of("first", "second")) : result;
    }
}

ผลลัพธ์ยังเรียงตาม list เดิม ไม่ใช่ลำดับที่งานเสร็จ ถ้างานใด fail barrier จะ complete exceptionally และ join() โยน CompletionException ออกมา ควรกำหนด policy ว่าจะ fail-fast เชิงธุรกิจ, เก็บ partial results หรือแปลง error เป็นค่า ก่อนประกอบ futures

allOf ไม่ได้ยกเลิกงานพี่น้องให้เองเมื่อหนึ่งงานพัง และไม่ได้จำกัด concurrency หาก input มาจากรายการใหญ่ต้องควบคุม executor หรือแบ่ง batch เพิ่ม

Recap

  • เก็บ futures ต้นทางเพื่ออ่านค่าหลัง allOf
  • กำหนดลำดับผลลัพธ์ให้ชัด
  • ออกแบบ exception และ cancellation policy
  • จำกัด concurrency แยกจาก barrier