bbottema/simple-java-mail

Provide a way to handle success/failure in async mode (including testConnection())

trathschlag opened this issue · 7 comments

Hi!
It would be really useful if you could somehow handle success and failures when sending asynchronously. Is it be possible to implement CompletableFuture as a return value for mailer.sendAsync(...) or something?
I am interested to prepare a pull request.

Thanks in advance!

Hmm, Simple Java Mail uses JDK 1.7, so it would need to be something else. Any preference?

Also, this issue will be solved another way with #121 when you can add custom steps in between the various stages of emailing (including handling exceptions). However, that won't be in the near future.

I've added Future to the API for release 6.0.0. To use it:

try {
	f.get(); // blocks
} catch (ExecutionException e) {
	System.err.println("Sending email failed");
	e.printStackTrace(System.err);
}

You can also implement your own (threaded) checking routine that checks f.isDone() on mutliple emails in your batch so your thread doesn't block for individual async emails being sent (otherwise what's the point of sending asynchronously).

Would this suit your needs?

Hi, thanks for the reply!
I wanted to avoid Future as a solution, because there is no way to register a callback with it. You need to block or implement some polling mechanism, as you described.

Would it be possible to provide a basic interface

interface MailCallback {
    void onSuccess();
    void onFailure(Exception e);
}

which the user can implement and pass into mailer.sendAsync(callback)?
This way everyone can write their own wrappers for integration with JDK8/Guava/Kotlin/etc...

You got your wish @trathschlag!

Both sending emails and testing server connections can now be done asynchronously with either Future or Handlers.

Using Handlers

AsyncResponse asyncResponse = mailer.sendMail(email, true);
// or: mailer.testConnection(email, true);

asyncResponse.onSuccess(() -> System.out.println("Success"));
asyncResponse.onException((e) -> System.err.println("error"));

Using Future

Future<?> f = asyncResponse.getFuture();

// f.get() actually blocks until done, below is an example custom loop
// for checking result in a non-blocking way:
while (!f.isDone()) Thread.sleep(100);

// result is in, check it
try {
  f.get(); // without the above loop, this would actually block until done
  System.err.println("success");
} catch (ExecutionException e) {
  System.err.println("error");
}

Released in 6.0.0-rc1!!

6.0.0 has released as well, finally.

7.0.0 just released, which is a switch to Java8 and I've replaced this system with CompletableFuture for #367.