[Golang] ตั้งสติ ก่อน panic
ใน gobyexample ได้อธิบายเรื่องของ Panic ไว้ดังนี้
A
panic
typically means something went unexpectedly wrong. Mostly we use it to fail fast on errors that shouldn’t occur during normal operation, or that we aren’t prepared to handle gracefully.
นั่นแปลว่า ถ้าใช้คำสั่งนี้ โปรแกรมมันจะปลิว…
เช่น
func main() {
panic("test")
x := "test"
const y = "1"
type Direction int
const (
a Direction = iota
b
c
)
fmt.Println("Hello", "world", x, y, c)
}
ถ้าวิ่งแบบนี้มันจะอออกจากโปรแกรม เมื่อวิ่งเจอทันที
❯ go run main.go
panic: testgoroutine 1 [running]:
main.main()
/Users/bomb/Documents/playground/go_study/hello/main.go:12 +0x30
exit status 2
นอกจากนี้คำสั่งอย่าง log.Fatal หรือ log.Panic ก็มีพฤติกรรมที่คล้ายกัน คือแสดง Error แล้ว ก็ออก เพียงแต่ Fatal มันจะไม่แสดง Stack ขึ้นมาเท่านั้นเอง
ตัวอย่างนี้คือ log.Fatalln
>go run main.go
2022/04/30 20:54:56 test
exit status 1
ส่วนอันนี้คือ log.Panicln
❯ go run main.go
2022/04/30 20:55:06 test
panic: testgoroutine 1 [running]:
log.Panicln({0x14000066f08?, 0x14000002228?, 0x14000066f28?})
/usr/local/go/src/log/log.go:399 +0x68
main.main()
/Users/bomb/Documents/playground/go_study/hello/main.go:13 +0x48
exit status 2
ดังนั้น คำสั่งนี้ไม่ควรจะใช้ ในเหตุการณ์ที่ไม่จำเป็นต้องออกจริงๆ เช่น
Validation Business Flow Fail ซึ่งมันใช้แค่ error/ warn ก็ได้แล้ว
ส่วนที่มาทำไม มีคำสั่งลักษณะนี้ ต้องเล่าว่า แต่ก่อนในภาษา C จะมีคำสั่งขาโหดอยู่ตัวหนึ่งชื่อว่า Assert
คำสั่งนี้ ตามชื่อ ก็มาจาก Assertion คือ การยืนยันว่า ค่าๆ นี้จะเป็นแบบนี้เสมอ ตามความคิดของผู้พัฒนา
ซึ่งถ้ามันผิดไปจากนี้ ระบบอาจจะทำงานผิดพลาดที่เราคาดไม่ถึง
หรือว่า อยู่ในสถานะที่ผู้เขียนโปรแกรม คิดว่ามันเป็นไปไม่ได้ที่จะเกิด แต่กัน Surprise ถ้ามาตรงนี้จริง จงตายซะ แล้วแสดงข้อมูลตำแหน่งมาให้ด้วย จะได้หาวิธีจัดการต่อไป
ทีนี้หลายคนอาจจะคิดว่า ก็ในเมื่อโลกปัจจุบันมันเป็น Cloud Native มี K8s / มี Docker ช่วย ถึง panic ไป มันก็ restart ขึ้นมาให้อยู่ดี
ใช่ครับมันช่วย แต่มันใช้เวลากี่วินาทีถึงจะกลับมา 1–5 วิ แล้วแต่สถานการณ์ ถ้าเป็นงานทีคนเข้า วันละครั้งมันไม่มีผลอะไรแน่นอน แต่ถ้าเข้า วินาทีละ 50000 แปลว่า เรา เสียโอกาส 5*50000 ครั้งเลยนะครับ กับการแค่ Panic ทิ้งๆขว้างๆ ไม่สนใจ context
ดังนั้น สิ่งสำคัญ นอกเหนือว่า รู้ว่ามีคำสั่งอะไร ทั้งตระกูล panic , fmt, หรือ log สิ่งสำคัญคือ รู้ว่าเมื่อไหร่ ควรจะใช้อะไร
ตรงนี้ต้องมากางตารางเอา case มาดูกัน ว่าเคสนี้ impact มากน้อยแค่ไหน ส่งผลต่อระบบยังไง แล้วถึงเลือกว่าควรจะใช้ท่าไหน
บางที Efficiency เบื้องต้นก็ดูแค่ว่า เวลาที่เราหกล้มในกรณีต่างๆ เราลุกขึ้นช้าเร็ว เพื่อจะมาสู้ใหม่ ยังไงและเร็วแค่ไหน เท่านั้นเอง