Как стать автором
Поиск
Написать публикацию
Обновить

Комментарии 3

Спасибо за статью.
Немного подушню :-) В воркерах я бы добавил проверку, что канал не был закрыт, и прокинул бы контекст дальше в целевую функцию (ну и обрабатывать отмену там тоже), а то в случае если контекст будет отменен после того, как мы провалились в функцию, воркер не закончит работу пока она не доработает.

func worker(ctx context.Context, jobs <-chan Job) {
    for {
        select {
        case job, ok := <-jobs:
            if !ok {
              return              
            }

            processJob(ctx, job)
        case <-ctx.Done():
            log.Println("Worker shutting down")
            return
        }
    }
}

func processJob(ctx context.Context , job Job) {
    ch := make(chan {}struct)
    go func() {
      // Вот тут что-нить тяжелое

      close(ch)
    }

    select {
      case <-ch:
        return
      case <-ctx.Done():
        return
    }
}
func withRetry(fn func() error, maxRetries int, backoff time.Duration) error {
    for i := 0; i < maxRetries; i++ {
        if err := fn(); err == nil {
            return nil
        }
        
        if i < maxRetries-1 {
            select {
            case <-time.After(backoff * time.Duration(i+1)):
                // Exponential backoff
            }
        }
    }
    return fmt.Errorf("exceeded max retries")
}

Здесь ошибка в комментарии, т.к. реализован линейный backoff.
Экспоненциальный делей можно реализовать вот так:

delay := backoff * time.Duration(1 << i)

Конкурентность и параллелизм не одно и тоже! Каналы это инструмент для контроля конкурентности, в не параллелизма.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации