Steven
Steven2 นาทีที่อ่าน

ซอฟต์แวร์ที่นิ่ง: กำจัดปุ่มสวิตช์ที่กะพริบ และสอนแชตให้บอกว่ากำลังอยู่ในโหมดไหน

GeekBye ปล่อยอัปเดตเล็ก ๆ สองเวอร์ชัน ไม่มีฟีเจอร์เด่นอะไรเลย มีแค่ปุ่มสวิตช์ในหน้าตั้งค่าที่เลิกกะพริบ กับผู้ช่วยแชตที่ในที่สุดก็บอกคุณได้แล้วว่ามันตอบในโหมดประชุมหรือโหมดเขียนโค้ด นี่คือราคาที่แท้จริงของคำว่า "ซอฟต์แวร์ที่นิ่ง" ทีละรายละเอียด

ผลิตภัณฑ์
ดีไซน์
วิศวกรรม
GeekBye Releases
ซอฟต์แวร์ที่นิ่ง: กำจัดปุ่มสวิตช์ที่กะพริบ และสอนแชตให้บอกว่ากำลังอยู่ในโหมดไหน

ไม่ใช่ทุกอัปเดตจะเป็นเรื่องราวการต่อสู้อันยิ่งใหญ่ บางครั้งมันก็เป็นแค่รายการของสิ่งเล็ก ๆ ที่แทบมองไม่เห็น ซึ่งค่อย ๆ ผิดเพี้ยนอยู่เงียบ ๆ สิ่งที่ไม่ได้ทำให้อะไรพังลง แต่ทำให้แอปรู้สึกน่าเชื่อถือน้อยลงนิดหน่อย กระตุกนิดหน่อย เป็นของเราน้อยลงนิดหน่อย GeekBye v2.0.3 และ v2.0.5 คือสองอัปเดตแบบนั้น ไม่มีฟีเจอร์ใหม่ มีแค่ความนิ่ง

"ซอฟต์แวร์ที่นิ่ง" ฟังดูเหมือนอารมณ์อย่างหนึ่ง แต่จริง ๆ แล้วมันคือกองการตัดสินใจที่เจาะจงต่างหาก นี่คือสามอย่างในนั้น

ปุ่มสวิตช์ที่ตัดสินใจอะไรไม่ได้สักที

มีปุ่มสวิตช์ในหน้าตั้งค่าอยู่ตัวหนึ่ง ตัวที่ควบคุมการกู้คืนเสียง มันกะพริบทุกครั้งที่คุณกด แตะเปิดปุ๊บ ในเสี้ยววินาทีมันจะแสดงเป็น เปิด แล้วเด้งกลับไปเป็น ปิด แล้วค่อยนิ่ง เป็นอาการสะดุดทางสายตาเล็ก ๆ แต่ตาคุณจับได้ และมันสื่อความหมายว่า แอปไม่แน่ใจว่าตัวเองกำลังทำอะไรอยู่

สาเหตุคือ race ของ UI แบบคลาสสิกที่เรียกว่า optimistic update เมื่อคุณกดปุ่มสวิตช์ แอปมีสองทางเลือก จะรอให้ค่าตั้งค่าถูกบันทึกจริงก่อนแล้วค่อยอัปเดตปุ่ม (ถูกต้อง แต่รู้สึกหน่วง) หรือสลับปุ่มทันทีแล้วค่อยบันทึกเบื้องหลัง (รู้สึกฉับไว) GeekBye เลือกทางที่สอง สลับทันที แต่มัน ยัง อ่านค่าที่บันทึกไว้ซ้ำอีกครั้งเมื่อค่านั้นกลับมา ลำดับเหตุการณ์จึงเป็นแบบนี้ คุณกด ปุ่มสลับเป็นเปิดแบบ optimistic ค่าจริงที่บันทึกไว้ตามมาช้ากว่านั้นหนึ่งจังหวะ และในหนึ่งเฟรมนั้นทั้งสองค่าขัดแย้งกันจนปุ่มเด้งให้เห็น

