2 คะแนน โดย GN⁺ 2023-09-12 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เมื่อวันที่ 28 สิงหาคม 2023 ความขัดข้องของ FPRSA-R ของ NATS ผู้ให้บริการควบคุมจราจรทางอากาศของสหราชอาณาจักร ทำให้เที่ยวบินถูกยกเลิกมากกว่า 2,000 เที่ยว และประเมินว่ามีค่าใช้จ่ายมากกว่า 100 ล้านปอนด์
  • แผนการบินที่จุดชนวนความวุ่นวายเป็น แผนที่ถูกต้อง ซึ่ง Eurocontrol IFPS ยอมรับแล้ว และระบบของ NATS พยายามเทียบข้อมูล ADEXP กับเส้นทาง ICAO4444 เพื่อดึงส่วนที่อยู่ในน่านฟ้าสหราชอาณาจักรออกมา
  • สาเหตุโดยตรงคือกรณีที่เวย์พอยต์สองจุดซึ่งอยู่ต่างพื้นที่ทางภูมิศาสตร์มีตัวระบุเดียวกัน โดย FPRSA-R จับคู่ ตัวระบุซ้ำ ที่ผิดเป็นจุดออกจากน่านฟ้า จึงไม่สามารถสร้างช่วงของสหราชอาณาจักรที่ถูกต้องได้
  • ระบบหลักและระบบสำรองประมวลผลแผนการบินเดียวกันด้วยลอจิกเดียวกัน แล้วต่างเกิด critical exception และเข้าสู่ maintenance mode ภายใน 20 วินาที ทำให้การประมวลผลอัตโนมัติหยุดลง
  • เครื่องบินยังคงได้รับการควบคุมอย่างปลอดภัย แต่โหมดความล้มเหลวที่แผนการบินเพียงรายการเดียวทำให้ระบบประมวลผลอัตโนมัติทั้งหมดหยุดลง การทดสอบที่ไม่เพียงพอ และขั้นตอนกู้คืนที่พึ่งพา log ระดับต่ำ ยังคงเป็นประเด็นปัญหา

ขนาดของเหตุขัดข้อง NATS เมื่อวันที่ 28 สิงหาคม 2023

  • NATS ผู้ให้บริการควบคุมจราจรทางอากาศของสหราชอาณาจักร ประสบปัญหาทางเทคนิคครั้งใหญ่เมื่อวันที่ 28 สิงหาคม 2023
  • อ้างอิงตาม BBC มีเที่ยวบินถูกยกเลิกมากกว่า 2,000 เที่ยว และประเมินว่ามีค่าใช้จ่ายมากกว่า 100 ล้านปอนด์
  • เหตุขัดข้องอาจส่งผลกระทบต่อผู้คนหลายแสนคน
  • รายงานข่าวช่วงแรกพูดถึงความเป็นไปได้ของ “แผนการบินที่ผิดพลาด” หรือ “ความผิดพลาดของสายการบินฝรั่งเศส” แต่แผนการบินที่ก่อปัญหาเป็นแผนการบินที่สอดคล้องกับ ICAO4444 ซึ่ง Eurocontrol IFPS ยอมรับแล้ว
  • ต่อมาเที่ยวบินจริงที่จุดชนวนเหตุขัดข้องถูกระบุว่าเป็น French Bee FBU731 ซึ่งบินจาก LAX/KLAX ไปยัง ORY/LFPO

เส้นทางที่แผนการบินไปถึง NATS

  • สายการบินส่งแผนการบินไปยัง IFPS ของ Eurocontrol
    • เมื่อ IFPS ยอมรับแผนการบินแล้ว หลังจากได้รับอนุญาตจากหอบังคับการสนามบินต้นทาง เครื่องบินจึงสามารถขึ้นบินได้
    • ในขั้นตอนนี้ไม่จำเป็นต้องมี input จาก NATS
  • IFPS ส่งต่อแผนการบินไปยังผู้ให้บริการเดินอากาศที่เกี่ยวข้อง
    • NATS ต้องได้รับแผนการบินอย่างน้อย 4 ชั่วโมงก่อนที่เครื่องบินจะเข้าสู่น่านฟ้าสหราชอาณาจักร
    • ระยะเวลา 4 ชั่วโมงนี้ทำหน้าที่เป็น buffer สำหรับแก้ปัญหาในการประมวลผล
  • ในการปฏิบัติการ En-route ของ NATS ที่ Swanwick Centre ข้อมูลจะถูกส่งต่อไปยัง FPRSA-R
    • FPRSA-R แปลงข้อมูลรูปแบบ ADEXP ที่ได้รับจาก IFPS ให้เป็นรูปแบบที่เข้ากันได้กับ UK National Airspace System หรือ NAS
    • NAS เป็นระบบประมวลผลข้อมูลการบินที่มีข้อมูลน่านฟ้าและเส้นทางที่เกี่ยวข้อง

ความแตกต่างระหว่าง ICAO4444 กับ ADEXP

  • แผนการบิน ICAO4444 เป็นรูปแบบที่เครื่องอ่านได้ และหากจำเป็นมนุษย์ก็อ่านได้ด้วย
    • ส่วนเส้นทางมีความเร็ว ระดับความสูง เวย์พอยต์ ชื่อเส้นทาง และตัวบ่งชี้การบินตรง เช่น DCT
    • ตัวอย่างเช่น N0440 หมายถึง 440 นอต และ F310 หมายถึง Flight Level 310
  • IFPS แปลงแผนการบิน ICAO4444 เป็นรูปแบบ ADEXP แล้วส่งต่อ
    • ADEXP มีแผนการบิน ICAO4444 เดิม พร้อมเวย์พอยต์ทางภูมิศาสตร์เพิ่มเติมสำหรับเส้นทางในภูมิภาคยุโรป
    • สำหรับเที่ยวบินที่ไม่ลงจอดในสหราชอาณาจักรแต่บินผ่านน่านฟ้าสหราชอาณาจักร อาจรวมเวย์พอยต์ที่จำเป็นสำหรับการเดินทางหลังออกนอกสหราชอาณาจักรด้วย
  • RTEPTS ของ ADEXP มีรายละเอียดระดับความสูงและเวลาผ่านโดยประมาณของแต่ละเวย์พอยต์มากกว่า
    • เส้นทาง ICAO อาจมีเวย์พอยต์ 9 จุด แต่รายการขยายของ ADEXP อาจมีเวย์พอยต์ 21 จุด
    • จุดต้นทางและปลายทางของเส้นทาง ICAO อยู่ใน field แยกต่างหาก จึงไม่รวมซ้ำในรายการเส้นทาง

