Open mdesharnais opened 3 days ago
This should be achievable with your example with the batch-module, as long as your have a core thread configured: withConnectionPoolCoreSize
# keep a single Transport connection alive for at least 60 minutes if not in use, and force all emails through it
simplejavamail.defaults.connectionpool.coresize=1
simplejavamail.defaults.connectionpool.maxsize=1
simplejavamail.defaults.connectionpool.claimtimeout.millis=60000 (defaults to forever)
simplejavamail.defaults.connectionpool.expireafter.millis=60000 (defaults to 5000)
Also see here: https://www.simplejavamail.org/configuration.html#section-batch-and-clustering.
After that, you need to manually call shutdown on the internal 'cluster', wait for it and create a new Mailer instance.
Future<?> shutdown = mailer.shutdownConnectionPool();
shutdown.get();
mailer = MailerBuilder.build();
Thanks for your response.
Do I understand correctly, that you mean I should do something like that?
Mailer mailer = ... // previous Mailer
final Iterator<String> iterator = ...
while (iterator.hasNext()) {
// Force the shutdown of the connection pool and, thus, of the one and only SMTP connection.
// This is in case messages were sent previously with the currently active connection.
final Future<?> shutdown1 = mailer.shutdownConnectionPool();
shutdown1.get();
mailer = ... // Get a new mailer and, thus, a new SMTP connection.
for (int i = 0; i < MAX_EMAILS_PER_CONNECTION && iterator.hasNext(); i += 1) {
final String email = iterator.next();
...
}
// Force the shutdown of the connection pool and, thus, of the one and only SMTP connection.
// This is in case messages get sent afterward with the currently active connection.
final Future<?> shutdown2 = mailer.shutdownConnectionPool();
shutdown2.get();
}
Assuming I understood correctly, this should allow me to use one connection for many emails while respecting the per-connection limit on the number of emails, but I see some caveats.
By changing the default from creating a new SMTP connection for each message to always reuse the same SMTP connection, I will now have protect all email-sending code snippets with shutdown to avoid prevent the per-connection limit from being reached by sending individual emails over time from different part of the code base. And if we forget to add protective shutdown code in some places, we could reach the limits at unexpected times and places.
Now I don't know if I expressed myself understandably, but I would prefer a solution that keeps the default behaviour safe, i.e., without requiring some protective code every time an email is sent. Because, most of the time, I don't care about the performance of sending individual emails, I would prefer the default to be simple and safe, i.e., not reusing SMTP connections, and to put more work in the very few places where performance matters and sharing an SMTP connection is relevant.
Not entirely, by default batch module has defaults that refuses Transport connections, but they are deallocated (disconnected) after a timeout until a thread is needed again to end emails. The shutdown is only needed here to force such a deallocation, as this is a special requirement for your server.
Hi, I have a use case where I need to send thousand of emails and the SMTP provider has a rate limit of 5000 emails per SMTP connection.
I initially assumed that the
Mailer
interface represented an SMTP connection and manually handled the limit in the following way.After some debugging, I realized that the
Mailer
interfaces opens a new SMTP connection for every message. My understanding is that the batch module does not support any form of per-SMTP-connection hard limit and, thus, cannot solve my problem.Note that adding such feature to the batch module is one possible solution but not the only one. Another solution could be to add some abstraction for an SMTP connection, e.g., an
SMTPConnection
interface that implements theClosable
interface, and let users such as myself manually handle the limits we need.The need for a per-connection hard limit was raised in issue #348 in October 2021, but the issue was closed after the poster found out they were hitting some other, unrelated limit.