การแก้คือทำให้ค่า optimistic กับค่าที่ยืนยันแล้วตรงกันอย่างสะอาด ปุ่มจะยึดกับสถานะที่คุณเลือกและเลิกกลับมาสงสัยตัวเองเมื่อการบันทึกยืนยันกลับมา นอกจากนั้น v2.0.3 ยังทำงานเก็บงานถ้อยคำที่ไม่หวือหวาอีกรอบ คำอธิบายของปุ่มกู้คืนเสียงถูกตัดให้สั้นลงเพื่อให้ยาวเท่ากับแถวข้าง ๆ และถ้อยคำในหน้าตั้งค่าก็ถูกเขียนให้เป็นภาษาคนมากขึ้น ไม่มีอะไรในนี้เป็นฟีเจอร์ แต่ทั้งหมดนี้คือความต่างระหว่างหน้าตั้งค่าที่รู้สึกว่า ถูกประกอบขึ้นมา กับหน้าที่รู้สึกว่า ถูกใส่ใจดูแล

ทัวร์ที่ไม่ยอมไปไหน

ทัวร์สำหรับผู้ใช้ใหม่มีประโยชน์เพียงครั้งเดียวเป๊ะ ๆ ปัญหาอยู่ที่ความ "ครั้งเดียว" นั่นแหละ หลังจากคุณดูมันจบแล้ว โอเวอร์เลย์แนะนำการใช้งานที่ปิดไม่ได้ก็กลายเป็นความรกที่ส่งสัญญาณว่า แอปนี้ยังคิดว่าคุณเป็นมือใหม่อยู่ v2.0.3 แก้ทั้งสองด้านของเรื่องนี้ ทัวร์แนะนำผลิตภัณฑ์ตอนนี้ ซ่อนได้ แล้ว และถ้าคุณอยากให้มันกลับมาจริง ๆ ก็มีปุ่ม เล่นทัวร์ซ้ำ แสดงมันตอนที่มันช่วยได้ หลบทางตอนที่มันไม่ช่วย และปล่อยให้ผู้ใช้เรียกมันขึ้นมาตามเงื่อนไขของตัวเอง การเคารพว่าผู้ใช้ไม่ใช่มือใหม่แล้วก็เป็นความนิ่งอีกรูปแบบหนึ่งในตัวมันเอง

ผู้ช่วยที่ไม่ยอมบอกว่าตัวเองกำลังคิดแบบไหน

อันนี้คือเรื่องที่สำคัญจริง ๆ และมันเชื่อมโยงกับปัญหาที่ลึกกว่านั้นซึ่งเราไล่ตามมาสักพักแล้ว

ผู้ช่วยของ GeekBye ตอบต่างกันขึ้นอยู่กับบริบท ในการประชุม คำถามว่า "คุณคิดยังไงกับเรื่องนี้?" ควรได้คำตอบเชิงสนทนาที่เข้าใจบริบทการประชุม ส่วนในเซสชันเขียนโค้ด คำเดียวกันควรได้คำตอบเชิงเทคนิค ดังนั้นเซิร์ฟเวอร์จึงส่งคำถามผ่านกรอบที่เหมาะสม เรียกมันว่า โหมดประชุม หรือ โหมดเขียนโค้ด และการตีกรอบนั้นเปลี่ยนคำตอบที่คุณได้จริง ๆ

ปัญหาคือแอปไม่เคยบอกคุณว่าโหมดไหนเป็นคนตอบ ดังนั้นเวลาผู้ช่วยตอบคำถามเชิงสนทนาด้วยคำตอบที่ออกแนวโค้ด หรือตอบคำถามโค้ดเหมือนคุณกำลังคุยเล่น มันดูเหมือน AI แค่ ตอบผิด เฉย ๆ แต่มันไม่ได้ผิด มันอยู่ในอีกโหมดหนึ่งต่างหาก และคุณไม่มีทางเห็นสิ่งนั้นเลย สถานะที่ถูกซ่อนไว้ทำให้พฤติกรรมที่ถูกต้องดูเหมือนพังอยู่ (ตัวตรรกะของโหมดเองเป็นงานชิ้นใหญ่กว่านั้น ตัวออร์เคสเทรเตอร์ที่ตัดสินใจว่าจะตอบคำถามที่ไม่เกี่ยวกับโค้ดอย่างไรระหว่างเซสชันเขียนโค้ด แต่ทั้งหมดนั้นไม่มีประโยชน์กับคุณเลยถ้าคุณ มองไม่เห็น การตัดสินใจที่มันทำ)

