go-gomail / gomail

The best way to send emails in Go.
MIT License
4.32k stars 572 forks source link

Connection Reset by Peer #63

Open jrkt opened 8 years ago

jrkt commented 8 years ago

I have 50 worker goroutines that start with a channel passed in. Then, the process forever loops reading 100 database records at a time and sleeping for 10 seconds in between database calls. As it loops through the 100 email records to send, it passes each record through the channel to one of the 50 workers, who then sends the email. The problem is, after it goes through about 1000 emails, I start getting errors like this:

gomail: could not send email 1: read tcp 10.2.30.25:56708->216.146.40.110:25: read: connection reset by peer

I have to send out about 50k emails per day. What do you recommend? Here's the main code that processes the email queue and passes each record to the worker through the channel:

func main() {

MaxWorkers := 50
println("Creating: " + strconv.Itoa(MaxWorkers) + " workers..")
batchChannel := make(chan EmailQueue.EmailQueueObj)

for i := 0; i < MaxWorkers; i++ {
    go startWorker(batchChannel)
}

for {
    println("Getting queue..")
    data, _ := EmailQueue.GetQueue() //returns 100 database records

    println("Reading through " + strconv.Itoa(len(data)) + " records..")
    for _, element := range data {
        batchChannel <- element
    }

    time.Sleep(10 * time.Second)
}
}

func startWorker(channel chan EmailQueue.EmailQueueObj) {
var s gomail.SendCloser
var err error
open := false
for obj := range channel {
    if !open {
        s, err = dialer.Dial()
        if err != nil {
            fmt.Println(err.Error())
            return
        } else {
            sendEmail(obj, &s)
        }
    } else {
        sendEmail(obj, &s)
    }
    open = true
}
s.Close()
}

func sendEmail(obj EmailQueue.EmailQueueObj, s *gomail.SendCloser) {

m := gomail.NewMessage()
m.SetHeader("From", "example@example.com")
m.SetHeader("To", obj.Recipient)
m.SetHeader("Subject", obj.Subject.String)
m.SetBody("text/html", obj.HTML.String)

// Send the email
response := ""
status := ""
if err := gomail.Send(*s, m); err != nil {
    response = err.Error()
    status = "error"
} else {
    response = "Email sent"
    status = "sent"
}
m.Reset()

return
}
jrkt commented 8 years ago

Any help here?

rusenask commented 7 years ago

started getting the same error, not sure why. Have you solved this by any chance?

jrkt commented 7 years ago

I did at least for the problem I was having. The smtp provider, Dyn, had a limit on how many emails could go out in a minute and a limit on how many concurrent workers I had processing the emails with an open connection to the smtp server. So, once I made sure I wasn't sending too many and I had the open connections limited, it fixed the issue.