ทำให้แชทยังทำงานเมื่อโทรศัพท์หลับ
เอเจนต์ของ Mythex อาจทำงานหลายนาทีกับคำขอเดียว และคุณอาจกำลังดูจากโทรศัพท์ ซึ่งจะล็อก สลับแอป และเปลี่ยนเครือข่ายระหว่างที่มันทำงาน บั๊กสองตัวทำให้เกิดปัญหาตรงนี้ ตัวหนึ่งทำให้แชทถือว่าทุกสัญญาณ “หน้าเว็บกลับมาแสดงผลแล้ว” เป็นหลักฐานว่าการเชื่อมต่อของมันตายไปแล้ว แล้ววนลูปจนค้างอยู่ที่ “กำลังเชื่อมต่อ…” อีกตัวทำให้โทรศัพท์ที่หลับระหว่างคำตอบแรกของแชทใหม่กลับมาพร้อมคำตอบเพียงไม่กี่ชิ้นแรกเท่านั้น จนกว่าจะรีเฟรชเอง ทั้งสองตัวได้รับการแก้ไขแล้ว
แชทติดตามรอบที่กำลังทำงานอย่างไร
ขณะที่เอเจนต์ทำงาน แชทจะเปิดสตรีมจากเซิร์ฟเวอร์ของเรา แต่ละขั้นตอน ไม่ว่าจะเป็นความคิด การเรียกเครื่องมือ หรือชิ้นของคำตอบ จะมาถึงในรูปแบบเหตุการณ์ ถ้าสตรีมหลุด แชทจะเชื่อมต่อใหม่ และเซิร์ฟเวอร์จะเล่นเหตุการณ์ล่าสุดซ้ำจากบัฟเฟอร์ที่เก็บ 120 วินาทีล่าสุด เมื่อรอบจบ แชทจะขอประวัติที่บันทึกไว้จากเซิร์ฟเวอร์ด้วย แล้วกระทบยอดสิ่งที่แสดงไว้กับสิ่งที่ถูกเก็บ ขั้นตอนสุดท้ายนั้นจับสิ่งที่สตรีมพลาดไป
เพื่อแยกการเชื่อมต่อที่ยังมีชีวิตจากที่ตายแล้วในช่วงที่ไม่มีอะไรเกิดขึ้น เซิร์ฟเวอร์จะส่ง “ping” เล็ก ๆ ทุก 15 วินาที
บั๊กที่ 1: การตื่นฆ่าสตรีมที่ยังปกติ
เบราว์เซอร์บอกหน้าเว็บเมื่อกลับมาแสดงผลอีกครั้ง เช่น หลังสลับแท็บ หรือหลังปลดล็อกหน้าจอ เราใช้สัญญาณนั้นเป็นสัญญาณให้ตรวจการเชื่อมต่อ และในทางปฏิบัติคือยกเลิกสตรีมแล้วเชื่อมต่อใหม่ โดยสมมติว่ามันตายขณะซ่อนอยู่
บนโทรศัพท์และเบราว์เซอร์แบบฝัง เหตุการณ์เหล่านี้เกิดบ่อยกว่าสตรีมที่ตายมาก ทุกครั้งที่สลับแท็บ ทุกครั้งที่ปลดล็อก และในเบราว์เซอร์แบบฝังบางตัวทุกสองสามวินาที แต่ละครั้งยกเลิกสตรีมที่ปกติดี แชทเชื่อมต่อใหม่ เล่นซ้ำ ถูกยกเลิกอีก แล้วค้างอยู่ที่ “กำลังเชื่อมต่อ…” จากนั้นก็บอกว่ารอบจบแล้วทั้งที่เอเจนต์ยังทำงานอยู่
วิธีแก้: ตัดสินจากว่าสตรีมยังพูดอยู่หรือไม่
ตอนนี้แชทบันทึกว่าสตรีมของแต่ละโปรเจกต์ได้รับอะไรล่าสุด ทั้งเหตุการณ์และ ping ทุก 15 วินาที สัญญาณ “กลับมาแสดงผล” จะยกเลิกสตรีมก็ต่อเมื่อมันเงียบมาแล้ว 25 วินาที ซึ่งนานกว่าช่วงห่างของ ping บวกการเดินทางของเครือข่ายที่ช้า ดังนั้นสตรีมที่ยังมีชีวิตจึงไม่เข้าเกณฑ์นี้ การทดสอบตรวจว่า ping นับเป็นสัญญาณของชีวิต และสตรีมที่เพิ่ง ping แล้วจะไม่ถูกมองว่าตาย
กฎที่เราได้จากเรื่องนี้: การมองเห็นของหน้าเว็บบอกเกี่ยวกับหน้าเว็บ ไม่ได้บอกเกี่ยวกับการเชื่อมต่อเครือข่าย ให้ถามที่การเชื่อมต่อเอง
บั๊กที่ 2: คำตอบครึ่งเดียวหลังโทรศัพท์ตื่น
อันนี้เราสร้างซ้ำได้ทุกครั้งใน iOS simulator:
- เริ่มแชทใหม่ และส่งคำขอที่ใช้เวลาสักพัก
- ให้โทรศัพท์หลับตลอดการสร้าง
- กลับมาหลังรอบจบแล้ว และบัฟเฟอร์การเล่นซ้ำสองนาทีหมดอายุไปแล้ว
แชทแสดงบล็อกแรกไม่กี่บล็อกของคำตอบ ทำเครื่องหมายว่าเสร็จแล้ว และคงอยู่แบบนั้นจนกว่าคุณจะรีเฟรชหน้า
สาเหตุ
แชทใหม่ยังไม่มีเธรด (การสนทนาที่บันทึกไว้) จนกว่าข้อความแรกจะสร้างมัน ซึ่งเกิดขึ้นภายในฟังก์ชันส่งหลังจากที่ส่งได้จับขั้นตอนกระทบยอดไว้แล้ว และขั้นตอนนั้นยังคิดว่าไม่มีเธรด ดังนั้นเมื่อสิ้นสุดรอบแรกในแชทใหม่ การกระทบยอดจะเห็นว่าไม่มีเธรด และกลับออกไปเงียบ ๆ โดยไม่ขออะไรเลย
ปกติไม่มีใครสังเกต เพราะสตรีมได้ส่งรอบทั้งหมดมาอยู่แล้ว แต่โทรศัพท์ที่หลับระหว่างรอบ และกลับมาหลังบัฟเฟอร์การเล่นซ้ำ 120 วินาทีหมดอายุ ไม่สามารถดึงเหตุการณ์ที่หายไปจากสตรีมได้ และการกระทบยอดที่ควรจะเติมช่องว่างนั้นไม่เคยทำงานเลย
วิธีแก้
- ส่งบอกการกระทบยอดว่ารอบนี้เป็นของเธรดไหน ดังนั้นรอบแรกของแชทใหม่จะถูกกระทบยอดเหมือนรอบอื่น ถ้าคุณเปิดแชทอื่นแล้วตอนที่คำตอบมาถึง ผลลัพธ์จะถูกทิ้งแทนที่จะไปแสดงผิดที่
- การกระทบยอดที่ล้มเหลวจะถูกลองอีกครั้ง โทรศัพท์ที่ตื่นบนการเชื่อมต่อที่ไม่ดีอาจพบว่ารอบจบแล้วแต่ดึงมาไม่ได้ ตอนนี้เรื่องนั้นจะถูกจดจำ และแชทจะถามใหม่เมื่อแท็บแสดงอีกครั้ง หรือเมื่อเครือข่ายกลับมา
- “ทำงานมาแล้ว” ซื่อตรง คำตอบแต่ละอันแสดงว่าเอเจนต์ทำงานนานเท่าไร ถ้าแท็บไม่เคยเห็นข้อความจบรอบจากเซิร์ฟเวอร์ มันเคยเติมค่านั้นจากนาฬิกาของตัวเอง ซึ่งนับตั้งแต่กดส่งจนโทรศัพท์ตื่น รวมเวลาที่ห่างไปด้วย ตัวเลขนั้นตอนนี้ถูกทำเครื่องหมายว่าเป็นการประมาณ และจะถูกแทนที่ด้วยระยะเวลาที่บันทึกไว้เมื่อประวัติมาถึง
สิ่งที่เราได้เรียนรู้
- ทดสอบบนอุปกรณ์ที่คนใช้จริง ในแบบที่เขาใช้ บั๊กทั้งสองอยู่ในช่องว่างระหว่าง “สตรีมที่ทำงานได้” กับ “โทรศัพท์ในกระเป๋า”
- กลไกสำรองที่ไม่เคยทำงานก็ไม่ใช่กลไกสำรอง ขั้นตอนกระทบยอดมีอยู่เพื่อจับกรณีนี้พอดี และมันข้ามไปอย่างเงียบ ๆ
- ลองการกู้คืนซ้ำด้วย ช่วงเวลาที่โทรศัพท์ตื่นมักเป็นช่วงที่การเชื่อมต่อแย่ที่สุด
- อย่าแสดงการเดาเป็นข้อเท็จจริง ระยะเวลาจากนาฬิกาผิดเรือนแย่กว่าไม่มีเลย ให้ติดป้ายหรือแทนที่
งานเดียวกันนี้ยังจัดระเบียบบางอย่างที่คุณจะเห็นขณะรอบทำงาน: ขั้นตอนของเชลล์ถูกติดป้ายด้วยคำสั่งที่ทำงานจริงแทนที่จะเป็น cd ภาพหน้าจอในแชทจะเก็บส่วนบนซ้ายของหน้าไว้และพอดีกับคอลัมน์ และโปรเจกต์ใหม่จะได้ชื่อที่สร้างขึ้นโดยไม่ต้องรีเฟรช
ถ้าคุณกำลังสร้างแอปสำหรับโทรศัพท์ คู่มือของเราวิธีสร้างเว็บแอปที่ใช้งานบนมือถือได้ และNative กับ Progressive Web Apps ครอบคลุมพื้นฐาน เพิ่มเติมเกี่ยวกับตัวแชทเองอยู่ในเอกสารแชท