-
-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#204 do not shutdown the ThreadPoolExecutor when mails are sent #205
Conversation
Analyzing your changes right now. Can you help me understand why it is better to log the error rather than have it bubble up? I can argue the whole thing should fail when an email fails and also why it shouldn't. Depends on the use case. Maybe it should be configurable. Actually, for v6.0.0 in develop, send returns a Future and Promise, which contains any exception that was thrown when sending async. |
The original default thread factory consulted the SecurityManager to determine the thread group, shouldn't your version do this as well? I must admit I'm not familiar with this function:
|
Actually, the more I look at it, the more I am starting to have doubts on daemon threads altogether. They shouldn't block the JVM from shutting down, but only when they are not actually doing anything. Now what happens is if an application is running just to send emails async, or from junit test, or from CLI (coming in 6.0.0), then the JVM kills the threads before they send anything, correct? They may even halt in the middle of an SMTP session. By their nature I feel an emailing thread should never block the JVM. The only way then to have the JVM exit is to properly shutdown the executor. /edit: then there's this: https://stackoverflow.com/a/29453160/441662 It solves the problem but feels like a workaround when I don't have the use case for daemon threads to begin with. |
Regarding my earlier question about |
I really appreciate your effort @amanteaux, but thinking about it more I feel this is not the right path. However, I am keeping some of your changes, like the custom thread factory to fix the thread names. |
I agree that the daemon thread solution is not really that good. From a JUnit test, it won't make a difference if you are using daemon threads or not: the thread pool will get shutdown/killed anyway once the test method is executed. But I can see for sure a use case where an application that executes for a short amount of time and wants to send asynchronous mails. Wouldn't the solution with the non-daemon threads and the time out (
This solution should not add complexity to Simple Java Mail no? |
…n. Threads are now named. Removed redundant warning suppressions
I'm willing to take another look if you are willing to take another stab at it (but branch off from "204-fix-race-condition-improve-threading" this time). Don't bother wiring the config into everything, I'll take care of that if I'm happy with the solution. I can see an advantage of a configurable timeout, although at the same time that adds complexity to Simple Java Mail as well! |
… report back in the Future / Promise that is returned from an async send / testConnection invocation
About your two other questions:
And thank you for time reviewing my merge request! |
Ok thank you! I will try to do something in the "204-fix-race-condition-improve-threading" branch! |
There are 3 changes:
ThreadPoolExecutor
is not shutdown anymore when mails are sentThreadPoolExecutor
are set to daemon (so they don't "block" the JVM shutdown) ; and also they are named "Simple Java Mail async mail sender #N" so they can be easily identified in the application threadsMailSender
class (instead of ae.printStackTrace()
in theThreadPoolExecutor
): that is not directly related to the original issue, if necessary I can do a separate pull request for thatThere are 2 unit tests I wanted to write (and eventually I did not):
MailSender
needs to be created=> but actually to make this work, I guess we would need a test SMTP server like https://github.com/davidmoten/subethasmtp ; it seems too complicated
Thread.getAllStackTraces().keySet()
, but JUnit seems to create many threads that are actually non-daemon... So I also gave up to do this Unit test.However, I did make manual "real-world" tests with our Java application.
Lastly, I am wondering if the default thread pool size for
ThreadPoolExecutor
, 10, is not a bit too high. I think that a default pool of 2 would be enough in the majority of use cases. Is there any reason for using a default thread pool that high?