Неправильное использование GoLang WaitGroup при создании нескольких исполнений? - PullRequest
0 голосов
/ 06 апреля 2020

В моем проекте golang я, кажется, получаю несколько выполнений следующей функции, которая заставляет отправлять несколько писем одному и тому же пользователю. Я замечаю два электронных письма, отправляемых каждому пользователю. Я подозреваю, что я неправильно использую WaitGroup в следующей функции, и это может быть причиной проблемы. Приведенная ниже функция создает шаблон html с данными и отправляет электронное письмо каждому подписанному пользователю. Вы случайно не заметили, что я могу делать что-то не так?

func build(subscriptions map[string]subscriptionService.SubscriptionDto, rawData map[string]dataService.DataDto) error {
    var wg sync.WaitGroup
    errorChannel := make(chan *error)
    locationError, countries := locationService.GetCountries()
    if locationError != nil {
        return locationError
    }

    emailsPerBatch := 10
    timeBetweenBatches := 15 // in seconds

    if len(subscriptions) > emailsPerBatch {
        wg.Add(emailsPerBatch)
    } else {
        if len(subscriptions) == 0 {
            logService.LogInfo("No valid subscribers.")
        } 

        wg.Add(len(subscriptions))
    }
    currentIndex := 0
    for _, subscription := range subscriptions {

        if currentIndex%emailsPerBatch == 0 && currentIndex != len(subscriptions) && currentIndex != 0 {
            wg.Wait()
            time.Sleep(time.Duration(timeBetweenBatches) * time.Second)
            remainingItemsLength := len(subscriptions) - currentIndex

            if remainingItemsLength > emailsPerBatch {
                wg.Add(emailsPerBatch)
            } else {
                wg.Add(remainingItemsLength)
            }
        }
        currentIndex++

        go func(subscription subscriptionService.SubscriptionDto, countries locationService.CountriesDto, wg *sync.WaitGroup, errorChannel chan *error) {
            defer wg.Done()

            templateModel := buildModelForSubscription(subscription, rawData, countries)

            buildHtmlTemplateError, emailHtml := buildHtmlTemplateForSubscription(subscription.Email, templateModel)
            if buildHtmlTemplateError != nil {
                logService.LogFatal(buildHtmlTemplateError.Error())
                return
            }

            minifier := minify.New()
            minifier.AddFunc("text/css", css.Minify)
            minifier.AddFunc("text/html", html.Minify)
            emailHtml, err := minifier.String("text/html", emailHtml)
            if err != nil {
                logService.LogFatal(err.Error())
                return
            }

            subscriptionService.UpdateLastSentDate(subscription.Email)

            sendMailError := mailing.SendEmail(emailHtml, subscription.Email)
            if sendMailError != nil {
                logService.LogFatal(sendMailError.Error())
                return
            }
        }(subscription, countries, &wg, errorChannel)
    }

    wg.Wait()

    return nil
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...