วันนี้ทำการเขียน RESTful API ด้วยภาษา Go
ซึ่งมีการใช้ข้อมูลร่วมกัน จัดเก็บในรูปแบบของ map
การทำงานนั้นเป็นปกติมาก ๆ
แต่เมื่อทำการลองยิง performance ดูหน่อยเท่านั้น
ก็เจอ Runtime error ดังนี้
fatal error: concurrent map read and map write
เริ่มจาก code ที่เป็นปัญหาดังนี้
ซึ่งใช้งานข้อมูลจากตัวแปรชนิด map
[gist id="c306d337225ebe020e0336942e86409f" file="1.go"]เป็น code ชุดที่เกิดปัญหานั่นเอง
ก็ลองไปหาต้นเหตุ ก็เจอว่า map นั้น
ไม่ปลอดภัยสำหรับการแก้ไขข้อมูลพร้อม ๆ กัน
แต่ถ้าอ่านอย่างเดียวไม่เป็นไร
การแก้ไขปัญหานี้แบบง่าย ๆ คือ
ถ้าทำการแก้ไขพร้อม ๆ กัน
ดังนั้นก็ lock/unlock หรือ Mutex กันไปเลย
สามารถแก้ไขปัญหาได้ แต่แลกมาด้วยความเร็วที่ช้าลง
แต่เป็นวิธีการที่ง่ายนะ เขียน code ได้ดังนี้
เพิ่มนิดเดียว
หรืออาจจะนำ go channel เข้ามาใช้เพื่อแก้ไขปัญหานี้ก็ได้นะ
ซึ่งก็เพิ่มความซับซ้อนขึ้นมาอีกหน่อย ดังนี้
[gist id="c306d337225ebe020e0336942e86409f" file="3.go"]หรืออาจจะใช้ sync map ที่ทาง Go ได้เตรียมมาให้
ก็สามารถแก้ไขปัญหาได้เช่นกัน
[gist id="c306d337225ebe020e0336942e86409f" file="4.go"]ทั้งสามวิธีสามารถแก้ไขปัญหาได้
มาดูผลการทดสอบ performance ทั้งสองกันบ้าง
[gist id="c306d337225ebe020e0336942e86409f" file="compare.txt"]ขอให้สนุกกับการเขียน code นะครับ