เวย์พอยต์ซ้ำที่ทำให้เกิดเหตุขัดข้อง

  • รายการเวย์พอยต์ ADEXP ที่เป็นปัญหามีเวย์พอยต์สองจุดซึ่งต่างพื้นที่ทางภูมิศาสตร์แต่มี designator เดียวกัน
    • แม้ ICAO และหน่วยงานอื่น ๆ จะพยายามลบชื่อเวย์พอยต์ที่ไม่เป็นเอกลักษณ์ออกไป แต่ทั่วโลกยังคงมีชื่อซ้ำอยู่
    • มาตรฐานล่าสุดกำหนดว่าเวย์พอยต์ที่มีตัวระบุเดียวกันต้องอยู่ห่างกันมากทางภูมิศาสตร์
    • ในเหตุการณ์นี้ เวย์พอยต์ทั้งสองอยู่นอกสหราชอาณาจักร จุดหนึ่งอยู่ช่วงต้นของเส้นทาง อีกจุดหนึ่งอยู่ช่วงท้ายของเส้นทาง และห่างกันประมาณ 4,000 ไมล์ทะเล
  • ในแผนการบินแบบขยายของเที่ยวบิน FBU731 ที่ระบุได้จริง มีเวย์พอยต์ชื่อ DVL ปรากฏสองครั้ง
    • จุดหนึ่งคือ Devil’s Lake ในรัฐวิสคอนซิน สหรัฐฯ
    • อีกจุดหนึ่งคือ Deauville ใน Normandy ประเทศฝรั่งเศส
    • จุดหลังถูกสรุปว่าเกิดขึ้นในช่วงท้ายของเที่ยวบินจากกระบวนการขยายเส้นทาง UN859

ขั้นตอนการประมวลผลของ FPRSA-R และจุดที่ล้มเหลว

  • FPRSA-R ค้นหา จุดเข้า น่านฟ้าสหราชอาณาจักรจากข้อมูลเวย์พอยต์ ADEXP โดยเริ่มจากต้นรายการ
  • จากนั้นค้นหา จุดออก จากน่านฟ้าสหราชอาณาจักร แล้วจึงพยายามหาช่วงที่สอดคล้องกันในส่วน ICAO4444
  • เส้นทาง ICAO ไม่จำเป็นต้องมีจุดออกจากน่านฟ้าเสมอไป
    • ซอฟต์แวร์ถูกออกแบบให้หากจุดออกไม่มีอยู่ในเส้นทาง ICAO ให้ใช้จุดถัดไปที่อยู่ใกล้ในไฟล์ ADEXP เพื่อค้นหาใหม่
  • ในเหตุการณ์นี้ ซอฟต์แวร์ไล่ตามเวย์พอยต์ถัด ๆ ไปใน ADEXP จนพบ ตัวระบุซ้ำ ที่มีอยู่ในเส้นทาง ICAO
    • แต่ตัวระบุนั้นไม่ใช่เวย์พอยต์หลังจุดออกจริงจากน่านฟ้าสหราชอาณาจักร หากเป็นเวย์พอยต์อีกจุดหนึ่งทางภูมิศาสตร์ที่อยู่ช่วงต้นของเส้นทาง
    • ผลคือ ลำดับหรือช่วงระหว่างจุดเข้าและจุดออกไม่ถูกต้อง จึงไม่สามารถดึงช่วง ICAO ที่สอดคล้องกับน่านฟ้าสหราชอาณาจักรได้
  • รายงานของ NATS ระบุจุดนี้เป็น root cause ของเหตุการณ์ และสรุปว่าสามารถตัดปัจจัยด้านไซเบอร์ออกได้

เหตุใดระบบหลักและระบบสำรองจึงหยุดพร้อมกัน

  • ซอฟต์แวร์ที่มีความสำคัญต่อความปลอดภัยถูกออกแบบให้ย้ายไปยังสถานะที่ต้องมีการแทรกแซงด้วยมือ เมื่อไม่สามารถดำเนินการต่อได้อย่างปลอดภัย
  • ระบบหลักของ FPRSA-R ตัดสินว่าไม่สามารถรับประกันความถูกต้องของข้อมูลในแผนการบินได้ จึงทำให้เกิด critical exception
    • เขียน log file ลงใน system log
    • เข้าสู่ maintenance mode
    • ระบบ C&M ตรวจพบว่าระบบหลักไม่พร้อมใช้งานอีกต่อไป
  • ระบบสำรองถูกออกแบบมาให้รับช่วงประมวลผลต่อเมื่อระบบหลักขัดข้อง
    • อยู่บนฮาร์ดแวร์แยก แหล่งจ่ายไฟแยก และ data feed แยก
    • แต่ใช้ลอจิกเดียวกันกับแผนการบินเดียวกัน และให้ผลลัพธ์เดียวกันคือเกิด critical exception
  • ตั้งแต่รับข้อความ ADEXP จนทั้งระบบหลักและระบบสำรองเข้าสู่ maintenance mode ใช้เวลา น้อยกว่า 20 วินาที
  • เวลา 08:32 การประมวลผลแผนการบินอัตโนมัติหยุดลง และหลังจากนั้นจำเป็นต้องป้อนแผนการบินด้วยมือภายใน buffer 4 ชั่วโมง

ขั้นตอนกู้คืนและผลกระทบต่อการปฏิบัติการ

  • ทีมสนับสนุน 1st Line รับรู้เหตุขัดข้องผ่านระบบ C&M เฉพาะทาง ระบบ C&M ส่วนกลาง และ feedback จากทีมปฏิบัติการ
  • การตอบสนองเบื้องต้นคือขั้นตอนกู้คืนมาตรฐาน โดยรีสตาร์ต subsystem ผ่านระบบ C&M ส่วนกลาง
    • ความพยายามกู้คืนหลายครั้งล้มเหลว
    • ทีมวิศวกรรม 2nd Line เข้ามาเกี่ยวข้อง และสนับสนุนวิศวกรภาคสนามผ่านลิงก์วิดีโอทางไกล
  • เมื่อ 1st Line และ 2nd Line ไม่สามารถกู้คืนบริการหรือระบุสาเหตุที่แน่ชัดได้ จึงขอความช่วยเหลือจาก Technical Design team และผู้ผลิต subsystem
  • ผู้ผลิตระบุแผนการบินที่ดูเหมือนจะก่อเหตุขัดข้องผ่านการวิเคราะห์ log ซอฟต์แวร์ระดับต่ำ
    • หลังจากทำความเข้าใจแผนการบินดังกล่าวแล้ว จึงให้ขั้นตอนที่ถูกต้องในการกู้คืนระบบอย่างควบคุมและปลอดภัย
  • เมื่อเกิดเหตุขัดข้อง มีขั้นตอนป้อนข้อมูลด้วยมือและประสานงานด้วยมือระหว่างภาคส่วนอยู่แล้ว แต่เมื่อเปลี่ยนไปใช้ขั้นตอนด้วยมือ จำเป็นต้องใช้ข้อจำกัดด้านการควบคุมจราจรทางอากาศเพื่อลดปริมาณการจราจรของสหราชอาณาจักร