v2.0.5 เพิ่ม ป้ายโหมดแบบอ่านอย่างเดียว เข้าไปในแชต เป็นป้ายเล็ก ๆ ที่แสดงว่าผู้ช่วยตอบในโหมดประชุมหรือโหมดเขียนโค้ด ความเป็นอ่านอย่างเดียวคือหัวใจทั้งหมด มันไม่ใช่ปุ่มควบคุมที่คุณตั้งค่าได้ มันคือ หน้าต่างที่มองเข้าไปเห็นการตัดสินใจที่ระบบทำไปแล้ว คุณเลิกเดาว่าทำไมคำตอบถึงรู้สึกไม่เข้าท่า เพราะคุณเห็นกรอบที่มันมาได้

รายละเอียดที่ทำให้ป้ายนี้ซื่อตรง

นี่คือการตัดสินใจเชิงวิศวกรรมที่ควรค่าแก่การส่งต่อ เพราะมันคือสิ่งที่แยกตัวบ่งชี้ที่แปะเข้ามาแบบขอไปที ออกจากตัวบ่งชี้ที่ไว้ใจได้

ข้อมูลโหมดมาจากเซิร์ฟเวอร์ในฐานะส่วนหนึ่งของคำตอบที่สตรีมมา เป็นเฟรม mode เล็ก ๆ ในสตรีมของ server-sent event แต่ไคลเอนต์รุ่นเก่าที่มีมาก่อนฟีเจอร์นี้จะไม่รู้จักว่าเฟรม mode คืออะไร อย่างดีที่สุดมันก็เพิกเฉย อย่างแย่ที่สุดมันก็เรนเดอร์อะไรออกมาเละเทะ ไคลเอนต์จึงประกาศความสามารถของตัวเอง มันส่ง request header บอกว่า ฉันรู้วิธีแสดงป้ายโหมด และเซิร์ฟเวอร์จะส่งเฟรม mode เฉพาะไคลเอนต์ที่ส่ง header นั้นมาเท่านั้น ไคลเอนต์เก่าจะไม่มีวันได้รับสัญญาณที่มันจัดการไม่ได้ ส่วนไคลเอนต์ใหม่ก็ได้รับเฟรมที่มันขอมาพอดี

มันคือการจับมือกันด้วย header เพียงตัวเดียว และมันคือความต่างระหว่าง "เราเพิ่มฟีเจอร์" กับ "เราเพิ่มฟีเจอร์โดยไม่ทำให้คนที่ยังไม่ได้อัปเดตพังไปด้วย" การรีวิวรอบเดียวกันนี้ยังทำให้พฤติกรรมที่เหลือรัดกุมขึ้น ป้ายจะเคลียร์ตัวเองเมื่อรีเซ็ตและเมื่อบริบทของการสนทนาเปลี่ยนไป (ป้ายโหมดที่ค้างเก่าก็เป็นการโกหกเล็ก ๆ ในตัวมันเอง) และมันจะแสดงเฉพาะในหน้าแชตซึ่งเป็นที่ของมันเท่านั้น

สิ่งที่อัปเดตแบบ "ไม่มีฟีเจอร์" สองตัวนี้สอนเรา

  1. การกระตุกคือสัญญาณของความน่าเชื่อถือ ปุ่มสวิตช์ที่กะพริบ ปุ่มที่เด้งไปมา ป้ายที่ค้างอยู่นานเกินไปหนึ่งเฟรม ไม่มีอันไหนเป็นบั๊กในความหมายของการทำให้แอปพัง แต่ทุกอันกระซิบว่า แอปนี้ยังคุมตัวเองได้ไม่ค่อยอยู่ ความนิ่งคือการไม่มีเสียงกระซิบเหล่านั้น และคุณได้มันมาทีละ race condition
  2. โหมดที่ถูกซ่อนไว้ทำให้พฤติกรรมที่ถูกต้องดูเหมือนบั๊ก ผู้ช่วยทำสิ่งที่ถูกต้องแต่กลับโดนตำหนิ ล้วนเพราะผู้ใช้มองไม่เห็นกรอบ เมื่อระบบของคุณตัดสินใจอย่างมองไม่เห็นที่ไปเปลี่ยนผลลัพธ์ จงแสดงการตัดสินใจนั้น ป้ายแบบอ่านอย่างเดียวมักเป็นทางแก้ทั้งหมดในตัวมันเอง
  3. ฟีเจอร์ใหม่ควรมองไม่เห็นสำหรับไคลเอนต์ที่ใช้มันไม่ได้ การจับมือด้วย capability header ทำให้สัญญาณโหมดไปถึงเฉพาะไคลเอนต์ที่เรนเดอร์มันได้ ความเข้ากันได้ย้อนหลังไม่ใช่การเช็กเวอร์ชันที่แปะเข้ามาทีหลัง มันคือไคลเอนต์ที่บอกว่าตัวเองเข้าใจอะไร และเซิร์ฟเวอร์ที่เคารพคำตอบนั้น

