इस पेज में, मैं Handler
इंटरफेस के डिज़ाइन की व्याख्या करूँगा।
आप जो सर्वर को प्रदान करते हैं, वह आपके असंक्रमिक कार्य हैंडलिंग तार्किकी का मूल है। हैंडलर की जिम्मेदारी है कि वह टास्क को स्वीकार करें और संदर्भ को ध्यान में रखते हुए इसे प्रसंस्कृत करें। यदि प्रसंस्करण विफल होता है, तो बाद में कार्य को पुनः प्रयास के लिए त्रुटियों की सूचना देनी चाहिए।
इंटरफेस इस प्रकार से परिभाषित की जाती है:
type Handler interface {
ProcessTask(context.Context, *Task) error
}
यह एक सरल इंटरफेस है, जो एक हैंडलर की जिम्मेदारियों का संक्षेप से वर्णन करता है।
इस हैंडलर इंटरफेस को अंगीकृत करने के कई तरीके हैं।
यहां आपको अपनी स्वयं की संरचना प्रकार को परिभाषित करने का एक उदाहरण है जो कि कार्यों को संभालने के लिए है:
type MyTaskHandler struct {
// ... फ़ील्ड
}
// ProcessTask विधि को कैसे लागू करें
func (h *MyTaskHandler) ProcessTask(ctx context.Context, t *asynq.Task) error {
// ... कार्य का संभाल तार्किक
}
आप इंटरफ़ेस को संतुष्ट करने के लिए एक फ़ंक्शन भी परिभाषित कर सकते हैं, धन्यवाद HandlerFunc
एडैप्टर प्रकार के:
func myHandler(ctx context.Context, t *asynq.Task) error {
// ... कार्य का संभाल तार्किक
}
// h जिम्मेदारी पूर्व प्रकार को संतुष्ट करता है
h := asynq.HandlerFunc(myHandler)
अधिकांश मामलों में, आपको इनपुट कार्य के Type
की जांच करने और उसके अनुसार संभालने की आवश्यकता होती है।
func (h *MyTaskHandler) ProcessTask(ctx context.Context, t *asynq.Task) error {
switch t.Type() {
case "type1":
// type1 संभालना
case "type2":
// type2 संभालना
case "typeN":
// typeN संभालना
default:
return fmt.Errorf("अप्रत्याशित कार्य प्रकार: %q", t.Type())
}
}
जैसा कि आप देख सकते हैं, एक हैंडलर कई विभिन्न हैंडलर से संयोजित हो सकता है। उपरोक्त उदाहरण में प्रत्येक मामला, एक समर्पित हैंडलर द्वारा संभाला जा सकता है। यहाँ ServeMux
प्रकार का उपयोग होता है।
नोट: आपको आवश्यकता नहीं होती कि आप हैंडलर को लागू करने के लिए ServeMux
प्रकार का उपयोग करें, लेकिन यह बहुत से मामलों में बहुत उपयोगी हो सकता है।ServeMux
का उपयोग करके, आप कई हैंडलर पंजीकृत कर सकते हैं। यह प्रत्येक कार्य के प्रकार का संबंधित पैटर्न के साथ मिलाता है और उस पैटर्न के पास कार्यक्षेत्र के नाम के निकटतम के हैंडलर को बुलाएगा।
mux := asynq.NewServeMux()
mux.Handle("email:welcome", welcomeEmailHandler) // हैंडलर पंजीकृत करें
mux.Handle("email:reminder", reminderEmailHandler)
mux.Handle("email:", defaultEmailHandler) // "email:" से शुरू होने वाले अन्य कार्य प्रकारों के लिए डिफ़ॉल्ट हैंडलर
मध्यस्थ का उपयोग
यदि आपको अनुरोध को संभालने से पहले और/या बाद में कुछ कोड को निष्पादित करने की आवश्यकता है, तो आप मध्यस्थ के साथ इसे प्राप्त कर सकते हैं। मध्यस्थ एक फ़ंक्शन है जो एक Handler
लेता है और एक Handler
लौटाता है।
नीचे एक उदाहरण है जो सार्वजनिक करता है जो कि कार्य प्रसंस्करण की शुरूआत और समापन का लॉग करता है।
func loggingMiddleware(h asynq.Handler) asynq.Handler {
return asynq.HandlerFunc(func(ctx context.Context, t *asynq.Task) error {
start := time.Now()
log.Printf("%q के लिए प्रसंस्कृति शुरू हुई", t.Type())
err := h.ProcessTask(ctx, t)
if err != nil {
return err
}
log.Printf("%q के लिए प्रसंस्कृति पूरी हुई: बीते समय = %v", t.Type(), time.Since(start))
return nil
})
}
अब आप इस मध्यस्थ का उपयोग अपने हैंडलर को “रैप” करने के लिए कर सकते हैं।
myHandler = loggingMiddleware(myHandler)
इसके अतिरिक्त, यदि आप ServeMux
का उपयोग कर रहे हैं, तो आप इस तरह से मध्यस्थ प्रदान कर सकते हैं।
mux := NewServeMux()
mux.Use(loggingMiddleware)
समूहित मिडलवेयर
यदि आपके पास ऐसी स्थिति है जहाँ आप कुछ कार्यों पर मिडलवेयर लागू करना चाहते हैं, तो आप इसे कई ServeMux
इंस्टेंस को कम्बाइन करके प्राप्त कर सकते हैं। एक प्रतिबंध है कि प्रत्येक समूह के कार्यों के टाइप नाम में समान प्रिफ़िक्स होना चाहिए।
उदाहरण:
यदि आपके पास ऑर्डर हैंडल करने के लिए कार्य और उत्पाद हैंडल करने के लिए कार्य हैं, और आप सभी “उत्पाद” के कार्यों पर साझा तरीके से और सभी “आर्डर” के कार्यों पर दूसरे साझा तरीके से लागू करना चाहते हैं, तो आप इसे इस प्रकार से कर सकते हैं:
productHandlers := asynq.NewServeMux()
productHandlers.Use(productMiddleware) // सभी उत्पाद कार्यों पर साझा तरीके से लॉजिक लागू करें
productHandlers.HandleFunc("product:update", productUpdateTaskHandler)
// ... अन्य "उत्पाद" कार्य हैंडलर रजिस्टर करें
orderHandlers := asynq.NewServeMux()
orderHandler.Use(orderMiddleware) // सभी आर्डर कार्यों पर साझा तरीके से लॉजिक लागू करें
orderHandlers.HandleFunc("order:refund", orderRefundTaskHandler)
// ... अन्य "आर्डर" कार्य हैंडलर रजिस्टर करें
// शीर्ष स्तर का हैंडलर
mux := asynq.NewServeMux()
mux.Use(someGlobalMiddleware) // सभी कार्यों पर साझा तरीके से लॉजिक लागू करें
mux.Handle("product:", productHandlers)
mux.Handle("order:", orderHandlers)
if err := srv.Run(mux); err != nil {
log.Fatal(err)
}