ผมตั้งค่าให้ GPS จักรยานสั่งพิซซ่าระหว่างแข่งทางกรวด
(steele.blue)- เพื่อหลีกเลี่ยงปัญหาพิซซ่าที่จุดเติมเสบียงหมดในงาน Nebraska Gravel Worlds Long Voyage จึงสร้างระบบอัตโนมัติให้สั่งพิซซ่าของ Casey's ล่วงหน้าตามตำแหน่ง GPS ของจักรยาน
- โครงสร้างคือ AWS Location geofence ตรวจจับการออกจากพื้นที่ของ GPS tracker แล้ว Lambda จะสั่งอาหารออนไลน์ให้ตรงกับ ETA ของจุดพักถัดไป
- เนื่องจาก Casey's ไม่มี API สั่งอาหารแบบสาธารณะ จึงใช้ Playwright ทำ screen scraping เว็บไซต์ที่สร้างด้วย React และตั้งค่าให้รับผลการสั่งผ่าน push notification บน iPhone และ Apple Watch
- ในการแข่งขันจริง มีการแจ้งเตือนว่าสั่งสำเร็จ แต่ที่ร้านไม่มีบันทึกคำสั่งซื้อ ทำให้เห็น false positive ของการทำ browser automation บนคลาวด์
- หลังจากนั้นเมื่อปรับให้บันทึกวิดีโอการทำงานของเบราว์เซอร์ลง S3 คำสั่งซื้อทดสอบก็สำเร็จ แต่ในสภาพแวดล้อม Lambda การทดสอบเฉพาะบนเครื่อง local ยังไม่พอให้มั่นใจเรื่องเสถียรภาพ
เหตุผลที่อยากให้ได้พิซซ่าระหว่างแข่ง
- เข้าร่วมการแข่งขันจักรยาน Gravel Worlds Long Voyage ที่รัฐ Nebraska ในช่วงฤดูเก็บเกี่ยวของ Midwest
- ปีก่อน นักปั่นที่เร็วกว่าไปถึงก่อนและหยิบพิซซ่าของ Casey's ที่จุดเติมเสบียงไปหมด ตอนที่ไปถึงจึงไม่เหลือพิซซ่าแล้ว
- เป้าหมายปีนี้คือสั่ง พิซซ่าสดใหม่ ล่วงหน้าให้ตรงกับเวลาจอดพัก
- ตั้งใจจะต่อยอดจากระบบ GPS tracker จักรยานแบบ serverless ที่มีอยู่เดิม โดยเพิ่มวิธีให้รันสคริปต์สั่งอาหารเมื่อออกจาก geofence ที่กำหนด
วิธี trigger การสั่งซื้อด้วย GPS และ Lambda
- การออกแบบโดยรวมคือใช้ geofence ของ AWS Location เฝ้าติดตาม GPS tracker
- เมื่อ tracker ออกจาก geofence จะ trigger ฟังก์ชัน Lambda
- Lambda คำนวณ ETA ไปยังจุดพักถัดไป
- สั่งพิซซ่า Casey's ให้สอดคล้องกับเวลาที่คำนวณได้
- Casey's ไม่มี public API สำหรับสั่งอาหารออนไลน์ จึงเลือกทำ screen scraping เว็บไซต์
- เว็บไซต์ของ Casey's เป็นแอป React ซับซ้อนที่ render ฝั่ง client
- ใช้ Playwright แทน scraper ทั่วไป
- ขั้นตอนการรัน Playwright บน Lambda ยุ่งยากถึงขนาดแยกเขียนเป็นอีกบทความได้
- เพื่อยืนยันสถานะคำสั่งซื้อ ตั้งค่าให้ส่ง push notification ไปยังโทรศัพท์และนาฬิกาเมื่อสำเร็จหรือล้มเหลว
- การตั้งค่าให้ Web Push ทำงานบนอุปกรณ์ iOS ก็เป็นเรื่องที่เขียนแยกได้อีกบทความเช่นกัน
ผลหน้างานที่ต่างจากการแจ้งว่าสำเร็จ
- ตั้ง geofence สำหรับ trigger การสั่งซื้อไว้บริเวณหลัก 180 ไมล์ ของการแข่งขัน
- วางแผนไปรับพิซซ่าที่หลัก 200 ไมล์
- เมื่อออกจาก geofence ก็มี push notification บนนาฬิกาแจ้งว่าสั่งพิซซ่าสำเร็จ
- แต่เมื่อไปถึงจุดพัก ที่เคาน์เตอร์ไม่มีคำสั่งซื้อ และในร้านก็ไม่มีบันทึกคำสั่งซื้อเช่นกัน
- เมื่อตรวจสอบบัญชี พบว่าไม่มีการสร้างคำสั่งซื้อจริง เป็นเพียง false positive ที่เกิดจากการแจ้งว่าสำเร็จเท่านั้น
- ที่หน้างานมีพิซซ่าหั่นชิ้นที่ทำไว้ล่วงหน้าอยู่ไม่กี่ชิ้น จึงซื้อสิ่งนั้นแทน
- หลังจากนั้นจนจบการแข่งขัน 300 ไมล์ ก็เอาแต่คิดว่าฟังก์ชัน Lambda ผิดพลาดตรงไหน
วิดีโอ capture ทิ้งเบาะแสไว้แทน log
- หลังจบการแข่งขัน ตรวจสอบ log แล้วก็ไม่พบข้อมูลที่บอกสาเหตุความล้มเหลว
- จาก log ดูเหมือนทุกอย่างสำเร็จอย่างเงียบ ๆ จึงแทบไม่มีเบาะแสสำหรับ debug
- ไม่กี่วันต่อมา ปรับ Lambda ให้ capture เป็นวิดีโอ การทำงานของเบราว์เซอร์และอัปโหลดไปยัง bucket S3
- เมื่อทดสอบด้วยพฤติกรรมที่ปรับแล้ว คำสั่งซื้อก็สำเร็จจริง และไปรับ Hawaiian pizza ได้ตามปกติ
- ยังสรุปสาเหตุที่แน่ชัดไม่ได้
- อาจเป็นไปได้ว่า Lambda จบการประมวลผลทันทีที่
form.submit()สุดท้ายถูกรันใน embedded Playwright browser - อาจเป็นไปได้ว่าเว็บไซต์สั่งอาหารออนไลน์ไม่ได้ยืนยันว่าเบราว์เซอร์ได้รับ response สำเร็จ จึงไม่ได้ประมวลผลคำสั่งซื้อจนเสร็จสมบูรณ์
- เวลาที่เพิ่มขึ้นจากการประมวลผลและอัปโหลดวิดีโออาจทำให้มีเวลาพอสำหรับการเก็บกวาดเบราว์เซอร์
- อาจเป็นไปได้ว่า Lambda จบการประมวลผลทันทีที่
ถ้าทำใหม่ครั้งหน้าจะเปลี่ยนอะไร
- การ screen scraping แอป client-side React ด้วยเบราว์เซอร์บนคลาวด์ให้เสถียรนั้นทำได้ แต่ ยุ่งยากมาก
- ถ้าทำใหม่ อาจพิจารณา reverse engineer แอป native ของ Casey's แล้ว trigger internal API โดยตรง
- ต้องมี workflow ที่ดี สำหรับจำลองพฤติกรรมเชิงภูมิสารสนเทศ
- ตอนแรกทดสอบด้วยการสร้าง geofence รอบบ้าน
- วิธีเดินออกไปทดสอบจริงตอน 5 ทุ่มกลายเป็นภาระอย่างรวดเร็ว
- ไม่ควรลดการทดสอบในสภาพแวดล้อมจริง
- ก่อนแข่ง ส่วนใหญ่ทดสอบด้วยการรันฟังก์ชันบน local workstation
- ความสำเร็จบน local ทำให้มั่นใจผิด ๆ ว่าจะทำงานได้ถูกต้องในสภาพแวดล้อม Lambda ด้วย
- หากกังวลว่าพิซซ่า Casey's จะหมด อีกวิธีคือทิ้งระยะห่างจากกลุ่มหน้าให้มากกว่า 30 นาที เพื่อให้ร้านมีเวลาทำพิซซ่าหั่นชิ้นชุดใหม่
- โค้ดเปิดเผยอยู่บน GitHub: https://github.com/mattdsteele/spot-tracker-tracker/…
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
Colin สามารถทำพิซซ่าให้ได้ด้วยระหว่างส่งของ: https://youtu.be/YjyJRTM0knE?si=fes2lbRntUlciPSH
จุดบกพร่องร้ายแรงของแผนที่ดูไร้ช่องโหว่คือ เวลา truck วิ่งผ่านหลุมบ่อบนถนน พิซซ่าจะปลิวไปมาและเสีย topping ไปหมด: https://gizmodo.com/zume-softbank-ai-pizza-delivery-stellar-...
วิดีโอนี้ทำให้ผมหัวเราะดังที่สุดในบรรดาที่ดูบน YouTube ปีนี้
จนตอนนี้ก็ยังตัดสินไม่ได้ และแปลกที่มันทำให้ดูยากขึ้น แน่นอนว่าเขาคงไม่ปล่อยวิดีโอที่มีอะไรผิดพลาดหนัก ๆ ออกมาหรอก
ผมนั่งดูวิดีโอที่คนนี้ ขุดอุโมงค์จากบ้านไปโรงเก็บของ อยู่ 2 ชั่วโมงครึ่ง เป็นช่องที่สนุกจริง ๆ
เยี่ยมมาก ให้ความรู้สึกเหมือนการตีความ pizzatool ในแบบศตวรรษที่ 21
https://donhopkins.medium.com/the-story-of-sun-microsystems-...
เกร็ดอีกอย่างคือ ร้านพิซซ่า Waypoint Pizza ใน Tiburon ถ้าขอเขาดี ๆ เขาส่งถึงบนผืนน้ำของ San Francisco Bay ได้ด้วย มีประโยชน์มากเวลามีแข่งเรือใบแปลก ๆ แบบไม่ค่อยจริงจัง เช่น Three Bridge Fiasco
Dean Karnazes เคยทำอะไรคล้าย ๆ กันในการแข่งอัลตร้ารันนิ่งโดยไม่ใช้เทคโนโลยี
ว่ากันว่าเขา ม้วนพิซซ่าเหมือนบูร์ริโต แล้วถือวิ่งไปด้วย: https://gffmag.com/the-raw-endurance-of-ultramarathon-man-de...
ถ้าเป็นเว็บไซต์ React ก็มีความเป็นไปได้สูงว่าหมายถึงมี API ที่เรียกใช้ได้โดยตรง
อาจต้องล็อกอินเพื่อเอา token แต่แบบนั้นแข็งแรงกว่ามาก
ถูกกว่ามากและแข็งแรงกว่ามาก หรือว่าผมพลาดอะไรไป?
ผมสนุกกับบทความนี้มากจริง ๆ
มีองค์ประกอบดี ๆ เยอะ ทั้งปัญหาทางเทคนิคที่น่าสนุก พิซซ่า การทำให้ผมต้องไปค้นว่า “s-tier” หมายถึงอะไร แค่ premise ก็ขำแล้วแต่ยังมีมุกเพิ่มอีก รวมถึง mea culpa ตอนท้ายและการคาดเดาสาเหตุของบั๊ก ทฤษฎีนั้นก็ดูมีเหตุผลดี แม้จะยังไม่แน่ชัด
รู้สึกเหมือนรวมข้อเสียของเทคโนโลยีสมัยใหม่ไว้ทั้งหมด
พูดตรง ๆ ว่าค่อนข้างเจ๋งเลย สงสัยว่าจะทำอะไรคล้าย ๆ กันกับบริการอย่าง Deliveroo ได้ไหม
ถ้าในวันที่กำหนด X เงื่อนไขตรงกัน เช่น ตอนทำงานดึก แล้วอยู่ห่างจากบ้านประมาณ Z ก็สั่งเมนู Y ที่ตั้งไว้ล่วงหน้า ดูเหมือนน่าจะทำได้
มีเหตุผลอะไรที่ไม่ทำให้การสั่งอาหารและจ่ายเงินผสานเข้ากับการ hack แบบ IFTTT ได้ง่าย ๆ บ้างไหม?
มีความทรงจำดี ๆ กับการโตมากับการกิน Casey's pizza
ทุกครั้งที่กลับไป Midwest ก็จะซื้อกิน อธิบายให้ชัดว่ายังไงยาก แต่มันมี เสน่ห์เฉพาะตัว อยู่
อ้อ สุดท้ายก็ไม่ทำงานสินะ
ถ้ารู้ตอนอยู่ที่ ไมล์ที่ 200 ก็คงหนักเอาเรื่อง
ซอฟต์แวร์ จักรยาน พิซซ่า นี่คือสิ่งที่ชอบในชีวิตเลย
ผมอ่านโปรเจกต์และบทความนี้อย่างสนุกมาก และยังทำให้นึกไอเดียคล้าย ๆ กันออกด้วย
ถ้าเป็นผมคง โทรแบบ hands-free หรือขอให้เพื่อนช่วยโทร แล้ว trigger ด้วยข้อความแทน
แล้วก็เรียกว่า “ส่ง” อยู่เรื่อย ๆ แต่จริง ๆ แล้วมันเป็น pickup ไม่ใช่เหรอ?