يصف هذا الصفحة كيفية تكوين إعادة المحاولة في المهمة.
السلوك الافتراضي
بشكل افتراضي، ستقوم asynq
بإعادة محاولة المهمة حتى 25 مرة كحد أقصى. في كل مرة تتم فيها إعادة المحاولة، يتم استخدام استراتيجية الانحراف الأسي لحساب تأخير إعادة المحاولة. إذا استنفدت المهمة جميع محاولات إعادة المحاولة (الافتراضي هو 25 مرة)، سيتم نقل المهمة إلى الحالة أرشفة لأغراض تصحيح الأخطاء والتفتيش، ولن يتم إعادة محاولتها تلقائياً (يمكنك مع ذلك تشغيل المهمة يدوياً باستخدام واجهة سطر الأوامر (CLI) أو واجهة المستخدم عبر الويب (WebUI)).
يمكن تخصيص خصائص إعادة المحاولة للمهمة المتبقية على هذه الصفحة.
تخصيص الحد الأقصى لمحاولات إعادة المهمة
يمكنك تحديد الحد الأقصى لعدد محاولات إعادة المهمة عند إرسال المهمة للانتظار باستخدام الخيار asynq.MaxRetry
.
مثال:
client.Enqueue(task, asynq.MaxRetry(5))
هذا يشير إلى أنه يجب إعادة محاولة task
مرة واحدة كحد أقصى.
بالإضافة إلى ذلك، إذا كنت ترغب في تحديد الحد الأقصى لمحاولات إعادة المهمة لمهمة معينة، يمكنك ضبطه كخيار افتراضي للمهمة.
task := asynq.NewTask("feed:import", nil, asynq.MaxRetry(5))
client.Enqueue(task) // تم ضبط MaxRetry على قيمة 5
تخصيص تأخير المحاولة
يمكنك تحديد كيفية حساب تأخير المحاولة باستخدام الخيار RetryDelayFunc
في هيكل Config
.
توقيع RetryDelayFunc
هو كما يلي:
// n هو عدد مرات محاولة إعادة المهمة
// e هو الخطأ الذي عاد به معالج المهمةب
// t هو المهمة ذات الصلة
RetryDelayFunc func(n int, e error, t *asynq.Task) time.Duration
مثال:
srv := asynq.NewServer(redis, asynq.Config{
Concurrency: 20,
RetryDelayFunc: func(n int, e error, t *asynq.Task) time.Duration {
return 2 * time.Second
},
})
هذا يشير إلى أن جميع المهام الفاشلة ستنتظر لمدة ثانيتين قبل معالجتها من جديد.
السلوك الافتراضي هو الانحراف الأسي، المحدد بواسطة DefaultRetryDelayFunc
. يوضح المثال التالي كيفية تخصيص تأخير إعادة المحاولة لأنواع معينة من المهام:
srv := asynq.NewServer(redis, asynq.Config{
// بالنسبة للمهام "foo"، استخدم دائمًا تأخير لمدة 2 ثانية، وبالنسبة للمهام الأخرى، استخدم السلوك الافتراضي.
RetryDelayFunc: func(n int, e error, t *asynq.Task) time.Duration {
if t.Type() == "foo" {
return 2 * time.Second
}
return asynq.DefaultRetryDelayFunc(n, e, t)
},
})
خطأ غير فاشل
في بعض الأحيان، قد ترغب في إعادة المهمة لاحقًا دون استخدام عدد محاولات إعادة المهمة. على سبيل المثال، قد ترغب في إعادة المحاولة لاحقًا لأن الوحدة العملية لديها موارد غير كافية لمعالجة المهمة.
أثناء تهيئة الخادم، يمكنك اختيار تقديم Config
للدالة IsFailure(error) bool
. تحدد هذه الدالة العاملية الشرطية ما إذا كان الخطأ من المعالج يعتبر كفشل. إذا قامت الدالة بإرجاع قيمة خاطئة (أي، خطأ غير فاشل)، فإن الخادم لن يستخدم عدد محاولات إعادة المهمة وسيقوم بجدولة المهمة ببساطة لإعادة المحاولة لاحقًا.
مثال:
var ErrResourceNotAvailable = errors.New("no resource is available")
func HandleResourceIntensiveTask(ctx context.Context, task *asynq.Task) error {
if !IsResourceAvailable() {
return ErrResourceNotAvailable
}
// ... منطق لمعالجة المهمة المكثفة للموارد
}
// ...
srv := asynq.NewServer(redisConnOpt, asynq.Config{
// ... خيارات تكوين أخرى
IsFailure: func(err error) bool {
return err != ErrResourceNotAvailable // خطأ غير فاشل إذا لم تتوفر الموارد
},
})
تخطي إعادة المحاولة
إذا قام Handler.ProcessTask
بإرجاع خطأ SkipRetry
، سيتم أرشفة المهمة بغض النظر عن عدد المحاولات المتبقية لإعادة المحاولة. يمكن أن يكون الخطأ المُرجَع SkipRetry
أو خطأ مُلفق بخطأ SkipRetry
.
func ExampleHandler(ctx context.Context, task *asynq.Task) error {
// منطق معالجة المهمة هنا...
// إذا كان المعالج يعلم أنه لا يجب إعادة المحاولة للمهمة، فإرجاع:SkipRetry
return fmt.Errorf(": %w", asynq.SkipRetry)
}