spring-retry icon indicating copy to clipboard operation
spring-retry copied to clipboard

An idea for async retry

Open ashamukov opened this issue 6 years ago • 10 comments

Hello! Here is a draft for the async retry feature with rescheduling. The goal for now is to discuss: is it worth to implement it this way. (javadoc and formatting are expected to be later)

The general idea is described in the README.dm diff, and also is outlined here: async-diagram-1

Checklist:

  • [x] solution for inter-thread retry-context propagation:
    • [x] is discussed
    • [ ] merged (+ tests)
  • [ ] consensus about the value of such a feature is reached (probably, it is worth to use some full-fledged async-programming framework instead, like zio-retry for scala)
  • [ ] migration of the repo to java8 is discussed and performed
  • [ ] details of java.util.concurrent.Future support are discussed and implemented Copy pasted from the issue:

    Because it has no "thenApply"-like notation, exception handling and retry scheduling for actual job can not be performed by worker right after previous attempt fails, i.e. invocation of "resultFuture.get()" is required to start even the first retry of actual job. That mixes sync and async approaches in a not very beautiful way, so I propose to not specially support java.util.concurrent.Future at all.

  • [ ] javadoc and formatting are polished
  • [ ] additional tests are written for:
    • [ ] stateful rescheduling
    • [ ] RejectedExecutionException on rescheduler
    • [ ] InterruptedException

Can be done in separate PRs:

  • add ListenableFuture support
  • support declarative async retry

https://github.com/spring-projects/spring-retry/issues/154

ashamukov avatar May 18 '19 14:05 ashamukov

I rebased your work onto master. See PR: https://github.com/ashamukov/spring-retry/pull/1 (or alternatively reset your own branch to https://github.com/dsyer/spring-retry/tree/ashamukov-async-retry).

dsyer avatar Sep 06 '19 10:09 dsyer

About RetrySynchronizationManager Supported partially. There is no way to implicitly pass the context into the worker thread, because the worker executor,

True, but it's a really common pattern. The way we normally solve it in Spring projects is to provide a wrapper for the executor that has to be supplied by the user for the background state to be propagated. I expect we can do that - if the user provides the right wrapper they can use RetrySynchronization, otherwise not.

dsyer avatar Sep 06 '19 10:09 dsyer

@dsyer Hello Dave! Thanks for the rebase.

The way we normally solve it in Spring projects is to provide a wrapper for the executor that has to be supplied by the user for the background state to be propagated.

Here is an example of solution: https://github.com/ashamukov/spring-retry/pull/2 What do you think?

ashamukov avatar Oct 24 '19 10:10 ashamukov

I give that solution 👍

artembilan avatar Oct 24 '19 19:10 artembilan

I give that solution 👍

Thanks, Artem!) Just to double-check: are you agree, that in this situation, copy-pasting is better than extracting DelegatingContextExecutor to somewhere like spring-core, and parametrizing it with RetryContext + RetrySynchronizationManager#register in spring-retry, and with SecurityContext + SecurityContextHolder#setContext in spring-security?

ashamukov avatar Oct 25 '19 13:10 ashamukov

Well, doesn't look like it is going to be an easy task to extract some common abstraction and we may end up with generics hell. Although I wouldn't mind to play with that. Do you have something to take a look already?

artembilan avatar Oct 25 '19 13:10 artembilan

Do you have something to take a look already?

This is an attempt ;) https://github.com/ashamukov/spring-security/pull/1

ashamukov avatar Oct 25 '19 20:10 ashamukov

You know, looks cool!

Let's raise an issue in https://github.com/spring-projects/spring-framework/issues and page @rwinch for determining what we would like to do with Spring Security after that common abstraction.

I believe there might be some improvements or changes in your solution, but at least my colleagues will know our position about such a propagation abstraction from one thread to another! 😄

artembilan avatar Oct 25 '19 20:10 artembilan

Thanks, Artem!

Let's raise an issue

The issue: https://github.com/spring-projects/spring-framework/issues/23876

ashamukov avatar Oct 28 '19 08:10 ashamukov

I rebased and did some tidying up: https://github.com/dsyer/spring-retry/tree/ashamukov-async-retry. We can start from there if anyone is interested in this. It works for CompletableFuture and Future (as least as much as is tested).

dsyer avatar Apr 08 '20 10:04 dsyer