3 คะแนน โดย GN⁺ 5 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ส่วนขยาย durable function ที่จัดการ การลองใหม่, การตั้งเวลา, parallel fan-out, การแตกแขนงตามเงื่อนไข ภายใน PostgreSQL ได้ด้วย SQL DSL ขนาดเล็ก
  • ทำงานได้ด้วย Postgres และ background worker เท่านั้น โดยไม่ต้องมีคอนเทนเนอร์หรือบริการภายนอก
  • ทุกขั้นตอนบันทึกสถานะเป็นเช็กพอยต์ลงใน PostgreSQL ทำให้ กลับมาทำงานต่อจากจุดที่หยุดได้แม้เกิดแครช รีสตาร์ต หรือการเชื่อมต่อขาด
  • ไม่ต้องลงมือสร้างการจัดการคิว การติดตามสถานะ การกู้คืนจากแครช การประสานขั้นตอน และการลองใหม่เอง เพราะ เพียงเขียน SQL แล้ว orchestration engine จะจัดการให้
  • งานที่ถ้าทำเองต้องใช้ boilerplate มากกว่า 300 บรรทัด สามารถแทนที่ได้ด้วยการเรียก DSL เพียงครั้งเดียว และพร้อมใช้งานแบบโอเพนซอร์สทันทีบน PostgreSQL 17

ภาพรวมและคุณค่าหลัก

  • durable function ที่ทนต่อแครช (crash-proof) ซึ่งฝังอยู่ใน Postgres สำหรับจัด orchestration ของการลองใหม่ การตั้งเวลา parallel fan-out และการแตกแขนงตามเงื่อนไขด้วย SQL DSL ขนาดเล็ก
  • ทำงานได้ด้วย Postgres + background worker โดยไม่ต้องมีโครงสร้างพื้นฐานเพิ่ม ไม่ต้องใช้คอนเทนเนอร์หรือบริการภายนอกแยกต่างหาก
  • ทำหน้าที่เป็น orchestration engine ที่ดูแลทั้งการจัดการคิว การติดตามสถานะ การกู้คืนจากแครช การประสานขั้นตอน และการลองใหม่ทั้งหมด โดยผู้ใช้เพียงเขียน SQL

หากต้องสร้างโดยไม่มี pg_durable

  • หากต้องรันการ aggregate 3 รายการแบบขนานแล้วอัปเดตแดชบอร์ด พร้อมรองรับการลองใหม่และการกู้คืนจากแครช จะต้องใช้ boilerplate มากกว่า 300 บรรทัด
    • สิ่งที่ต้องสร้างเอง ได้แก่ การตั้งค่าและโครงแบบของคิว, การจัดการ worker และการ polling, การประมวลผลข้อความและการติดตามสถานะ, การจัดการข้อผิดพลาดและการลองใหม่, การประสานขั้นตอนแบบแมนนวล
    • โค้ดตัวอย่างมีทั้งตารางสถานะจำนวนมาก เช่น job_queue, job_results, job_state, workflow_steps, step_variables, scheduled_jobs รวมถึง polling worker, ความคืบหน้าของ workflow, การกู้คืนจากแครช, ตัวประสานงานการรันแบบขนาน, การส่งผ่านตัวแปร, การตั้งเวลา และฟังก์ชันสำหรับเก็บกวาด
    • การคำนวณ next_run สำหรับการตั้งเวลายังต้องเพิ่ม ไลบรารี cron parser ภายนอก อีกด้วย

หากสร้างด้วย pg_durable

  • งาน aggregate แบบขนานชุดเดียวกันพร้อมการอัปเดตแดชบอร์ดสามารถเขียนได้ด้วยการเรียก df.start() เพียงครั้งเดียว โดยใช้ โอเปอเรเตอร์ & สำหรับ fan-out และ ~> สำหรับ join
    • ตัวอย่าง: คิวรี 3 ชุดแตกแขนงทำงานแบบขนานก่อนจะมารวมกันที่ขั้น refresh dashboard เพื่อสร้างผลลัพธ์
    • ในตัวอย่างการรันจริง หลังรัน 3 ขั้นตอนแบบขนานแล้ว join จนถึง dashboard ready ใช้เวลาเพียง 1.9 วินาที และเสร็จสมบูรณ์แบบ durable
  • การจัดการคิว การติดตามสถานะ การกู้คืนจากแครช การประสานขั้นตอน และการลองใหม่ pg_durable จะจัดการทั้งหมด

