จาก Popclient สู่ Fetchmail

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

เป็นเวลาหลายสัปดาห์ ที่ผมได้ปรับปรุงต่อเติม fetchmail โดยรู้สึกว่าส่วนติดต่อนั้นทำงานได้ดี แต่ดูรกรุงรัง ไม่สวยและมีตัวเลือกหยุมหยิมเต็มไปหมด ผมรำคาญตัวเลือกที่ให้โยนเมลที่ดึงมาไปลงแฟ้ม mailbox หรือเอาต์พุตมาตรฐาน แต่ก็ไม่รู้เหมือนกันว่าทำไม

(ถ้าคุณไม่สนเรื่องทางเทคนิคของการส่งเมลในอินเทอร์เน็ต ก็อ่านข้ามสองย่อหน้าถัดไปนี้ได้เลย)

สิ่งที่ผมเห็นเมื่อคิดถึงการส่งเมลต่อไปยัง SMTP ก็คือ popclient นั้นพยายามทำงานหลายอย่างเกินไป มันถูกออกแบบให้เป็นทั้งโปรแกรมจัดส่งเมลภายนอก (mail transport agent – MTA) และโปรแกรมกระจายเมลภายในเครื่อง (local delivery agent – MDA) เมื่อมีความสามารถในการส่งเมลต่อไปยัง SMTP แล้ว มันก็ควรจะเลิกทำตัวเป็น MDA และเป็นเพียง MTA เพียงอย่างเดียว แล้วโอนหน้าที่ในการกระจายเมลในเครื่องไปให้โปรแกรมอื่น เหมือนกับที่ sendmail ทำอยู่

ทำไมต้องไปยุ่งกับรายละเอียดในการตั้งค่าการกระจายเมล หรือการล็อคกล่องเมลก่อนเขียนต่อท้าย ในเมื่อแทบจะแน่ใจได้ว่ามีพอร์ต 25 ให้ใช้ในทุกแพล็ตฟอร์มที่สนับสนุน TCP/IP อยู่แล้ว? โดยเฉพาะอย่างยิ่ง เมื่อการใช้พอร์ตดังกล่าวยังรับประกันได้ว่าจะทำให้เมลที่ดึงมานั้น ดูเหมือนเมล SMTP ปกติที่รับมาจากผู้ส่งโดยตรง ซึ่งเป็นสิ่งที่เราต้องการจริงๆ อยู่แล้ว

(กลับสู่เรื่องเดิม...)

ถึงแม้คุณจะไม่ได้ติดตามศัพท์แสงทางเทคนิคในย่อหน้าก่อน แต่ก็ยังมีบทเรียนที่สำคัญหลายบทสำหรับเรื่องนี้ สิ่งแรกก็คือ การส่งเมลต่อไปยัง SMTP เป็นผลลัพธ์ที่ดีที่สุดที่ผมได้รับจากการเลียนแบบวิธีพัฒนาของไลนัสอย่างจงใจ ผู้ใช้คนหนึ่งได้ให้แนวคิดสุดยอดอันนี้ สิ่งที่ผมต้องทำคือเข้าใจความหมายและสิ่งที่จะตามมา

11. สิ่งที่ดีที่สุดรองจากการมีแนวคิดดีๆ ก็คือการตระหนักถึงแนวคิดที่ดีจากผู้ใช้ของคุณ บางครั้ง การตระหนักดังกล่าวก็ถือว่าสำคัญกว่า

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

(ตอนที่ผมพูดบนเวทีในงาน Perl Conference เดือนสิงหาคมปี 1997 ลาร์รี วอลล์ แฮ็กเกอร์ผู้ยิ่งยงนั่งอยู่แถวหน้า เมื่อผมพูดถึงเรื่องในย่อหน้าที่ผ่านมา เขาตะโกนขึ้นราวกับเสียงปลุกเร้าของนักบุญ ว่า "บอกเขาไป บอกเขาไปให้หมด เพื่อน!" ผู้ฟังทั้งหมดหัวเราะครืน เพราะรู้ว่าเรื่องนี้เกิดกับเขาซึ่งเป็นผู้สร้างภาษา Perl ด้วย)

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

แต่ยังมีบทเรียนพื้นฐานที่ไม่เกี่ยวกับการเมืองอีกสองข้อ ที่เกี่ยวกับการออกแบบทุกชนิดโดยทั่วไป

12. บ่อยครั้งที่วิธีการที่เฉียบแหลมและแปลกใหม่ จะมาจากการตระหนักว่า คุณมองปัญหานั้นผิดมาตลอด

ผมเคยพยายามแก้ปัญหาผิดประเด็น โดยการพัฒนา popclient ให้เป็นทั้ง MTA/MDA ในตัวเดียวกันต่อไป พร้อมกับโหมดการกระจายเมลแบบต่างๆ ภายในเครื่อง แต่การออกแบบ fetchmail ต้องเริ่มคิดใหม่แต่ต้นให้เป็น MTA ล้วนๆ โดยเป็นส่วนหนึ่งของเส้นทางเมลในอินเทอร์เน็ตผ่านโพรโทคอล SMTP

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

