Scoped Values ขึ้น final ใน JDK 25: ส่ง requestId แบบอ่านอย่างเดียวข้ามเธรดลูก
น้องกายEngineering
เคยใช้ ThreadLocal เก็บ requestId แล้วลืมเคลียร์จนค่าเก่าโผล่ใน request ถัดไปไหมครับ
ใน JDK 25 Scoped Values ขึ้นสถานะ final ตาม JEP 506 (หลังผ่าน preview หลายรอบ) — ให้ส่งค่าอ่านอย่างเดียวลงในขอบเขตเมธอดและเธรดลูก โดยไม่ต้องยัดพารามิเตอร์ทุกชั้น
ต่างจาก ThreadLocal แบบย่อ:
- ค่าเป็น immutable ในขอบเขต
- อายุสั้นตาม block ที่
where(...).run(...) - คู่กับ virtual threads + structured concurrency ได้ดี เพราะไม่คัดลอกกอง mutable ใหญ่
เรามีบทความแนวคิด preview ไว้ก่อนแล้ว รอบนี้เน้นว่าไม่ต้องเปิด preview flag สำหรับ Scoped Values ใน 25 แล้ว
บล็อกด้านล่างเป็น fragment สำหรับอ่านแนวคิด (ไม่ใช่ suite ที่รันใน CI นี้)
// Conceptual final API shape (JDK 25+)
// private static final ScopedValue<String> REQUEST_ID = ScopedValue.newInstance();
// ScopedValue.where(REQUEST_ID, "req-42").run(() -> handler());
Recap
- อ่าน JEP 506
- วางแผนย้าย request context จาก ThreadLocal ที่มีปัญหา cleanup
- ใช้คู่ Structured Concurrency เมื่องานลูกต้องเห็นบริบทเดียวกัน
- อย่าเก็บ state ที่ต้องเขียนทับบ่อยใน ScopedValue — มันออกแบบมาให้อ่าน