رفتار پیشفرض
به طور پیشفرض، 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
ارائه دهید. این تابع پیشفرض تعیین میکند که آیا خطای برگرداندهشده از دستگیرنده به عنوان یک شکست حساب شود یا نه. اگر تابع مقدار false (یعنی خطای غیرناموفق) برگرداند، سرور از شمارش دوباره انجام وظیفه استفاده نکرده و بهسادگی وظیفه را برای بعداً دوباره انجام زمانبندی میکند.
مثال:
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)
}