Resetting connection properly when the underlying TCP connection breaks. Fixes #997

pull/504/merge
Jordan Wright 2018-04-20 20:33:00 -05:00
parent 3a7a62e9d6
commit 0b91404c4f
No known key found for this signature in database
GPG Key ID: 138D5AD2331B3C11
3 changed files with 23 additions and 9 deletions

View File

@ -146,7 +146,7 @@ func sendMail(ctx context.Context, dialer Dialer, ms []Mail) {
} }
defer sender.Close() defer sender.Close()
message := gomail.NewMessage() message := gomail.NewMessage()
for _, m := range ms { for i, m := range ms {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return return
@ -187,8 +187,16 @@ func sendMail(ctx context.Context, dialer Dialer, ms []Mail) {
continue continue
} }
} else { } else {
m.Error(err) // This likely indicates that something happened to the underlying
sender.Reset() // connection. We'll try to reconnect and, if that fails, we'll
// error out the remaining emails.
origErr := err
sender, err = dialHost(ctx, dialer)
if err != nil {
errorMail(err, ms[i:])
break
}
m.Backoff(origErr)
continue continue
} }
} }

View File

@ -263,16 +263,21 @@ func (ms *MailerSuite) TestUnknownError() {
message := messages[0].(*mockMessage) message := messages[0].(*mockMessage)
// Check that the first message did not perform a backoff // If we get an unexpected error, this means that it's likely the
expectedBackoffCount := 0 // underlying connection dropped. When this happens, we expect the
// connection to be re-established (see #997).
// In this case, we're successfully reestablishing the connection
// so we expect the backoff to occur.
expectedBackoffCount := 1
backoffCount := message.backoffCount backoffCount := message.backoffCount
if backoffCount != expectedBackoffCount { if backoffCount != expectedBackoffCount {
ms.T().Fatalf("Did not receive expected backoff. Got backoffCount %d, Expected %d", backoffCount, expectedCount) ms.T().Fatalf("Did not receive expected backoff. Got backoffCount %d, Expected %d", backoffCount, expectedBackoffCount)
} }
// Check that there was a reset performed on the sender // Check that the underlying connection was reestablished
if sender.resetCount != expectedCount { expectedDialCount := 2
ms.T().Fatalf("Did not receive expected reset. Got resetCount %d, expected %d", sender.resetCount, expectedCount) if dialer.dialCount != expectedDialCount {
ms.T().Fatalf("Did not receive expected dial count. Got %d expected %d", dialer.dialCount, expectedDialCount)
} }
// Check that the email errored out appropriately // Check that the email errored out appropriately

View File

@ -147,6 +147,7 @@ func (mm *mockMessage) GetDialer() (Dialer, error) {
func (mm *mockMessage) Backoff(reason error) error { func (mm *mockMessage) Backoff(reason error) error {
mm.backoffCount++ mm.backoffCount++
mm.err = reason
return nil return nil
} }