Frequentis AG และ FPRSA-R

  • Subsystem FPRSA มีอยู่ใน NATS มาหลายปี และในปี 2018 ระบบเดิมถูกแทนที่ด้วยฮาร์ดแวร์และซอฟต์แวร์ใหม่ของ Frequentis AG
  • Frequentis AG เป็นบริษัทออสเตรีย และเป็นหนึ่งในซัพพลายเออร์ระบบควบคุมจราจรทางอากาศ
  • ผลิตภัณฑ์ ATC ของผู้ผลิตรายนี้เป็นที่ทราบว่าใช้งานอยู่ในประมาณ 150 ประเทศ และมีสถานะระดับโลกในด้านการจัดการข้อมูลการบินและระบบประมวลผลข้อความ
  • ในหน้า careers ของ Frequentis AG มี Ada, C++, Java, Python ปรากฏในบริบทที่เกี่ยวข้องกับระบบควบคุมจราจรทางอากาศ โดย Java พบเห็นบ่อยที่สุด

บั๊กซอฟต์แวร์และปัญหาการทดสอบ

  • FPRSA-R ไม่สามารถดึงช่วง ICAO ที่สอดคล้องกับน่านฟ้าสหราชอาณาจักรจากแผนการบินที่ถูกต้องซึ่ง IFPS ยอมรับแล้ว
  • ตัวระบุเวย์พอยต์ไม่ได้เป็นเอกลักษณ์ทั่วโลก และนี่เป็นปัญหาที่ทราบกันดี
    • หากเวย์พอยต์ซ้ำอยู่ห่างกันมาก แผนการบินทั่วไปอาจยังไม่กำกวม
    • แต่ซอฟต์แวร์ควรจัดการเงื่อนไขนี้ได้อย่าง robust
  • NATS ระบุว่าสามารถพิจารณาผ่านรัฐบาลสหราชอาณาจักรเรื่องการลบชื่อเวย์พอยต์ซ้ำจำนวนน้อยที่เกี่ยวข้องกับเหตุการณ์นี้ออกจากชุดข้อมูลทั่วโลกที่ ICAO ดูแล
  • Martin Rolfe ซีอีโอของ NATS กล่าวกับ BBC ว่าเหตุการณ์นี้มีโอกาสเกิด “1 ใน 15 ล้าน”
    • เขากล่าวว่าระบบดังกล่าวเริ่มใช้งานในปี 2018 และตั้งแต่นั้นได้ประมวลผลแผนการบินไปแล้ว 15 ล้านรายการ
  • สำหรับระบบที่มีความสำคัญต่อความปลอดภัย ขั้นตอนประมวลผลแผนการบิน โดยเฉพาะขั้นตอนสำคัญอย่างการดึงช่วงของสหราชอาณาจักร ควรถูกทดสอบ
    • การทดสอบที่ไม่ได้คำนึงถึงชื่อเวย์พอยต์ซ้ำอาจไม่สามารถเผยบั๊กนี้ได้
    • fuzzing ซึ่งป้อนแผนการบินแบบสุ่มจำนวนมาก อาจช่วยค้นหา input ที่ทำให้ระบบเข้าสู่โหมดล้มเหลวที่ไม่ดีได้

ปัญหาของโหมดความล้มเหลว

  • แผนการบินเพียงรายการเดียวทำให้ระบบประมวลผลอัตโนมัติ FPRSA-R ทั้งหมดหยุดลง และส่งผลให้ไม่มีแผนการบินใดถูกประมวลผลแบบอัตโนมัติ
  • โหมดความล้มเหลวที่ดีกว่าคือส่งแผนการบินรายการเดียวที่มีปัญหาไปยัง queue ช้าที่แยกไว้ เพื่อให้มนุษย์ประมวลผลด้วยมือ
  • NATS ระบุว่า ในมาตรการที่กำลังดำเนินการอยู่หรือดำเนินการเสร็จแล้ว จะเพิ่มตัวกรองข้อความเฉพาะใน data flow ระหว่าง IFPS กับ FPRSA-R เพื่อกรองแผนการบินที่ตรงกับเงื่อนไขซึ่งก่อเหตุการณ์นี้
  • เมื่อ FPRSA-R หยุดทำงาน แผนการบินที่เกี่ยวข้องถูกระบุได้จาก log ซอฟต์แวร์ระดับต่ำเท่านั้น
    • หากข้อผิดพลาดในการประมวลผลแผนการบินเฉพาะรายการในระบบประมวลผลแผนการบินทำให้ทั้งระบบหยุดลง ควรมีการแจ้งเตือนไปยังทีม monitoring ทันทีโดยรวมแผนการบินดังกล่าวไว้ด้วย
  • NATS ระบุว่าได้จัดทำคำแนะนำการปฏิบัติการเพื่อกู้คืน FPRSA-R ได้อย่างรวดเร็วหากสถานการณ์เดียวกันเกิดซ้ำ และผู้ปฏิบัติงานด้านเทคนิคได้รับการฝึกให้ทำตามขั้นตอนใหม่แล้ว
    • การ monitoring ที่เพิ่มขึ้นและผู้เชี่ยวชาญด้านวิศวกรรมเพิ่มเติมจะคอยกำกับดูแลกิจกรรมด้วย

ความเป็นไปได้ของการใช้ formal verification

  • ไม่มีร่องรอยชัดเจนว่ามีการใช้ formal verification ในขั้นตอนและระบบที่เกี่ยวข้องกับเหตุการณ์นี้ และรายงานก็ไม่ได้กล่าวถึง
  • formal verification หรือ model checking อาจช่วยลดบั๊กประเภทนี้ได้
  • อย่างไรก็ตาม การทำ formal verification แบบ end-to-end สำหรับระบบขนาดใหญ่ยังอยู่ในระยะเริ่มต้น และแม้จะใช้ formal verification บางส่วน ก็ยังมีความเป็นไปได้ที่โค้ดที่มีข้อบกพร่องจะเข้าสู่สภาพแวดล้อมปฏิบัติการ
  • ต้องรอผลการสอบสวนขั้นสุดท้ายจึงจะทราบมากขึ้นว่าจริง ๆ แล้วมีการใช้วิธีตรวจสอบแบบใด

