Bu sayfa, görev tekrarını yapılandırmanın nasıl yapılacağını açıklar.

Varsayılan Davranış

asynq varsayılan olarak bir görevi maksimum 25 kez tekrar deneyecektir. Her tekrar denemede, tekrar deneme gecikmesini hesaplamak için üssel bir geri çekilme stratejisi kullanır. Bir görev tüm tekrar deneme girişimlerini tüketirse (varsayılan olarak 25 kez), görevi hata ayıklama ve inceleme amaçları için arşivlenmiş durumuna taşır ve otomatik olarak tekrar denemez (görevi hala CLI veya WebUI kullanarak manuel olarak çalıştırabilirsiniz).

Aşağıdaki görev tekrar deneme özellikleri özelleştirilebilir:

  • Her görev için maksimum tekrar deneme girişimleri
  • Bir başarısız görevin tekrar denenebilmesi için beklenmesi gereken zaman aralığı (yani gecikme)
  • Görevin tekrar deneme sayısını kullanıp kullanmamak
  • Tekrarları atlayıp görevi doğrudan arşive gönderip göndermemek

Bu sayfanın geri kalan kısımları yukarıda bahsedilen her özel seçeneği açıklar.

Görevler için Maksimum Tekrar Deneme Girişimlerini Özelleştirme

Bir görevi kuyruğa alırken, asynq.MaxRetry seçeneğini kullanarak bir görev için maksimum tekrar deneme girişimlerini belirtebilirsiniz.

Örnek:

client.Enqueue(task, asynq.MaxRetry(5))

Bu, task'ın en fazla beş kez tekrar deneneceğini gösterir.

Ayrıca, belirli bir görev için maksimum tekrar deneme girişimlerini ayarlamak istiyorsanız, görev için varsayılan seçenek olarak ayarlayabilirsiniz.

task := asynq.NewTask("feed:import", nil, asynq.MaxRetry(5))
client.Enqueue(task) // MaxRetry 5 olarak ayarlandı

Tekrar Deneme Gecikmesini Özelleştirme

Config yapısında RetryDelayFunc seçeneğini kullanarak tekrar deneme gecikmesini nasıl hesaplayacağınızı belirtebilirsiniz.

RetryDelayFunc'ın imzası şöyledir:

// n, görevin tekrar denendiği kez sayısıdır
// e, görev işleyicisi tarafından döndürülen hata
// t, ilgili görevdir
RetryDelayFunc func(n int, e error, t *asynq.Task) time.Duration

Örnek:

srv := asynq.NewServer(redis, asynq.Config{
    Concurrency: 20,
    RetryDelayFunc: func(n int, e error, t *asynq.Task) time.Duration {
        return 2 * time.Second
    },
})

Bu, tüm başarısız görevlerin yeniden işlenmeden önce iki saniye beklemesi gerektiğini gösterir.

Varsayılan davranış, DefaultRetryDelayFunc tarafından tanımlanan üssel geri çekilmedir. Aşağıdaki örnek, belirli görev tipleri için tekrar deneme gecikmesini özelleştirmenin nasıl yapıldığını gösterir:

srv := asynq.NewServer(redis, asynq.Config{
    // "foo" görevleri için her zaman 2 saniyelik bir gecikme kullan, diğer görevler varsayılan davranışı kullanır.
    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) 
    },
})

Başarısızlık olmayan hata

Bazen işleyiciden bir hata döndürmek ve görevi daha sonra tekrar denemek isteyebilirsiniz, ancak görevin tekrar deneme sayısını kullanmak istemeyebilirsiniz. Örneğin, iş biriminin görevi işlemek için yeterli kaynağı olmadığından görevi daha sonra tekrar denemek isteyebilirsiniz. Sunucu başlatılırken, IsFailure(error) bool işlevi için bir Config sağlamayı seçebilirsiniz. Bu önek işlevi, işleyiciden gelen hatanın bir başarısızlık olarak sayılıp sayılmayacağını belirler. İşlev false dönerse (yani, başarısızlık olmayan bir hata), sunucu görevin tekrar deneme sayısını kullanmaz ve görevi sadece daha sonra tekrar denemek üzere planlar.

Örnek:

var ErrResourceNotAvailable = errors.New("yeterli kaynak mevcut değil")

func HandleResourceIntensiveTask(ctx context.Context, task *asynq.Task) error {
    if !IsResourceAvailable() {
        return ErrResourceNotAvailable
    }
    // ... yüksek kaynak kullanımlı görevi işleme ilişkin mantık
}

// ...

srv := asynq.NewServer(redisConnOpt, asynq.Config{
    // ... diğer yapılandırma seçenekleri
    IsFailure: func(err error) bool {
        return err != ErrResourceNotAvailable // yeterli kaynak yoksa başarısızlık olmayan bir hata
    },
})

Tekrarı Atla

Eğer Handler.ProcessTask, SkipRetry hatası döndürürse, görevin tekrar deneme sayısı kalmaksızın arşivlenecektir. Döndürülen hata SkipRetry olabilir veya SkipRetry hatası ile sarmalanmış bir hata olabilir.

func ExampleHandler(ctx context.Context, task *asynq.Task) error {
    // Görev işleme mantığı burada bulunmaktadır...
    // İşleyici, görevin tekrar denemek istenmediğini bilirse, SkipRetry döndürülsün
    return fmt.Errorf(": %w", asynq.SkipRetry)
}