এই পৃষ্ঠাতে, আমি Handler ইন্টারফেস এর ডিজাইন সম্পর্কে ব্যাখ্যা করব।

আপনি যদি একটি ব্যবহারকারীর সার্ভারে প্রদান করেন তাহলে উনির জন্য আসলে আপনার অসমযোজী কাজের লজিক এর কোর টা হল একটি হ্যান্ডলার। হ্যান্ডলারের দায়িত্ব হল একটি কাজকে গ্রহণ করা এবং প্রসেসিং করা যেহেতু কনটেক্সট বিবেচনা করা হয়। যদি প্রসেসিং ব্যর্থ হয়, তবে পরে কোন ভুল রিপোর্ট করতে হবে।

ইন্টারফেসটি নিম্নলিখিত ভাবে সংজ্ঞায়িত আছে:

type Handler interface {
    ProcessTask(context.Context, *Task) error
}

এটি একটি সহজ ইন্টারফেস, সংক্ষেপে হ্যান্ডলারের দায়িত্বগুলি বর্ণনা করছে।

এই হ্যান্ডলার ইন্টারফেস প্রায়ই বিভিন্ন উপায়ে অনুষ্ঠিত করা যেতে পারে।

নিচে উল্লেখ করা হল একইসাথে আপনার নিজের স্ট্রাক্ট ধরনের অসমযোজী কাজ করা সংদর্শবান ।

type MyTaskHandler struct {
   // ... fields
}

// Implement the ProcessTask method
func (h *MyTaskHandler) ProcessTask(ctx context.Context, t *asynq.Task) error {
   // ... task handling logic
}

আপনি ইন্টারফেসের প্রয়োজন অনুযায়ী একটি ফাংশনও পরিভাষা করতে পারেন, HandlerFunc অ্যাডাপ্টার টাইপের ধন্যবাদ।

func myHandler(ctx context.Context, t *asynq.Task) error {
    // ... task handling logic
}

// h satisfies the Handler interface
h := asynq.HandlerFunc(myHandler)

সাধারণভাবে, আপনার দেওয়া সময় চেক করা থাকবে কাজের টাস্ক এর Type এবং সেটি অনুযায়ী কাজ করা যাবে।

func (h *MyTaskHandler) ProcessTask(ctx context.Context, t *asynq.Task) error {
   switch t.Type() {
   case "type1":
      // handle type1
   case "type2":
      // handle type2
   case "typeN":
      // handle typeN
   default:
      return fmt.Errorf("unexpected task type: %q", t.Type())
   }
}

আপনি দেখতে পাচ্ছেন, একটি হ্যান্ডলার অনেক বিভিন্ন হ্যান্ডলারে তৈরি করা যাতে পারে। উপরোক্ত উদাহরণে প্রত্যেক মামলাকে একটি সম্পর্কিত হ্যান্ডলার দ্বারা হ্যান্ডেল করা যেতে পারে। এটা হলServeMux এর ব্যবহারের জন্য।

নোট: আপনাকে আবশ্যকতামত না হলেও, হ্যান্ডলার ইমপ্লিমেন্ট করার জন্য ServeMux ব্যবহার করা ছাড়া ভালো হতে পারে।
ServeMux ব্যবহারের মাধ্যমে, আপনি একাধিক হ্যান্ডলার রেজিস্টার করতে পারেন। এটি প্রত্যেক টাস্কের টাইপ ম্যাচ করে রেজিস্টার করা প্যাটার্ন এবং টাস্ক টাইপ নাম নির্ধারণ করা নিকটতম প্যাটার্নের সাথে মিলাতে হবে।

mux := asynq.NewServeMux()
mux.Handle("email:welcome", welcomeEmailHandler) // Register handler
mux.Handle("email:reminder", reminderEmailHandler)
mux.Handle("email:", defaultEmailHandler) // Default handler for other task types starting with "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("Processing started for %q", t.Type())
        err := h.ProcessTask(ctx, t)
        if err != nil {
            return err
        }
        log.Printf("Processing completed for %q: elapsed time = %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)
}