นี่คืออัปเดตที่ไม่มีใครเอาไปเขียนพาดหัว changelog และมันคือส่วนสำคัญที่ทำให้ GeekBye v2 รู้สึกเป็นแบบที่มันเป็น สำหรับอัปเดตที่ความนิ่งนี้ถูกสร้างขึ้นมาบนนั้น อ่านได้ที่ เวอร์ชันสองต้องแลกมาด้วยอะไรบ้าง (v2.0.0) สำหรับงานด้านความเสถียรที่ทำควบคู่กันไป อ่าน วันที่แอปของเรา DDoS ใส่ตัวเอง (v2.0.1) และ ทำไมโปรแกรมจดประชุม AI ของคุณถึงหยุดอัดกลางคัน (v2.0.9)

บทความที่เกี่ยวข้อง

แอป Mac ของคุณอนุญาตให้ใช้ไมโครโฟน — แล้วลืมมันทุกครั้งที่เปิด
Steven
Steven2 นาทีที่อ่าน

แอป Mac ของคุณอนุญาตให้ใช้ไมโครโฟน — แล้วลืมมันทุกครั้งที่เปิด

GeekBye ขอสิทธิ์ไมโครโฟน คุณกดอนุญาต และมันก็ทำงานได้ พอเปิดครั้งถัดไป: หายไป และแอปไม่เคยโผล่ใน System Settings → Microphone เลยด้วยซ้ำ ตัวการคือฟีเจอร์ความปลอดภัยของ macOS ที่แอบรันแอปจากพาธที่หายวับไป — นี่คือการวินิจฉัยและการแก้แบบกดครั้งเดียวจบ

macOS
สิทธิ์การเข้าถึง
วิศวกรรม
เมื่อไฟร์วอลล์บล็อก WebSocket แล้วการถอดเสียงเรียลไทม์จะเป็นยังไง
Steven
Steven3 นาทีที่อ่าน

เมื่อไฟร์วอลล์บล็อก WebSocket แล้วการถอดเสียงเรียลไทม์จะเป็นยังไง

เครือข่ายองค์กรชอบปล่อย HTTPS ให้ผ่าน แต่แอบฆ่า WebSocket upgrade ทิ้งเงียบๆ ซึ่งทำให้การถอดเสียงเรียลไทม์พังแบบไร้เสียง GeekBye v2.0.8 จะ fall back ไปยัง transport แบบ HTTPS ล้วนโดยอัตโนมัติ — และระหว่างที่ทำมันออกมา เราก็เจอบั๊กที่จะทำให้ทั้งฟีเจอร์นี้ไร้ประโยชน์ไปเลย

ถอดเสียง
เครือข่าย
วิศวกรรม
ทำไมการบันทึกหน้าจอถึงจับมอนิเตอร์ผิดตัว (และวิธีที่เราแก้)
Steven
Steven2 นาทีที่อ่าน

ทำไมการบันทึกหน้าจอถึงจับมอนิเตอร์ผิดตัว (และวิธีที่เราแก้)

บนเครื่องที่ต่อสองจอ GeekBye บันทึกและแคปหน้าจอหลักเสมอ ไม่ว่าคุณจะทำงานอยู่บนจอไหน การแก้คือฟังก์ชันเล็กๆ ตัวเดียว — แต่เวอร์ชันแรกของมันผิด และ code review จับได้ว่าทำไม

บันทึกหน้าจอ
หลายจอ
วิศวกรรม