ความปลอดภัยและรายงานสาธารณะ

  • เครื่องบินในน่านฟ้าสหราชอาณาจักรยังคงปลอดภัยตลอดเหตุการณ์
    • ผู้ควบคุมจราจรทางอากาศที่มีประสบการณ์เฝ้าติดตามเครื่องบินผ่านแผนการบินที่ทราบอยู่แล้ว วิทยุ เรดาร์ และการมองเห็น
    • ผลลัพธ์จึงไม่ใช่ความเสี่ยงต่อชีวิต แต่เป็นสถานการณ์ที่เที่ยวบินขึ้นบินได้ลดลงมาก หรือจำเป็นต้องบินอ้อมเพื่อหลีกเลี่ยงน่านฟ้าสหราชอาณาจักร
  • NATS รักษาความปลอดภัยด้วยการดำเนินมาตรการลดจำนวนเที่ยวบิน
  • รายงานที่เผยแพร่มีความโปร่งใสและละเอียดพอสมควร และการรายงานลักษณะนี้มีความสำคัญต่อโครงสร้างพื้นฐานสำคัญ
  • Michael O’Leary จาก Ryanair วิจารณ์รายงานดังกล่าวว่าเป็น “rubbish” และกล่าวว่ารายงานลดทอนผลกระทบต่ออุตสาหกรรมการบิน แต่ก็มีการประเมินว่า scope ของรายงานเบื้องต้นไม่ได้อยู่ที่การวิเคราะห์ระดับความล้มเหลวของ NATS

