I have a singleton SmtpClient that sends emails to AWS SES.
The problem is that I'm getting SmtpException
way too often:
System.Net.Mail.SmtpException: Error in processing. The server response was: 4.4.2 Timeout waiting for data from client.
Basically, almost for every new MailMessage
object the first request fails, then the next one succeeds.
I suspect there's a problem with SmtpClient's connection pooling, a client tries to reuse a connection from the pool, whilst it was closed on the other side (by SES). It catches up the exception, starts a new connection, successfully sends an email, the connection on the other side closes and the cycle goes all over again.
Does this mean I need a shorter lifetime for a smtpClient? Like per request rather than singleton? Or maybe something in-between - a short-lived smtpClient for a group of emails (all the emails within some timeframe go into a single group).
Also would be nice to find out what is SES connection timeout and to what extent a single smtpClient can be reused.
Here's the simplified version of the code that conveys the idea of how it works:
//resolved as a singleton
public class EmailService: IDisposable {
private readonly BlockingCollection < MailMessage > _messages = new();
private readonly SmtpClient _client;
public EmailService() {
_client = new SmtpClient() {
//fill settings
};
new Thread(ProcessQueue) { IsBackground = true }.Start();
}
public void SendEmail(MailMessage message) {
_messages.Add(message);
}
private void ProcessQueue() {
foreach(var item in _messages.GetConsumingEnumerable()) {
ProcessItem(item);
}
}
private void ProcessItem(MailMessage message) {
using(message) {
try {
_client.Send(message);
} catch (SmtpException) {
// retry
}
}
}
public void Dispose() {
//
}
}