นากกายตั้งนาฬิกาจับเวลาข้างกล่องงานบนโต๊ะมิ้นต์

Java CompletableFuture.orTimeout: ตัดงานช้าด้วยหมดเวลาในตัว

น้องกายEngineering

เคยรอ Future จนสปินไหม ผมใช้ orTimeout ให้มันล้มเองเมื่อเกินเวลาครับ

ตามเอกสาร Java เมธอดนี้ทำให้ CompletableFuture เสร็จแบบผิดปกติด้วย TimeoutException ถ้ายังไม่เสร็จภายในเวลาที่กำหนด (มีตั้งแต่ Java 9)

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class Main {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> slow = new CompletableFuture<>();
        CompletableFuture<String> guarded = slow.orTimeout(50, TimeUnit.MILLISECONDS);

        boolean timedOut = false;
        try {
            guarded.get();
        } catch (ExecutionException ex) {
            timedOut = ex.getCause() instanceof TimeoutException;
        }
        assert timedOut : "expected TimeoutException cause";

        CompletableFuture<String> fast = CompletableFuture.completedFuture("ok")
                .orTimeout(1, TimeUnit.SECONDS);
        assert "ok".equals(fast.get());
    }
}

orTimeout ไม่ได้ยกเลิกเธรดพื้นหลังให้อัตโนมัติเสมอ ถ้าว่างานจริงกินทรัพยากร ให้ผูกการยกเลิกเองหรือใช้ API ที่รองรับ interrupt ตามเคส

Recap

  • ใส่ orTimeout กับ I/O หรืองานภายนอกที่อาจค้าง
  • ตรวจว่าสาเหตุเป็น TimeoutException ใน ExecutionException
  • วางแผนยกเลิกงานพื้นหลังแยกถ้าจำเป็น
  • ทดสอบทั้งเคสทันและเคสหมดเวลา