แนวทางการทำ implementation ให้ robust ขึ้น

  • ปัญหาคือการจัดการเวย์พอยต์ของสอง sequence
    • ADEXP: รายการเวย์พอยต์ทั้งหมด
    • ICAO: subsequence ของเวย์พอยต์ ADEXP
  • เนื่องจากแผน ICAO ไม่จำเป็นต้องมีจุดเข้า·ออกน่านฟ้า งานค้นหาช่วงต่อเนื่องที่เล็กที่สุดของ ICAO ซึ่งสอดคล้องกับน่านฟ้าสหราชอาณาจักรจึงไม่ง่าย
  • ปัญหาของอัลกอริทึมที่ผิดคือการจัดการ pointer ที่ชี้ไปยังข้อมูล ICAO และ ADEXP พร้อมกัน โดยปล่อย invariant ที่ไม่ชัดเจนไว้นอกโค้ด
  • แนวทางที่เสนอคือ ขั้นแรกลอง reconcile ข้อมูล ICAO และ ADEXP ให้เป็นโครงสร้างแผนการบิน Combined เดียว จากนั้นจึงดึงช่วงของสหราชอาณาจักรออกมา
    • คำนวณ reconciliation ที่เป็นไปได้ทั้งหมดเพื่อตรวจหากรณีกำกวม
    • หาก reconciliation มี 0 รายการ แปลว่าไม่สามารถจับคู่ ICAO กับ ADEXP ได้
    • หากมีหลายรายการ แปลว่ากำกวม จึงสามารถส่งไปให้จัดการด้วยมือได้
  • implementation ตัวอย่างใน Haskell จัดการข้อผิดพลาด NonUkPlan, CannotReconcileIcaoAdexp, AmbiguousReconciliationsOfIcaoAdexp อย่างชัดเจน
  • ในตัวอย่าง แม้รายการ ADEXP จะมีตัวระบุซ้ำ Q หากข้อมูล ICAO และ ADEXP จับคู่กันได้โดยไม่กำกวม ก็จะส่งคืนช่วงของสหราชอาณาจักรที่ถูกต้อง
  • โค้ดทั้งหมดอยู่ที่ uk-portion-of-ICAO

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

 
GN⁺ 2023-09-12
ความคิดเห็นบน Hacker News
  • เหมือนกับว่าลืมใส่ ขอบเขตจำกัดที่แยกตามภูมิศาสตร์ ในการค้นหาแผนการบิน ผมเคยทำระบบนำร่องการบินมาก่อน รู้จักบั๊กนี้ เคยเห็นมันเกิดจริง และเคยทำตามสเปกที่ให้ใส่ geofence เพื่อหลีกเลี่ยงบั๊กนี้

    • ถ้าชื่อจุดนำร่องไม่ได้ไม่ซ้ำกันทั่วโลก และเส้นทางบินข้ามภูมิภาคก็เป็นเรื่องปกติ ผมก็ไม่เข้าใจว่าทำไมถึงไม่ใส่ GUID ให้จุดนำร่องพวกนี้
    • สงสัยว่าพัฒนาโดยใช้ภาษาอะไร
    • มาตรฐาน ICAO กำหนดมาตั้งแต่ปี 1978 แล้วว่า หากจะใช้ตัวระบุซ้ำกัน ต้องอยู่ห่างกันมากกว่า 600 ไมล์ทะเล (690 ไมล์, 1,100 กม.)
  • ประเด็นอยู่ตรงที่ว่า “ระบบสำรองนำตรรกะเดียวกันไปใช้กับแผนการบิน และได้ผลลัพธ์แบบเดียวกัน” ในซอฟต์แวร์ ระบบสำรอง ควรใช้ตรรกะที่ต่างออกไป
    สมัยก่อนตอนทำงานกับระบบ trim ของ stabilizer บน Boeing 757 มีคอมพิวเตอร์ avionics สองเครื่องต่ออยู่กับสายไฟที่สั่งให้ trim ทำงาน และเชื่อมผ่าน comparator โครงสร้างคือถ้ากล่องทั้งสองไม่เห็นตรงกัน ทั้งคู่จะเสียอำนาจควบคุม
    กล่องทั้งสองถูกออกแบบให้ใช้คนละอัลกอริทึม คนละภาษาโปรแกรมมิง คนละ CPU และโค้ดจากคนละทีมที่แยกกันด้วย firewall โดยตั้งใจไม่ให้บั๊กฝั่งหนึ่งทำให้อีกฝั่งพังในแบบเดียวกัน

    • นี่น่าจะเป็น ระบบ 2oo2 ที่มีนักบินเป็นตัวสำรอง แต่ 2oo2 ไม่ได้มี availability สูง
      ระบบควบคุมจราจรทางอากาศควรเป็นอย่างน้อย 2oo3[1] คือโครงสร้างที่ต้องมี 2 จาก 3 ระบบที่พัฒนาอย่างอิสระเห็นตรงกันเสมอ แบบนั้นถึงแม้ระบบหนึ่งล้มเหลว อีกสองระบบก็ยังทำงานต่อได้ โดยไม่กระทบ availability ของอุตสาหกรรมการบิน
      การให้มนุษย์เป็นตัวสำรองทำไม่ได้เพราะกำลังคนและความซับซ้อน ระบบควบคุมจราจรทางอากาศต้องสามารถให้การควบคุมการแยกระยะได้ภายใต้เงื่อนไข IFR[2] และ CVFR[3]
      [1] https://en.wikipedia.org/wiki/Triple_modular_redundancy
      [2] https://en.wikipedia.org/wiki/Instrument_flight_rules#Separa...
      [3] https://en.wikipedia.org/wiki/Visual_flight_rules#Controlled...
    • ตอนอ่านก็คิดแบบเดียวกันขึ้นมาก่อนเลย ระบบ failover นี้ดูเหมือนถูกออกแบบมาเพื่อลดผลกระทบจากความขัดข้องของฮาร์ดแวร์ มากกว่าบั๊กของซอฟต์แวร์
    • “เมื่อ ระบบนิรภัย ล้มเหลว มันจะล้มเหลวในแบบที่ไม่สามารถล้มเหลวอย่างปลอดภัยได้”
      J. Gall
    • ทีมต่างกันก็มักทำพลาดแบบเดียวกันได้บ่อย ๆ ไม่ใช่โครงสร้างที่สมบูรณ์แบบ แต่แนวทางที่อธิบายมาก็ดูสมเหตุสมผล
    • นอกเรื่องนิดหนึ่ง แต่น่าเสียดายที่ MAX รู้แนวทางแบบนั้นแล้วแต่ไม่ได้เอากลับมาใช้
  • จำได้ว่า NATS ก็เคยมีปัญหาอื่นที่ให้ผลแบบเดียวกัน ระบบหลักล้มแล้วสลับไปตัวรอง แต่ตัวรองก็ล้มด้วยเหตุผลเดียวกันเป๊ะ
    คงควรทำ failover ก็ต่อเมื่อรู้ว่าปัญหาอยู่ที่ระบบหลักเอง ไม่ใช่ตัวซอฟต์แวร์ การสลับไปเฉย ๆ ยิ่งตอกย้ำความรู้สึกว่าไม่มีการเปิดเผยข้อมูลมากพอให้ตัดสินได้ว่าจริง ๆ แล้วควรทำอะไร
    ส่วนที่ทำให้รู้สึกแย่กว่านั้นคือ ไม่มีเมธอดอย่าง “ValidateFlightPlan” พอไม่สามารถ parse ได้ไม่ว่าด้วยเหตุผลใดก็โยน error และไม่มีเส้นทางจัดการ error แบบเรียบง่ายมาก ๆ อยู่เลย ผมนึกไม่ออกว่าจะมีโปรแกรมเมอร์คนไหนมองตัวจัดการอินพุตจากภายนอกแล้วไม่คิดว่า “ถ้าอินพุตแย่ ๆ ที่ทำให้ระบบพังเข้ามา จะทำยังไง?”

    • ถ้ารู้ว่าระบบหลักไม่ได้อยู่ในสถานะปกติ ก็อาจลองสลับไป โดยหวังว่าเป็นปัญหาอย่างดิสก์ไหม้ หรือ bit flip จากรังสีคอสมิก
      ฟีเจอร์ด้านความปลอดภัยที่แท้จริงคือเวลาผ่อนผัน 4 ชั่วโมงก่อนที่จะต้องใช้ การประมวลผลด้วยมือ
      ในการบิน การควบคุมความปลอดภัยหลัก ๆ ไม่ได้ใกล้กับคำถามว่า “จะทำอย่างไรไม่ให้มันพังตั้งแต่แรก” เท่ากับ “ถ้ามันพังด้วยเหตุผลใดก็ตาม จะทำอะไร”
    • นอกจากประเด็นที่ไม่มีการตรวจสอบความถูกต้องแล้ว ข้อความส่วนนี้ในบทความสะดุดตาผม
      สไตล์การโปรแกรมดูเป็น imperative มาก และจากคำอธิบาย ฟังเหมือนขั้นตอนทำงานกับ representation แบบข้อความของแผนการบินโดยตรง ไม่ใช่โครงสร้างข้อมูลที่ parse มาจากไฟล์ข้อความ ถ้าเป็นแบบนั้นจริงก็น่ากังวลทีเดียว แต่อาจเป็นเพราะวิธีอธิบายก็ได้
      ถ้าเป็นไปตามคำอธิบายนี้จริง ต่อให้เป็นโครงสร้างที่แค่เอา regex หรือ substring matching ไปรันบนข้อความ โดยไม่มี class, object หรือ data structure เลย ก็ไม่น่าแปลกใจ ต้องเผื่อความเป็นไปได้ด้วยว่าอาจเป็น โค้ด C อายุหลายสิบปีที่การบินทั้งสหราชอาณาจักรต้องพึ่งพา และเขียนใหม่หรือเปลี่ยนแทนไม่ได้
    • ไม่มีวิธีตัดสินว่าไม่ใช่ฮาร์ดแวร์เป็นต้นเหตุ ดังนั้นการ failover เองถือว่าถูกแล้ว เพียงแต่ควรออกแบบการตอบสนองเมื่อเกิดความล้มเหลวครั้งที่สองให้ดีกว่านี้ เพื่อหลีกเลี่ยงผลกระทบเป็นลูกโซ่
    • มองในเชิงไฟฟ้า ก็เหมือนเปลี่ยนฟิวส์แล้วนั่งดูมันขาดอีกครั้ง ในร้านไม่มีฟิวส์เหลือแล้ว นี่คือความคืบหน้าหรือ?
    • ความล้มเหลวในการปล่อย Ariane 5[1] ก็เป็นปัญหาคล้ายกัน และผลลัพธ์อลังการกว่ามาก
      ระบบหลักล้มเหลวเพราะ integer overflow และระบบรองที่เหมือนกันก็ overflow ไปด้วย มุมปะทะเพิ่มขึ้น booster แยกตัว แล้วจรวดก็ระเบิด
      [1] https://en.wikipedia.org/wiki/Ariane_flight_V88
  • ไม่เข้าใจว่าทำไมจึงเอาเฉพาะแผนการบินที่ล้มเหลวไปใส่ไว้ใน คิวรอให้มนุษย์ตรวจสอบ แล้วปล่อยให้เที่ยวบินที่เหลือประมวลผลต่อไปไม่ได้ จุดที่เข้าใจยากที่สุดคือการที่ไม่มี “ฟีเจอร์” นั้น

    • โค้ดจัดประเภทข้อผิดพลาดนั้นว่า “เรื่องนี้ไม่มีทางเกิดขึ้นเด็ดขาด!” แล้วมันก็เกิดขึ้นจริง ๆ ไม่ได้จัดว่าเป็น “ข้อมูลแผนการบินไม่ดี” หรือ “ข้อมูลถูกต้องแต่ยังไม่รองรับ”
      เมื่อเกิดข้อผิดพลาดแบบ “ไม่มีทางเกิดขึ้นเด็ดขาด” ระบบจะไม่รู้ว่าอะไรผิดพลาด ผลกระทบใหญ่และกว้างแค่ไหน ครั้งนี้อาจจะเดินหน้าต่อไปได้ก็จริง แต่ก็อาจเป็นบั๊กใหม่ร้ายแรงในซอฟต์แวร์ที่ทำให้แผนการบินอื่นทั้งหมดปนเปื้อนอย่างเงียบ ๆ และทำให้คนตายได้ ถ้าไม่รู้ว่าดำเนินต่อไปแล้วปลอดภัยหรือไม่ ก็ต้องหยุด
    • ถ้าว่ากันอย่างเป็นธรรม ช่วงต้นของบทความบอกว่าแผนการบินเหล่านี้บางครั้งถูกประมวลผลสำหรับเครื่องบินที่กำลังบินอยู่แล้ว แม้อย่างน้อยจะยังอยู่ห่างจากสหราชอาณาจักรมากกว่า 4 ชั่วโมงก็ตาม
      ถ้าสามารถกันไม่ให้เครื่องบินลำที่มีปัญหานั้นขึ้นบินได้ การปล่อยให้ระบบทำงานต่อก็อาจไม่เป็นไร แต่ถ้ามันอยู่กลางอากาศแล้ว เรื่องก็เปลี่ยนไป
      การตัดสินใจว่า “มีเครื่องบินที่จะเข้าสู่น่านฟ้าสหราชอาณาจักรกำลังอยู่ระหว่างเส้นทาง แต่เราไม่รู้ว่าจะเข้ามาเมื่อไรและที่ไหน จึงหยุดรับแผนการบินเพิ่มเติมไว้ก่อนจนกว่าจะรู้ตำแหน่งของเครื่องบินลำนั้น” ก็ไม่ใช่เรื่องไร้เหตุผลเสียทีเดียว
      ถ้าประมวลผลแผนการบินนั้นไม่ได้จริง ๆ ทางออกที่สมเหตุสมผลอาจเป็นการเปลี่ยนเส้นทางเครื่องบินลำนั้นให้ไปลงจอดก่อนถึงสหราชอาณาจักร แต่เรื่องแบบนั้นสุดท้ายก็ต้องรอการแทรกแซงแบบแมนนวล
    • ทั้งบทความและการวิเคราะห์หลังเหตุการณ์ต่างมองว่า โหมดความล้มเหลวที่แย่ของระบบ FPRSA-R เป็นปัญหาหลัก และผมเห็นว่านี่คือส่วนสำคัญที่สุด
      ทุกระบบอาจทำงานผิดพลาดได้ สิ่งสำคัญคือมันต้องผิดพลาดในแบบที่ดี และผู้รับผิดชอบต้องเตรียมพร้อมสำหรับสถานการณ์นั้น
      แผนการบินเพียงรายการเดียวก่อปัญหา แล้วระบบ FPRSA-R ทั้งหมดก็ดับ ทำให้ไม่มีการประมวลผลแผนการบินเลย หากแผนการบินหนึ่งมีปัญหา ก็ควรย้ายไปยังคิวช้าแยกต่างหากเพื่อให้มนุษย์จัดการด้วยมือ NATS เองก็ยอมรับในส่วน “มาตรการที่ดำเนินการไปแล้วหรือกำลังดำเนินการ” ว่าจะเพิ่มตัวกรองข้อความในโฟลว์ข้อมูลระหว่าง IFPS กับ FPRSA-R เพื่อกรองแผนการบินที่เข้าเงื่อนไขดังกล่าว
    • ในระบบที่ความปลอดภัยเป็นภารกิจจำเป็น เมื่อเจอ “ข้อผิดพลาดที่ไม่รู้จัก” ก็ต้องถือว่า เงื่อนไขคงที่ ทั้งหมดถูกละเมิด และระบบเข้าสู่พฤติกรรมที่ไม่ได้กำหนดไว้ จึงไม่มีทางเลือกนอกจากหยุด
      การบอกว่าสิ่งนี้ควรถูกจัดการเป็นข้อผิดพลาดที่รู้จักนั้นก็สมเหตุสมผล แต่ถ้ามองกว้าง ๆ ก็คล้ายกับการพูดว่า “ควรเขียนโค้ดที่ไม่มีบั๊ก” แม้จะพาร์สเป็น struct แล้ว ก็อาจเหมือนกรณีที่โค้ดซึ่งสมมติว่ามีคีย์ตัวเลือกอยู่ จู่ ๆ ก็เจอ KeyError โผล่มา
      การวิเคราะห์หลังเหตุการณ์และการปรับปรุงสำหรับเรื่องแบบนี้ควรตั้งอยู่บนสมมติฐานว่า วันหนึ่งข้อผิดพลาดไม่รู้จักที่ไม่ได้ถูกจัดการและคาดเดาไม่ได้จะเกิดขึ้น แล้วควรรับมืออย่างไรให้ดีกว่านั้น ทางแก้ของบั๊กคือแก้บั๊ก แต่สาเหตุของเหตุขัดข้องใหญ่คือแผนกู้คืนจากภัยพิบัติที่ไม่สามารถปฏิบัติได้ภายในเวลาที่สมเหตุสมผล ไม่ว่าจะใช้แนวปฏิบัติ สไตล์ ภาษา หรือเครื่องมือเขียนโปรแกรมแบบใด เหตุการณ์ระดับใกล้เคียงกันก็จะเกิดขึ้นอีกในสักวันด้วยความน่าจะเป็น 1 แม้จะเป็นนักพัฒนาที่เก่งที่สุดก็ตาม
    • อัลกอริทึมที่อธิบายในบทความมีแนวโน้มว่าไม่ใช่โค้ดเชิงขั้นตอนแบบง่าย ๆ ที่ไล่ตาม waypoint ของแผนการบินอินพุตตามลำดับ อาจมี abstraction บางอย่างที่บดบังความจริงว่านี่คือ ข้อผิดพลาดของอินพุต
      จากมุมมองของโค้ด หากมันดูเหมือนความล้มเหลวด้านความสมบูรณ์ของฐานข้อมูล waypoint นำทางพื้นฐาน การตัดสินใจหยุดประมวลผลแผนการบินก็เข้าใจได้มากขึ้นมาก
      ตัวอย่างเช่น ถ้าโค้ดถามคลัง waypoint และเส้นทางว่า “หา waypoint ที่เส้นทางนี้ออกจากน่านฟ้าสหราชอาณาจักรให้หน่อย” จากนั้นหา segment ของเส้นทางที่มี waypoint นั้น แล้ว assert ว่า segment นั้นผ่านน่านฟ้าสหราชอาณาจักร แต่ assertion นั้นล้มเหลว นี่อาจดูไม่ใช่ปัญหาแผนการบิน แต่เหมือนสมมติฐานที่ฝังอยู่ในข้อมูลเส้นทางถูกละเมิด
      ในแง่หนึ่ง มันอาจเป็นบั๊กร้ายแรงจริง ๆ ก็ได้ เหตุการณ์นี้แสดงให้เห็นว่าสมมติฐานที่อัลกอริทึมตั้งไว้กับข้อมูลนั้นผิด และอาจส่งคำตอบที่ผิดกลับมาได้
  • บทความที่เกี่ยวข้อง
    ระบบควบคุมการจราจรทางอากาศของสหราชอาณาจักรถูกหลอกเพราะชื่อ waypoint ซ้ำกันโดยบังเอิญ - https://news.ycombinator.com/item?id=37430384 - กันยายน 2023, 64 ความคิดเห็น
    ข้อมูลแผนการบินที่ไม่ดีทำให้ระบบควบคุมการจราจรทางอากาศของสหราชอาณาจักรขัดข้อง - https://news.ycombinator.com/item?id=37402766 - กันยายน 2023, 20 ความคิดเห็น
    รายงานอุบัติเหตุการควบคุมการจราจรทางอากาศของ NATS เปิดเผยสาเหตุรากและแนวทางแก้ไขโดยละเอียด - https://news.ycombinator.com/item?id=37401864 - กันยายน 2023, 19 ความคิดเห็น
    เครือข่ายควบคุมการจราจรทางอากาศของสหราชอาณาจักรล่ม - https://news.ycombinator.com/item?id=37292406 - สิงหาคม 2023, 23 ความคิดเห็น

    • หลังจากฟังตอนล่าสุดของ The Daily เกี่ยวกับอุตสาหกรรมการบินของสหรัฐฯ แล้ว ก็มั่นใจว่าอีกไม่นานเราจะได้เห็น พาดหัวข่าวภัยพิบัติร้ายแรง แบบนี้ต่อไปไม่ได้แล้ว
    • เห็นชื่อบทความนี้แล้วนึกว่าเป็นเหตุขัดข้องที่เพิ่งเกิดขึ้นใหม่ตอนนี้
  • ข้อเท็จจริงที่พวกเขาโทษแผนการบินของฝรั่งเศสที่ Eurocontrol รับไปแล้ว เป็นหลักฐานว่าพวกเขาไม่เข้าใจจริง ๆ ว่าซอฟต์แวร์ทำงานอย่างไร และบริษัทออสเตรียก็ควรรับผิดชอบบางส่วนต่อ การขาดการทดสอบอย่างเข้มข้น ด้วย

    • ก็เพราะเป็นสหราชอาณาจักร เลยโทษฝรั่งเศสนั่นแหละ นิสัยเสียเลิกยาก
  • เป็นบทความที่ยอดเยี่ยม อ่านแล้วใจความน่าจะประมาณนี้
    ชื่อจุดรายงาน/จุดผ่านทางที่ใช้กันทั่วโลกไม่ได้มีเอกลักษณ์ไม่ซ้ำกัน และเพื่อเลี่ยงความสับสน มาตรฐานล่าสุดจึงกำหนดแบบแก้ขัดว่าให้วางตัวระบุเดียวกันให้ห่างกันทางภูมิศาสตร์มากพอ ถึงอย่างนั้น ในเส้นทางบินเส้นหนึ่ง ชื่อจุดผ่านทางเดียวกันก็ยังอาจหมายถึงตำแหน่งคนละแห่งได้
    ซอฟต์แวร์ไม่ได้คำนึงถึงความเป็นไปได้นั้น การคำนวณเส้นทางจึงล้มเหลว โยน “fatal exception” และเข้าสู่ “maintenance mode” กล่าวคือ ตายไปแล้ว
    ระบบสำรองเข้ามารับช่วงต่อ แต่เจอบั๊กเดียวกันจากข้อมูลชุดเดียวกัน จึงตายไปเหมือนกัน และทีมซัพพอร์ตก็ลำบากกันมาก สุดท้ายต้องติดต่อผู้จำหน่ายซอฟต์แวร์ก่อน จึงพบล็อกระดับต่ำที่เผยให้เห็นสาเหตุ

    • ไม่เข้าใจเลยว่าทำไม ระบบที่จำเป็นต่อภารกิจ ระดับนี้ถึงไม่มีคนที่คุ้นกับโค้ดคอย on-call ตลอด 24/7
    • ประเด็นหลักคือไม่มี namespace ที่เหมาะสม ใครจะไปคิดว่าวิศวกรการบินและอวกาศต้องเรียนระบบปฏิบัติการด้วย
      เพื่อนผมที่เป็นอดีตนักบินกองทัพอากาศจบจาก Cranfield University ซึ่งเป็นสถาบันบัณฑิตศึกษาด้านวิศวกรรมการบินและอวกาศชั้นนำของสหราชอาณาจักร และมีสนามบินของตัวเองสำหรับการเรียนการสอนและการวิจัยด้วย[1] เพื่อนคนนั้นเคยบอกว่าเรียนระบบปฏิบัติการที่ Cranfield ตอนนี้ถึงเข้าใจเหตุผลแล้ว
      ดูจากคอมเมนต์อื่น ๆ มาตรฐาน namespace มีอยู่แล้ว แต่ดูเหมือน NATS/ATC จะไม่ได้ใช้ หวังว่าเหตุการณ์นี้จะทำให้เริ่มใช้กันเสียที คอมเมนต์บนสุดพูดถึงบั๊ก geofencing แต่ถ้า NATS/ATC ใช้ namespace ที่ถูกต้องตั้งแต่แรก geofencing ก็มีโอกาสสูงว่าจะไม่จำเป็นเลย
      [1] Cranfield University:
      https://en.wikipedia.org/wiki/Cranfield_University
  • “อ่านจากคำอธิบายแล้ว ฟังดูเหมือนขั้นตอนไม่ได้จัดการกับโครงสร้างข้อมูลที่ parse มาจากไฟล์ข้อความ แต่จัดการกับตัวแทนแบบข้อความของแผนการบินโดยตรง ถ้าเป็นอย่างนั้นจริงก็น่ากังวลพอสมควร แต่อาจเป็นเพราะวิธีอธิบายก็ได้”
    ในงานอุตสาหกรรมการบิน วิธีแบบนี้พบได้ทั่วไป ถ้าถามโปรแกรมเมอร์เรื่อง domain model หรือ parsing มักจะได้เห็นสีหน้าว่างเปล่า พวกเขาชอบโค้ด validation และถ้า validate ไม่ผ่านก็ชอบยอมแพ้ไปเลย ทั้งหมดเป็นแค่ data pipeline โง่ ๆ และแทบไม่มีโค้ดที่ model กิจกรรมที่เกิดขึ้นในโลกจริงเลย
    ไม่มีระบบไหนมี type “แผนการบิน” ที่มีพฤติกรรม หรือชุด type ของจุดผ่านทางอะไรทำนองนั้น ถึงจะมี type ก็เป็น struct ของสตริงในมุมมองแบบ C และทุกครั้งที่มีการเข้าถึงสมาชิกของ struct นั้น ก็จะถูก parse ใหม่ทุกครั้ง ไม่ใช่แค่ครั้งเดียว อย่างที่บทความบอกไว้ว่า “สไตล์การเขียนโปรแกรมดูเป็นแบบ imperative มาก” นั่นแหละถูกแล้ว

    • การยอมแพ้เมื่อ validation ล้มเหลวเป็นแนวทางมาตรฐานอย่างหนึ่ง เพื่อไม่ให้แพร่กระจายข้อมูลที่ตีความผิดออกไปจนเกิดบั๊กที่ซับซ้อนกว่ามาก ควร validate ให้เร็ว validate ให้เข้ม รายงานข้อผิดพลาด และไม่พยายามฝืนตีความว่าตรงไหนของอินพุตแปลกไป พอเริ่มทำตัวให้ “ฉลาด” ช่องโหว่ด้านความปลอดภัยก็เกิดขึ้น
      การตายเพราะอินพุตแย่ ๆ เป็นเรื่องผิดก็จริง แต่การพยายามตีความข้อมูลที่ยังไม่ผ่าน validation โดยไม่มีสเปก มักจะนำไปสู่ความไม่ตรงกันในการทำความเข้าใจ ปัญหาความเข้ากันได้ และเงื่อนไขขอบเขตที่คาดไม่ถึงในภายหลัง ไม่มีใครอยากจ่ายเงินเพื่อระบบที่รองรับทุกกรณีและทดสอบครบถ้วน เครื่องมือจำลองอินพุตผิดพลาด และการตรวจพิสูจน์เชิงรูปแบบของ parser รวมถึงโค้ดทั้งหมดที่ใช้ผลลัพธ์จาก parser
      เดิมทีก็มีปัญหามากอยู่แล้วจากตัวส่งข้อมูลที่ไม่เป็นไปตามมาตรฐาน เป็น legacy หรือมีบั๊ก รวมถึงความซับซ้อนของ semantics และ timing ของ interface การพยายามตอบสนองอย่างฉลาดต่อข้อมูลที่มีรูปแบบหรือ encoding ผิดยิ่งทำให้อันตรายกว่าเดิม
      แค่สร้างระบบให้ทำงานตามสเปกก็ยากและแพงอยู่แล้ว การเพิ่มรูปแบบย่อย ๆ ที่ยอมรับพฤติกรรมที่ไม่ได้ระบุในสเปกอย่างผ่อนปรนมากขึ้น ไม่ต่างจากการเรียกหาบั๊ก หรือไม่ก็สร้างระบบที่แพงขึ้นจนเกินเกณฑ์ราคาจัดซื้อ
    • น่าสนใจมาก และก็น่ากลัวนิด ๆ ด้วย น่าสนุกตรงที่อุตสาหกรรมต่าง ๆ ต่างสร้าง วัฒนธรรมการพัฒนา ของตัวเองขึ้นมาแตกต่างกัน ด้วยเหตุผลที่ก็ไม่ได้ชัดเจนนัก
  • “การควบคุมจราจรทางอากาศของสหราชอาณาจักร: สอบสวนว่าข้อผิดพลาดของฝรั่งเศสทำให้เกิดเหตุขัดข้องหรือไม่”
    แน่นอนว่าไม่ใช่สิ นี่เป็นระบบของสหราชอาณาจักร แล้วจะไปเป็นความผิดของสายการบินฝรั่งเศสได้อย่างไร? ระบบแบบนี้ควรเป็น โครงสร้างป้องกันข้อผิดพลาด ที่มี redundancy
    แค่ปฏิเสธรายการที่ไม่ดีหนึ่งรายการแล้วทำงานต่อไป ก็น่าจะเพียงพอแล้ว

    • ถ้าจะนับแบบชาตินิยมจริง ๆ ซอฟต์แวร์นั้นผลิตในออสเตรีย
  • เป็นวันที่ไม่อยากจำเลย ปลายทางที่ปกติใช้เวลา 2 ชั่วโมง กลับต้องใช้ 15 ชั่วโมง
    ผมนั่งรถไฟ รถบัส แล้วก็รถไฟอีกครั้ง และหลังจากจองตั๋วไปได้ 30 นาที ตั๋วสำหรับสองวันก็ขายหมดเกลี้ยง

    • ผมรอที่สนามบิน 6 ชั่วโมงกว่าจะรู้ว่าเที่ยวบินถูกยกเลิก แล้วต้องจองใหม่ ผมกำลังจะไป New York เพื่อไปพบครอบครัว เลยแทบไม่มีทางเลือกการเดินทางอื่นเลย