คุณสมบัติหลัก

  • Durable by default

    • ทุกขั้นตอนบันทึกสถานะเป็น เช็กพอยต์ ลงใน PostgreSQL ทำให้ workflow อยู่รอดได้แม้เกิดแครช รีสตาร์ต หรือการเชื่อมต่อขาด
    • กลับมาทำงานต่อได้ตรงจากจุดที่หยุดไว้
  • Automatic retries

    • มี ตรรกะการลองใหม่ในตัว สำหรับงานที่ไม่เสถียร เมื่อขั้นตอนล้มเหลวจะลองใหม่เฉพาะขั้นนั้น ขณะที่ workflow ส่วนที่เหลือยังดำเนินต่อได้
    • ไม่ต้องมีโค้ดจัดการข้อผิดพลาดแบบแมนนวล
  • Full observability in SQL

    • สถานะของ workflow ทั้งหมดถูกเก็บไว้ใน ตารางของ Postgres ทำให้ตรวจดูประวัติการทำงาน ดูผลลัพธ์ของแต่ละขั้น และดีบักความล้มเหลวได้ด้วย SQL มาตรฐาน
    • ไม่ต้องใช้แดชบอร์ดภายนอก
  • Parallel execution

    • ใช้ โอเปอเรเตอร์ & หรือ df.join() เพื่อ fan-out งานที่เป็นอิสระจากกัน และรันขั้นตอนอย่าง aggregate, API call หรือ ETL พร้อมกันโดยมีการประสานอัตโนมัติ

รูปแบบงานที่สร้างได้

  • ETL Pipelines

    • เชื่อม cleanup → transform → load โดยรับประกันลำดับการทำงาน แต่ละขั้นจะรอขั้นก่อนหน้า และหยุด pipeline อย่างเป็นระเบียบเมื่อเกิดความล้มเหลว (~> sequence, |=> variables)
  • Parallel Aggregation

    • นับจำนวนผู้ใช้ + รวมรายได้ + ตรวจสอบสต็อกไปพร้อมกัน แตกแขนงด้วยหลายคิวรีแล้วรอให้ทั้งหมดเสร็จ (&, df.join())
  • Order Processing

    • จับค่า order ID แล้วส่งต่อไปยังขั้นตอนตรวจสอบ ประมวลผล และเสร็จสิ้น โดยตัวแปรไหลระหว่างขั้นตอนได้อัตโนมัติ (|=> capture, $var substitution, df.sleep())
  • Scheduled Jobs

    • polling API, archive records, sync ข้อมูลตาม cron schedule โดยลูปทำงานถาวรและยังอยู่รอดได้หลังการรีสตาร์ต (@> loop, df.wait_for_schedule())
  • Conditional Branching

    • ตรวจสอบงานที่รออยู่ จำนวนแถว หรือแฟล็กเพื่อแตกแขนงไปยังการประมวลผลหรือการข้าม โดย ตรรกะการแตกแขนงอยู่ใน SQL ไม่ใช่ในแอปพลิเคชัน (df.if(), ?> conditional)
  • Multi-step Validation

    • ดึงข้อมูล → ตรวจสอบ schema → ตรวจสอบ business rules → อนุมัติ/ปฏิเสธ โดยทุกขั้นมีเช็กพอยต์จึงไม่สูญเสียความคืบหน้าแม้เกิดความล้มเหลว
  • Database Maintenance

    • ตรวจจับปัจจัยที่ขัดขวาง autovacuum, table bloat และความเสี่ยง wraparound แล้วแสดงเพื่อให้ตรวจทาน ก่อนจะ แก้ไขอย่าง durable แม้มีการรีสตาร์ต หลังได้รับการอนุมัติ (?> conditional, df.wait_for_signal(), @> loop)
  • Azure Functions & HTTP

    • ใช้ df.http() เพื่อเรียก Azure Functions หรือ HTTPS endpoint ที่อนุญาตได้โดยตรงจาก SQL แล้วประมวลผลการ chunk เอกสาร การเสริมข้อมูลแถว และการจัดหมวดหมู่เรคคอร์ดแบบอินไลน์
  • Human-in-the-Loop Approval

    • อนุมัติงานทั่วไปโดยอัตโนมัติ และ หยุดพักงานที่มีความเสี่ยงสูงไว้จนกว่าจะได้รับสัญญาณอนุมัติจากมนุษย์ เช่น ใบแจ้งหนี้มูลค่าสูงหรือการดำเนินการแบบทำลายข้อมูล (df.wait_for_signal(), df.if())

