مثال على تكوين خادم 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
}