Production Graceful Shutdown
Production darajasidagi muloyim to'xtash
Oldingi darsda bitta worker uchun graceful shutdown ko'rgan edik. Haqiqiy serverda esa bu jarayon biroz kengroq: server "to'xtash signali"ni kutadi, signal kelganda yangi so'rovlarni qabul qilishni to'xtatadi, so'ng hozirgi faol so'rovlar tugashini kutadi, va faqat shundan keyin dastur butunlay yopiladi.
package main
import (
"context"
"fmt"
"time"
)
type Server struct{}
func (s *Server) Shutdown(ctx context.Context) error {
done := make(chan struct{})
go func() {
// haqiqiy loyihada: faol so'rovlar tugashini kutish
time.Sleep(5 * time.Millisecond)
close(done)
}()
select {
case <-done:
return nil
case <-ctx.Done():
return ctx.Err()
}
}
func main() {
srv := &Server{}
stop := make(chan struct{})
go func() {
time.Sleep(1 * time.Millisecond)
close(stop) // haqiqiy loyihada: bu OS signalidan (Ctrl+C) kelardi
}()
<-stop
fmt.Println("to'xtatish signali keldi")
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
fmt.Println("xato:", err)
return
}
fmt.Println("server to'xtatildi")
}Haqiqiy loyihada stop kanali odatda os/signal paketi orqali operatsion tizimning "Ctrl+C" (SIGINT) yoki "deploy tizimidan to'xtatish" (SIGTERM) signalidan keladi — biz buni bu yerda oddiy time.Sleep bilan simulyatsiya qildik, chunki bizning muhitimizda haqiqiy OS signali yubora olmaymiz. Server.Shutdown(ctx) — bu naqsh aynan Go'ning standart kutubxonasidagi http.Server.Shutdown metodining o'zi ishlatadigan imzo: u ham contextni oladi, chunki "qancha vaqt kutish mumkinligi" chegarasi bo'lishi kerak.
Bu yerdagi select — "Graceful Shutdown Basics" darsidagi bilan bir xil g'oya, lekin teskari nuqtai nazardan: endi biz "barcha ish tugashini" (done) kutayapmiz, agar bu juda uzoq davom etsa (ctx muddati tugasa), majburan to'xtatib, xato qaytaramiz — "cheksiz kutib qolmang" degan xavfsizlik chegarasi.
>_ Exercise
Shutdown vaqti chegaradan oshib ketgan holatni sinab ko'ring.
- •Server.Shutdown ichidagi time.Sleep'ni 200 millisekundga o'zgartiring (juda uzoq)
- •context timeout'ni 50 millisekundga o'zgartiring
- •natijada Shutdown xato (context deadline exceeded) qaytarishi kerak
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Production graceful shutdown har doim vaqt chegarasiga (context timeout) ega bo'lishi kerak — aks holda "muloyim kutish" abadiy davom etib, dasturni umuman to'xtatib bo'lmay qolishi mumkin.
NEXT UP
Factory Pattern
$ go run main.go
Kodingizni ishga tushiring