การช่วยเขียนด้วย AI

  • หากอธิบาย workflow เป็น ภาษาอังกฤษแบบธรรมดา Copilot จะสร้าง durable-function SQL ที่ถูกต้องให้ โดยไม่ต้องเรียนรู้ไวยากรณ์ เพียงบอกสิ่งที่ต้องการ
  • ในรีโพซิทอรีมี agent skill ที่นำกลับมาใช้ซ้ำได้ชื่อ pg-durable-sql เพื่อสอน GitHub Copilot และเอเจนต์อื่น ๆ ให้สร้าง SQL ที่ถูกต้องสำหรับโอเปอเรเตอร์ การแทนที่ตัวแปร ลูป parallel join และอื่น ๆ

เปิดให้ใช้แบบโอเพนซอร์ส

  • ให้ใช้งานแบบโอเพนซอร์สเต็มรูปแบบ ไม่มี waiting list และไม่มี lock-in สามารถโคลนรีโพซิทอรี สร้าง และรันบน PostgreSQL ของตัวเองได้ทันที
  • ใช้ durable orchestration ได้ทั้งบนโน้ตบุ๊ก เซิร์ฟเวอร์ หรือคลาวด์

ตัวเลือกแบบ managed ของ Azure HorizonDB

  • Azure HorizonDB คือบริการ PostgreSQL บนคลาวด์ตัวใหม่ของ Microsoft ที่มี pg_durable ติดตั้งมาในตัว ช่วยให้คง durable function ที่เขียนไว้เดิมได้ พร้อมเพิ่มความสามารถด้านการสเกลระดับองค์กร ความปลอดภัย และ AI
    • ประสิทธิภาพเร็วขึ้นสูงสุด 3×, สตอเรจขยายอัตโนมัติได้สูงสุด 128 TB, compute scale-out สูงสุด 3,072 vCore
    • Microsoft Defender สำหรับตรวจจับภัยคุกคามแบบเรียลไทม์, Microsoft Entra ID สำหรับการจัดการตัวตน
    • Filtered DiskANN vector search, semantic ranking และการคัดสรรโมเดล AI ภายในฐานข้อมูล
    • Microsoft Fabric สำหรับ near real-time mirroring, การรวมกับ VS Code และการเชื่อมต่อ GitHub Copilot
  • AI pipeline ที่มีมาในตัว

    • HorizonDB ซ้อนทับ AI pipeline แบบ managed ครบวงจรไว้บนการรันแบบ durable ของ pg_durable โดยแต่ละขั้นมีเช็กพอยต์ ลองใหม่ได้ และปลอดภัยจากแครช
    • ลำดับขั้นตอน: Ingest(โหลดเอกสาร·ข้อมูล) → Chunk(แบ่งเนื้อหา) → Embed(สร้างเวกเตอร์) → Index(จัดเก็บใน DiskANN) → Serve(ค้นหา·จัดอันดับ)