เอาล่ะ ผมได้มองปัญหาของผมใหม่ ชัดเจนว่าสิ่งที่ควรทำคือ (1) เพิ่มการส่งเมลต่อไปยัง SMTP เข้าไปในไดรเวอร์ทั่วไป (2) ทำให้มันเป็นโหมดปริยาย และ (3) เอาโหมดอื่นๆ ออกไปในที่สุด โดยเฉพาะ โหมดกระจายไปยังแฟ้ม (deliver-to-file) และโหมดกระจายไปยังเอาต์พุตมาตรฐาน (deliver-to-standard-output)

ผมลังเลที่จะทำขั้นที่ 3 อยู่ระยะหนึ่ง เพราะกลัวว่าจะทำให้ผู้ที่ใช้ popclient มานานที่อาจจะใช้วิธีกระจายเมลแบบอื่นอยู่ไม่พอใจ ตามทฤษฎีแล้ว เขาสามารถเปลี่ยนไปแก้แฟ้ม .forward (หรือแฟ้มอื่นๆ ที่เทียบเท่าถ้าไม่ใช้ sendmail) ได้ทันที โดยได้ผลเหมือนเดิม แต่ในทางปฏิบัติ การเปลี่ยนดังกล่าวอาจจะยุ่งยาก

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

นอกจากนั้น โอกาสเดียวที่จะทำเมลหายก็หมดไปอีกด้วย เดิมที ถ้าคุณระบุให้กระจายไปยังแฟ้ม (delivery-to-file) และเนื้อที่ดิสก์เกิดเต็มขึ้นมา เมลนั้นจะหายไป แต่สิ่งนี้จะไม่เกิดขึ้นกับการส่งต่อไปยัง SMTP เพราะว่าโปรแกรมรับเมลแบบ SMTP จะไม่ยอมตกลงจนกว่าเมลจะถูกกระจายไปเรียบร้อย หรืออย่างน้อยก็ส่งเข้าที่พักไว้ รอการกระจายต่อในภายหลัง

เรื่องประสิทธิภาพก็ยังสูงขึ้นอีกด้วย (แม้จะไม่รู้สึกในการทำงานครั้งเดียว) ผลดีอีกอย่างที่ไม่สำคัญเท่าไร คือคู่มือวิธีใช้ (man page) ดูง่ายลงมาก

ต่อมาภายหลัง ผมต้องนำส่วนกระจายเมลผ่าน MDA ที่ผู้ใช้กำหนดกลับมาอีก เพื่อจัดการกับบางสถานการณ์ที่เกี่ยวกับ SLIP แต่ผมพบวิธีที่ง่ายกว่าเดิมมากในการเพิ่มมันเข้าไป

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

13. ``ความสมบูรณ์แบบ (ในการออกแบบ) จะได้มาไม่ใช่เมื่อไม่มีอะไรจะเพิ่ม แต่จะได้มาเมื่อไม่มีอะไรจะเอาออกต่างหาก''

เมื่อโค้ดขของคุณดีขึ้นและเรียบง่ายขึ้น เมื่อนั้นแหละที่คุณจะรู้สึกว่ามัน ใช่ และในกระบวนการนี้ การออกแบบของ fetchmail ได้สร้างเอกลักษณ์ของตัวเอง ซึ่งแตกต่างไปจาก popclient เดิม

มันถึงเวลาที่จะเปลี่ยนชื่อซะที การออกแบบแบบใหม่ดูเหมือนกับเป็นคู่ของ sendmail มากกว่าที่ popclient เดิมเคยเป็น โปรแกรมทั้งคู่เป็น MTA แต่ในขณะที่ sendmail จะผลักออกไปแล้วกระจาย แต่ popclient ตัวใหม่จะดึงเข้ามาแล้วกระจาย สองเดือนถัดมา ผมเปลี่ยนชื่อมันเป็น fetchmail

มีบทเรียนทั่วๆ ไปอีกข้อจากเรื่องเกี่ยวกับวิธีที่การกระจายเมลแบบ SMTP กลายมาเป็น fetchmail นี้ คือบทเรียนที่ว่า ไม่ใช่แค่การตรวจบั๊กเท่านั้น ที่ทำขนานกันได้ แต่การพัฒนาและการสำรวจความเป็นไปได้ของการออกแบบก็ทำขนานได้ (ในระดับที่น่าประหลาดใจ) เช่นกัน เมื่อการพัฒนาของคุณมีรูปแบบวนรอบอย่างรวดเร็ว การพัฒนาและเพิ่มความสามารถจะกลายเป็นการแก้บั๊กกรณีพิเศษ นั่นคือ `บั๊กเนื่องจากสิ่งที่ขาดไป' ในคุณสมบัติหรือแนวคิดเริ่มแรกของตัวซอฟต์แวร์

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