wait for email client to complete on shutdown

This commit is contained in:
david 2026-08-25 17:54:55 +03:00
parent 67c4b3b3d7
commit 034d9bf14e
2 changed files with 29 additions and 1 deletions

View File

@ -345,7 +345,11 @@ type client interface {
// Close waits for the deliveries still in flight and releases the sender.
func (s *Sender) Close() error {
s.supv.CloseAndWait()
// the deliveries must finish on a live context, so the wait precedes
// the cancellation Close brings. No new sends can arrive here — the
// HTTP server shuts down first — and _sendTimeout bounds the wait.
s.supv.Wait()
s.supv.Close()
return nil
}

View File

@ -338,6 +338,30 @@ func Test_Sender_SendAccountExists(t *testing.T) {
assert.Contains(t, msgBody(t, msg), "https://example.com/login")
}
func Test_Sender_Close(t *testing.T) {
t.Parallel()
var ctxErr error
client := &clientMock{
DialAndSendWithContextFunc: func(ctx context.Context, _ ...*mail.Msg) error {
ctxErr = ctx.Err()
return nil
},
}
s := stubSender(client)
s.SendPasswordReset("user@example.com", "https://example.com/reset")
require.NoError(t, s.Close())
// Close must drain the in-flight delivery before cancelling the
// supervisor context, so the send observed a live context.
require.Len(t, client.DialAndSendWithContextCalls(), 1)
assert.NoError(t, ctxErr)
}
// stubSender creates a sender backed by the provided mocked client.
func stubSender(client *clientMock) *Sender {
return &Sender{