1 ความคิดเห็น

 
GN⁺ 5 시간 전
ความคิดเห็นจาก Hacker News
  • ดูเหมือนว่า ปี 2026 จะเป็นปีของคิวบน Postgres: มีแนวทางอย่าง DBOS[0], pgQue[1] และเป็นเรื่องดีที่ชุมชนสร้างตัวเลือกแบบนี้ขึ้นมา
    แต่ในฐานะอดีตวิศวกรแอปพลิเคชัน ก็ยังชอบให้ตรรกะคิวอยู่ในโค้ดและใน Git มากกว่า อาจเปลี่ยนใจก็ได้ถ้ามีเครื่องมือที่เหมาะสม
    [0]: https://www.dbos.dev/
    [1]: https://github.com/NikolayS/pgque

    • มันอาจจะทำงานยากกว่า หรือแค่แตกต่างออกไป แต่ดูเหมือนจะยังขาด เอกสาร บทความที่ค้นหาเจอได้ ประสบการณ์ และเครื่องมือ
      อยากรู้ว่าจัดการเรื่องการควบคุมเวอร์ชัน การดีบัก การทดสอบ และการรีลีสกันอย่างไร การรวมทุกอย่างไว้ในที่เดียวเพื่อ data locality และทำให้สแตกเรียบง่ายขึ้นก็ดูดี แต่ก็ให้ความรู้สึกเหมือนสูญเสียองค์ความรู้ที่เป็นประโยชน์มากมายเกี่ยวกับวิธีทำให้ “ถูกต้อง”
    • เห็นด้วยกับประโยคที่ว่า “อยากให้ตรรกะคิวอยู่ในโค้ด” การกระทำที่ต้องทำกับข้อมูลเปลี่ยนบ่อยกว่าตัวข้อมูลเองมาก ดังนั้นการต้องทำ migration ทุกครั้งที่เปลี่ยนพฤติกรรมจึงฟังดูไม่สมเหตุสมผล
      นี่จึงเป็นเหตุผลที่เกลียดมากเวลาต้องสร้าง Postgres function แม้จะทำงานที่ซับซ้อนขึ้นมาอีกนิดเดียวบน Supabase อย่างไรก็ดี ที่สตาร์ตอัปก่อนหน้านี้เคยสร้างคิวงานง่าย ๆ เองบน Postgres และถ้ามีอะไรอย่าง pgQue ตอนนั้น ก็น่าจะได้ระบบที่ขัดเกลามากกว่านี้มาก
    • เป็นแฟนมาตั้งแต่ยุค Postgres 7 และเคยลองยัดทุกอย่างที่ทำได้เข้าไปใน PostgreSQL ในเชิงทดลอง แต่ อย่างน้อย ประสบการณ์นักพัฒนาและการสังเกตการณ์ระบบ ก็ยังไม่พร้อม
      ส่วน extension แบบ multi-master ก็ยังไม่ใช่เรื่องที่หยิบมาใช้ได้ทันทีและปลอดภัยเต็มร้อย เลยระวังที่จะใส่งานซับซ้อนที่เน้นการเขียนลงไป เพราะมันจะเร่งความจำเป็นในการขยายฐานข้อมูลให้มาถึงเร็วขึ้น
    • ในโปรเจ็กต์ที่มี DB trigger เราก็ เก็บโค้ด SQL ไว้ใน Git เพื่อจัดการเหมือนกัน
      บางครั้งก็ยัดมันเข้าไปใน Django migration เพื่อให้ตอนตั้งค่าเครื่องโลคัล trigger ถูกติดตั้งลงในฐานข้อมูลโลคัลด้วย
  • อันนี้มีกลิ่นของ stored procedure อยู่พอสมควร ทั้งทดสอบแบบ unit test ก็ยาก ควบคุมเวอร์ชันก็ยาก และ business logic ก็ไปซ่อนอยู่ในฐานข้อมูลจนกลายเป็น “สมองที่ซ่อนอยู่”
    ยังแยก noisy workload ได้ยาก ไม่มี observability และแรงกดดันด้านการสเกลก็กระจุกที่ Postgres ทั้งหมด โดยเฉพาะเรื่อง I/O อย่างการเรียก API ที่ดูอ่อนมาก มันโอเคสำหรับงานที่วิ่งอยู่แค่ในฐานข้อมูลโลคัล แต่ดูเหมือนกรณีใช้งานจะค่อนข้างแคบ

    • stored procedure ถ้าใช้อย่างถูกต้องก็ดีมาก การควบคุมเวอร์ชันทำได้ด้วยการต่อท้ายชื่อด้วย ID ที่เพิ่มขึ้นเรื่อย ๆ และถ้าต้องมี breaking change ก็แค่เพิ่ม ID พร้อมคงเวอร์ชันเก่าไว้จนกว่าจะเลิกใช้อย่างสมบูรณ์
      แน่นอนว่าต้องมีขั้นตอนอัปเกรดฐานข้อมูลที่ดีพอ ถ้าทีมปล่อยให้ใครก็ตามรัน SQL migration แบบสุ่มด้วยสิทธิ์ root ก็จะลำบากแน่
      ส่วน unit test ก็ทำได้เหมือนการทดสอบ SQL อื่น ๆ ทุกประการ แค่ต้องยกฐานข้อมูลขึ้นมาเท่านั้น ถ้าทดสอบ stored procedure ไม่ได้ ก็แปลว่าไม่มีทางทดสอบ SQL เองได้ ซึ่งนั่นต่างหากคือปัญหาจริง
      ทางเลือกแทน stored procedure ไม่ใช่การไม่ใส่ business logic ไว้ในฐานข้อมูลเลย แต่บ่อยครั้งกลับกลายเป็นการปล่อยให้ SQL กระจัดกระจายทั่ว codebase ทดสอบยาก ควบคุมเวอร์ชันและการห่อหุ้มก็แย่ แถมช้ากว่าโดยไม่จำเป็น
      เรื่อง observability นั้นก็จริงอยู่บ้าง เพราะการเจาะดูปัญหา SQL มักต้องลงแรงมากกว่าภาษาโปรแกรมส่วนใหญ่ แต่ถ้า stored procedure ทำให้เกิดปัญหา I/O และปัญหาการสเกล ก็แปลว่าใช้งานผิดวิธี เพราะถ้าใช้ถูกต้อง มันมักช่วยลด I/O ลงได้มากและทำให้สเกลดีขึ้นด้วยซ้ำ
  • ถ้าเข้าใจถูกต้อง Absurd ที่พัฒนาโดยผู้สร้าง Pi LLM harness ดูเหมือนจะพยายามลดการเข้าถึงฐานข้อมูลโดยตรงให้เหลือน้อยที่สุด ตอนนี้เพิ่งเริ่มตามดูหัวข้อนี้
    https://github.com/earendil-works/absurd

    • ขอแก้เล็กน้อย absurd ดูเหมือนจะเป็น โปรเจ็กต์ดั้งเดิมของ earendil ที่เริ่มมาก่อน Mario Zechner จะเข้าร่วมกับ earendil และก็ไม่เห็นชื่อเขาใน commit ด้วย
      แน่นอนว่าไม่ได้รู้รายละเอียดทั้งหมด เลยสงสัยจริง ๆ
  • ในหัวข้อ “ไม่ควรใช้เมื่อไร” มีคำว่า “เมื่อ workflow ส่วนใหญ่อยู่ข้างนอก Postgres และพาดผ่านหลายระบบต่างชนิดกัน” ถ้าอย่างนั้นก็ไม่เข้าใจว่าโปรเจ็กต์นี้จะเทียบกับอะไรอย่าง Temporal ได้อย่างไร
    เลยสงสัยว่าอาจกำลังเข้าใจข้อจำกัดที่คำแนะนำนี้สื่อผิดไปหรือไม่

    • เห็นด้วย ดูตัวอย่างที่ https://github.com/microsoft/pg_durable/blob/main/examples/i... แล้วก็ยังไม่ค่อยเข้าใจคุณค่าของโปรเจ็กต์นี้
      ในเชิงเทคนิคมันอาจเป็นความสำเร็จที่น่าสนใจ แต่การอ่าน SQL แบบนี้ค่อนข้างประหลาดทีเดียว
      SELECT df.start(
      @> (
      ($$SELECT ... FROM demo.invoices WHERE status = 'pending'$$ |=> 'inv')
      ~> df.if_rows('inv',
      $$UPDATE ... SET status = 'processing'$$
      ~> (df.http(...) |=> 'resp')
      ~> df.if($$SELECT $r.ok$$,
      -- classify, branch, wait for signal ...
      ),
      df.sleep(5)
      )
      ),
      'invoice-approval-pipeline'
      );
  • ที่บริษัทผูกอยู่กับ Azure และยังคงรอให้ Azure PostgreSQL ตามฟีเจอร์สมัยใหม่ให้ทันอยู่
    ตัวอย่างเช่น ใช้อันนี้ไม่ได้: https://www.paradedb.com/blog/hybrid-search-in-postgresql-th...
    และยังไม่รองรับเวกเตอร์มิติสูงมากด้วย การเปิดซอร์ส pg_durable นั้นก็ดีอยู่ แต่ก็อดคิดไม่ได้ว่าน่าจะเริ่มจากเพิ่มฟีเจอร์พื้นฐานที่บน AWS มีให้อยู่แล้วตามปกติก่อนไหม

    • ParadeDB เป็น AGPL เลยทำให้โดยทั่วไปผู้ให้บริการคลาวด์รายใหญ่ให้บริการได้ยาก อย่างไรก็ตาม บน Azure HorizonDB สามารถใช้ https://github.com/timescale/pg_textsearch ได้ และมีโอกาสสูงว่าจะเข้ามาใน Flex เร็ว ๆ นี้
      ขอเปิดเผยตรง ๆ ว่าผมเป็นผู้ดูแล pg_textsearch และตอนนี้อยู่ที่ Azure ส่วนที่พูดเรื่องการรองรับเวกเตอร์นั้น ผมยังไม่แน่ใจว่าเข้าใจถูกไหม ว่าคุณต้องการอะไรที่ไปไกลกว่า pgvector + diskann ที่ Azure มีให้หรือเปล่า
    • สำหรับการค้นหาเวกเตอร์ ดูเหมือนว่า Azure Cosmos DB จะเหมาะกว่านะ
    • คงพิจารณามาแล้วแหละ แต่สงสัยว่าทำไมถึงไม่สร้าง bare VM แล้วติดตั้ง Postgres เวอร์ชันล่าสุดไปเลย
    • ผมเป็น PM ที่ดูแลฟีเจอร์ AI ของ Postgres ในทีม Azure PG ฟีเจอร์ที่ขอมานั้นมีให้ใช้อยู่จริง และในช่วง 3–6 เดือนที่ผ่านมา มีความคืบหน้าไปมาก
      สำหรับ hybrid search (BM25 + เวกเตอร์) นั้น pg_search ของ ParadeDB ก็ไม่ใช่ฟีเจอร์เนทีฟของ AWS เช่นกัน และต้องโฮสต์เองบน EC2 ส่วน Azure PostgreSQL เราทำ pg_textsearch แบบเนทีฟไว้แล้ว ซึ่งให้โมเดลการจัดอันดับ BM25 แบบเดียวกัน และผู้มีส่วนร่วมหลักก็อยู่ในทีม Azure Postgres ตอนนี้
      เอกสาร: https://learn.microsoft.com/en-us/azure/horizondb/ai/full-te...
      เรื่องเวกเตอร์มิติสูงนั้นกลับเป็นด้านที่เรานำอยู่ด้วยซ้ำ pgvector ที่ใช้ HNSW มีข้อจำกัดที่ 2,000 มิติ แต่ Azure รองรับทั้ง pgvector สำหรับการจัดเก็บและค้นหาเวกเตอร์ และสำหรับเวิร์กโหลดขนาดใหญ่ที่มีมิติสูงก็มี pg_diskann ซึ่งเป็นดัชนีเวกเตอร์แบบกราฟของ Microsoft ให้ใช้ รองรับได้สูงสุด 16,000 มิติ และยังมีการกรองภายในดัชนีแบบขั้นสูงที่ประเมินเงื่อนไข WHERE ระหว่างการไล่กราฟ จึงไม่เสีย recall ในกรณีที่มีเงื่อนไขเลือกข้อมูลเฉพาะ
      pgvector: https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-...
      การรองรับมิติสูงของ DiskANN: https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-...
      ฟีเจอร์เหล่านี้ใช้งานได้แล้วบน Azure PostgreSQL โดยเฉพาะใน Azure HorizonDB Preview ถ้ามีเวิร์กโหลดเฉพาะเจาะจงก็สามารถลงรายละเอียดเพิ่มเติมได้
  • นี่ให้ความรู้สึกเหมือนเป็นวิธีแก้ที่ไม่ค่อยตรงจุดสำหรับปัญหาเก่าที่ ตัวจัดตารางเวลาแบบ DAG อย่าง Apache Airflow แก้กันมานานแล้ว
    แปลกดีว่าทำไมถึงอยากเก็บ control flow ไว้ในฐานข้อมูลแทนที่จะเก็บไว้ในโค้ด ไม่ได้จะดูถูกโปรเจกต์นะ แค่ยังไม่ค่อยเข้าใจ

    • Microsoft มีเฟรมเวิร์ก Durable Task[1] สำหรับงานลักษณะนี้อยู่แล้ว และสามารถรันเป็นบริการอิสระแบบโฮสต์เองได้เหมือน Temporal หรือจะรันแบบเซิร์ฟเวอร์เลสบน Azure Functions ก็ได้ ถ้าจำไม่ผิด มันยังออกมาก่อน Airflow กับ Temporal ด้วยซ้ำ
      โปรเจกต์นี้ดูเหมือนจะเน้น use case ที่เฉพาะกับฐานข้อมูลมากกว่า ข้อดีน่าจะเป็นการติดตามสถานะที่แน่นอนของงานได้จากในฐานข้อมูลเอง โดยไม่ต้องไล่เทียบทีละบรรทัดระหว่างล็อกของเวิร์กโฟลว์กับโค้ดเบส นอกจากนี้ภาระงานและความหน่วงก็น่าจะน้อยกว่า และในเชิงปฏิบัติการก็น่าจะลดจำนวนคอมโพเนนต์ที่ต้องรันลงได้หนึ่งตัว
      [1] https://learn.microsoft.com/en-us/azure/durable-task/common/...
    • เครื่องมือภายนอกอย่าง Airflow ไม่สามารถรับรู้ ภาระของฐานข้อมูล ได้ ถ้านักพัฒนายิง worker พร้อมกัน 200 ตัวเข้าใส่ฐานข้อมูล เวิร์กโหลดอื่นก็อาจได้รับผลกระทบ
      ในทางกลับกัน วิธีนี้แม้ตอนนี้จะยังดูไม่ได้ทำแบบนั้น แต่ก็มีศักยภาพที่จะปรับตัวเองได้โดยอาศัย feedback ด้านประสิทธิภาพแบบเกือบเรียลไทม์ โดยไม่ต้องเสียค่าใช้จ่ายจาก round-trip latency
  • แม้อ่านเอกสารและตัวอย่างแล้ว ก็ยังมีบางอย่างที่ไม่ชัดเจน อยากรู้ว่า df.wait_for_schedule() ทำงานอย่างไร
    ถ้าเรียกจากแอปพลิเคชัน มันเป็นแบบ idempotent หรือไม่ ถ้ารันสองครั้งด้วยพารามิเตอร์เดียวกันจะเกิด tick สองครั้งไหม ไม่แน่ใจว่ามันควรถูกเรียกด้วยตนเองจาก query console แค่ครั้งเดียว หรือรันเป็นส่วนหนึ่งของสคริปต์ migration
    และสงสัยด้วยว่า timed_out ในตัวอย่าง[0] เป็นค่าคงที่ตายตัวที่คืนเมื่อหมดเวลาหรือไม่ เรื่องการจัดการ error หรือ exception ก็ยังมองไม่เห็นชัดนัก
    [0] https://github.com/microsoft/pg_durable/blob/main/examples/i...

    • เมื่อเรียก df.start() จะเป็นการสร้าง durable function และเริ่มรันมันพร้อมกัน การเรียกนี้จะคืน instance ID ที่แทนการรันนั้นมาให้ และสามารถใช้สำหรับอ้างอิงการรันนั้นในภายหลังได้
      ภายใน durable function นี้จะมีการเรียก df.wait_for_signal() ซึ่งคำสั่งเรียกนี้จะถูกรันเพียงครั้งเดียวอย่างแน่นอนภายใน function instance นั้น จึงไม่สามารถเกิดการซ้ำได้. ตัว df.start() เองอาจซ้ำได้ถ้าการเรียกหมดเวลาแล้วถูกรันใหม่ แต่ในกรณีนั้นจะมี function instance คนละตัวถูกสร้างขึ้น
      ถ้าเกิดข้อผิดพลาดที่ไม่ได้ถูกจัดการระหว่างการรัน SQL function instance จะล้มเหลว และในสถานะก็จะแสดงข้อผิดพลาดที่เกิดขึ้นจริงตามเดิม
  • ช่วยอธิบายได้ไหมว่าทำไมถึงควรใช้สิ่งนี้แทน orchestration tool ที่อยู่นอกฐานข้อมูล อ่านทั้ง README และตัวอย่างแล้วก็ยังไม่ค่อยเข้าใจ

    • ถ้าใช้ snapshot PITR ของฐานข้อมูล ก็จะกู้คืน durable task ทั้งหมดกลับมาพร้อมกันถึงจุดเวลานั้นด้วย
      ไม่จำเป็นต้องซิงก์แบ็กอัปกับองค์ประกอบอื่นที่อยู่ใน data store เดียวกัน จึงเหมาะกับ ETL pipeline หรืองานแบบ state machine และถ้า ETL ส่วนใหญ่เป็น SQL ก็ยิ่งได้ประโยชน์จากการที่งานจริงรันอยู่บนเซิร์ฟเวอร์เดียวกัน
    • จากมุมมองของผู้มีส่วนร่วม ลูกค้า Postgres ของ Microsoft แบ่งออกได้ค่อนข้างพอ ๆ กันเป็นสองกลุ่ม กลุ่มที่อยากทำทุกอย่างให้มากที่สุดเท่าที่จะทำได้ในฐานข้อมูล กับกลุ่มที่อยากเก็บแอปพลิเคชันและการประมวลผลไว้นอกฐานข้อมูล
    • ถ้าในสถาปัตยกรรม ฐานข้อมูลเป็น องค์ประกอบแบบเก็บสถานะ เพียงตัวเดียว มันก็สะดวกได้ในบางครั้ง
      เมื่อสถานะทั้งหมดอยู่ในฐานข้อมูลเดียวกัน โอกาสที่จะได้แบ็กอัปที่สอดคล้องกันก็สูงขึ้นด้วย
    • มันสามารถผสานเข้ากับ application workflow ได้ดี เช่น แสดงความคืบหน้าผ่านลิงก์ถาวรในแอปฝั่งฟรอนต์เอนด์ สร้าง workflow ที่ทำงานต่อได้แม้แอปจะรีสตาร์ต และไม่ต้องเพิ่มองค์ประกอบ infrastructure อีกตัว
      ที่ https://transport.data.gouv.fr ก็ใช้ Postgres ในลักษณะนั้น และมันมีประโยชน์กับแอป Elixir ที่มีการประมวลผลค่อนข้างมาก ยังไม่รู้จัก pg_durable ดีพอ แต่เคยใช้หรือทำโซลูชันคล้าย ๆ กันมาก่อน จึงเข้าใจความคิดนี้ได้
  • ฐานข้อมูลก็เป็นหนึ่งใน infrastructure ที่ขยายระบบได้ยากที่สุดอยู่แล้วไม่ใช่หรือ ทำไมถึงยังอยากเอา งานที่รันยาวนาน ไปวางทับไว้อีกก็ไม่เข้าใจ

    • การรันงานที่ใช้เวลานานใน Postgres ไม่ใช่เรื่องใหม่เลย ตัวอย่างเช่น pg_cron
      ท้ายที่สุดแล้ว workload แบบนี้ก็คืองานที่จะต้องรันกับฐานข้อมูล ไม่ว่าจะถูก trigger โดยองค์ประกอบภายนอกหรือไม่ก็ตาม ใน data หรือ AI pipeline ก็เริ่มพบการให้ฐานข้อมูลส่ง HTTP query มากขึ้น เพื่อหลีกเลี่ยงการไปกลับและจุดล้มเหลวที่เกิดจากการมีองค์ประกอบเพิ่มขึ้น อย่างไรก็ตาม จะย้ายการประมวลผลไปหาข้อมูล หรือจะย้ายข้อมูลไปหาการประมวลผล ก็ยังเป็นทางเลือกด้านการออกแบบที่ถกเถียงกันมาก
  • มันให้ความรู้สึกเหมือนเป็น https://en.wikipedia.org/wiki/Inner-platform_effect อีกอันหนึ่ง ที่อาจไม่จำเป็นเลย ถ้าภาษาโปรแกรมหรือ VM ยอดนิยมรองรับ determinism, การรันทีละขั้นที่วัดและควบคุมได้, การพักสถานะของ runtime ชั่วคราว, การ serialize/deserialize และ resume ได้อยู่แล้ว