টাস্ক প্রক্রিয়া সীমাবদ্ধতা প্য়ারামিটার প্রয়োগ করার বিষয়ে asynq সার্ভার কনফিগারের উদাহরন

এই পাতা প্রদর্শন করে কিভাবে asynq সার্ভারকে কার্য প্রসেসিং রেট সীমাবদ্ধতা প্রয়োগ করতে হয়।

দয়া করে মনে রাখবেন এটি প্রতি সার্ভার ইনস্ট্যান্সের জন্য রেট সীমাবদ্ধতা, না সার্বজনিন রেট সীমাবদ্ধতা।

এই উদাহরণে, রেট সীমাবদ্ধতা উপস্থাপন করার জন্য আমরা golang.org/x/time/rate প্যাকেজটি ব্যবহার করব। আপনার সার্ভার আরম্ভণ সেটিংসে মূল কনফিগারেশনগুলি IsFailure এবং RetryDelayFunc। আমরা একটি কাস্টম ভুল টাইপ তৈরি করব এবং IsFailure এবং RetryDelayFunc ফাংশনে প্রদত্ত ভুলটি টাইপে টাইপ আসার্ট করব।

package main

import (
	"context"
	"errors"
	"fmt"
	"log"
	"math/rand"
	"time"

	"golang.org/x/time/rate"
	"github.com/hibiken/asynq"
)

func main() {
	srv := asynq.NewServer(
		asynq.RedisClientOpt{Addr: ":6379"},
		asynq.Config{
			Concurrency:    10,
			// যদি এটা রেট সীমাবদ্ধতার কারণে একটি ত্রুটি হয়, তবে সেটি একটি ব্যর্থতা হিসাবে গণনা করবে না।
			IsFailure:      func(err error) bool { return !IsRateLimitError(err) },
			RetryDelayFunc: retryDelay,
		},
	)

	if err := srv.Run(asynq.HandlerFunc(handler)); err != nil {
		log.Fatal(err)
	}
}

type RateLimitError struct {
	RetryIn time.Duration
}

func (e *RateLimitError) Error() string {
	return fmt.Sprintf("রেট সীমা পৌঁছা গেছে (পুনরায় চেষ্টা করুন %v)", e.RetryIn)
}

func IsRateLimitError(err error) bool {
	_, ok := err.(*RateLimitError)
	return ok
}

func retryDelay(n int, err error, task *asynq.Task) time.Duration {
	var ratelimitErr *RateLimitError
	if errors.As(err, &ratelimitErr) {
		return ratelimitErr.RetryIn
	}
	return asynq.DefaultRetryDelayFunc(n, err, task)
}

// প্রতি সেকেন্ড 10 ইভেন্টের রেট সীমা, উন্মুক্ত কমানে 30 ইভেন্টের মেঘগমন।
var limiter = rate.NewLimiter(10, 30)

func handler(ctx context.Context, task *asynq.Task) error {
	if !limiter.Allow() {
		return &RateLimitError{
			RetryIn: time.Duration(rand.Intn(10)) * time.Second,
		}
	}
	log.Printf("[*] টাস্ক %s সম্পাদন করা হচ্ছে", task.Payload())
	return nil
}