Python 3.14 os.reload_environ: รีเฟรช environment ได้ แต่ห้ามแข่งกับ thread อื่น
os.environ ถูกจับมาเป็น mapping ตอน import โมดูล os ครับ ถ้ามี native library หรือโค้ดนอก Python เปลี่ยน process environment โดยไม่แก้ mapping นี้ ค่าอาจไม่ตรงกัน Python 3.14 เพิ่ม os.reload_environ() เพื่ออ่าน environment ปัจจุบันกลับเข้ามาใหม่
WHY: ใช้เฉพาะขอบเชื่อมกับระบบภายนอก
แอปทั่วไปควรแก้ os.environ โดยตรง เพราะ Python จะเรียก putenv() ให้และ mapping ยังตรงกัน reload_environ มีไว้ตอนผู้เล่นอีกฝั่งแก้ state นอก mapping เช่น extension, embedding host หรือ native call เหมือนมีคนแก้สมุดเวรที่ห้องเครื่องโดยไม่บอกเคาน์เตอร์ เราจึงขอสำเนาใหม่เมื่อรู้ว่าการแก้เกิดขึ้นจริง
HOW: พิสูจน์ใน subprocess ที่แยกจากงานจริง
import os
import unittest
class ReloadEnvironTests(unittest.TestCase):
def test_reload_observes_putenv_change(self) -> None:
key = "SHOWKHUN_RELOAD_ENVIRON_TEST"
old = os.environ.get(key)
try:
os.putenv(key, "native-side")
self.assertNotEqual(os.environ.get(key), "native-side")
os.reload_environ()
self.assertEqual(os.environ.get(key), "native-side")
finally:
if old is None:
os.unsetenv(key)
os.environ.pop(key, None)
else:
os.environ[key] = old
if __name__ == "__main__":
unittest.main()
ตัวอย่างใช้ชื่อตัวแปรเฉพาะ test และคืนค่าหลังจบ ไม่มีการอ่านหรือพิมพ์ environment อื่น จึงไม่แตะ credential ของเครื่อง
จุดเสี่ยง: API นี้ไม่ thread-safe
เอกสารเตือนว่าการเรียกพร้อมกับ thread ที่อ่าน os.environ/os.getenv() อาจได้ผลว่างชั่วคราว นี่ไม่ใช่เมธอดที่ควรผูกกับ timer แล้วรีเฟรชทุกนาที ให้หยุด worker ที่เกี่ยวข้องหรือใช้ lock กลางครอบทั้ง reload และ read ที่ต้อง consistent
ทางออกที่มักดีกว่าคือส่ง configuration เป็น object immutable ให้ worker แล้วเปลี่ยนทั้ง object แบบ atomic เมื่อ reload config สำเร็จ Environment เหมาะกับ bootstrap มากกว่าระบบ dynamic configuration เพราะไม่มี schema, validation หรือ notification ในตัว
Recap
- ใช้
os.environโดยตรงสำหรับการแก้จาก Python - ใช้
reload_environเมื่อมีหลักฐานว่า native side เปลี่ยนค่า - ห้าม reload แข่งกับ thread ที่อ่าน environment
- ไม่ log environment ทั้งก้อน เพราะอาจมี secret