Skip to content
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

Re-work Execution and AsyncExecution APIs #287

Closed
jhalterman opened this issue Aug 13, 2021 · 3 comments
Closed

Re-work Execution and AsyncExecution APIs #287

jhalterman opened this issue Aug 13, 2021 · 3 comments

Comments

@jhalterman
Copy link
Member

jhalterman commented Aug 13, 2021

The Execution and AsyncExecution APIs are meant to make it easy to integrate with third party libraries or APIs where some portion of retry or execution logic is built into that library, and Failsafe just needs to do the rest. That said, they are a bit odd, having been created in the early days of Failsafe, and these APIs are very specific to retries as opposed to executions in general.

Execution

Current example:

// Standalone Execution
Execution execution = new Execution(retryPolicy);

if (execution.canRetryOn(someFailure))
  service.scheduleRetry(execution.getWaitTime().toNanos(), TimeUnit.MILLISECONDS);

A better idea might be something that focuses on "execution" semantics rather than retries, since retries are just one reason an execution might be needed or not, given whatever policies are in use. So a better idea might be:

execution.recordFailure(someFailure);
if (execution.canPerform())
  service.scheduleRetry(execution.getWaitTime().toNanos(), TimeUnit.MILLISECONDS);

AsyncExecution

Current example:

// Async execution
Failsafe.with(retryPolicy)
  .getAsyncExecution(execution -> service.connect().whenComplete((result, failure) -> {
    if (execution.complete(result, failure))
      log.info("Connected");
    else if (execution.retry())
      log.info("Retrying connection")
    else
      log.error("Connection attempts failed", failure);
  }));

Whether we're scheduling a retry or not should not really be a concern here. We should just attempt to handle the execution, and a retry either occurs or not based on whatever policies are configured:

Failsafe.with(retryPolicy)
  .getAsyncExecution(execution -> service.connect().whenComplete((result, failure) -> {
    execution.handle(result, failure); // May trigger a retry, or not
  }));

While the current AsyncExecution API allows for logging when an execution completes or is retried:

if (execution.complete(result, failure))
  log.info("Connected");
else if (execution.retry())
  log.info("Retrying connection")
else
  log.error("Connection attempts failed", failure);

...Failsafe's event listeners already support this. So we could change the original example to something like:

retryPolicy.onRetry(e -> "Retrying connection");
Failsafe.with(retryPolicy)
  .onSuccess(e -> log.info("Connected"))
  .onFailure(e -> log.error("Connection attempts failed", e.getFailure()))
  .getAsyncExecution(execution -> service.connect().whenComplete((result, failure) -> {
    execution.handle(result, failure);
  }));

And we're not losing any capabilities, just moving them around somewhat.


Thoughts?

@jhalterman
Copy link
Member Author

jhalterman commented Sep 22, 2021

This is up now in the 2.5.0 branch. tl;dr;, Execution and AsyncExecution now support a simple set of methods for recording results and determining whether the execution is complete. These include:

  • record(R result, Throwable failure)
  • recordResult(R result)
  • recordFailure(Throwable failure)
  • complete()
  • isComplete()

For async integration methods (getAsyncExecution, etc), retries will automatically be triggered, if needed, when a result is recorded.

https://github.com/failsafe-lib/failsafe/blob/2.5.0/src/main/java/net/jodah/failsafe/AsyncExecution.java
https://github.com/failsafe-lib/failsafe/blob/2.5.0/src/main/java/net/jodah/failsafe/Execution.java

@jhalterman
Copy link
Member Author

Closed by fb14816

@jhalterman jhalterman added 3.0 and removed 2.5 labels Nov 10, 2021
@jhalterman
Copy link
Member Author

3.0 has been released, which includes this improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant