-
Notifications
You must be signed in to change notification settings - Fork 292
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
Consider more explicit functional composition APIs #254
Comments
@Tembrel Does it need to happen on the var failsafe = Failsafe.of(retry
.andThen(fallback)
.compose(timeout)); The API of (Not sure if |
Right now polices do not lend themselves to composition as easily, and really, a FailsafeExecutor represents a particular composition of policies (along with a few listeners). But, if it makes sense to change things we can. |
I don't think you'd want to add composability to policies unless you also have a solid guarantee of immutability for policies (see #47), otherwise The same danger exists for |
Another possibility that uses nesting, but in doing so, is somewhat clear about how things compose: PolicyComposition composition = fallback.wrap(retryPolicy.wrap(circuitBreaker.wrap(timeout)));
Failsafe.with(composition).get(this::connect); This mirrors the flattened out version nicely: Failsafe.with(fallback, retryPolicy, circuitBreaker, timeout).get(this::connect); |
Hard to imagine anyone writing out the nested version; it's hard to read, let alone write. I've forgotten what you (@jhalterman) didn't like about: result = Failsafe.with(timeout)
.within(circuitBreaker)
.within(retryPolicy)
.within(fallback)
.get(this::connect); Or: result = Failsafe.with(fallback)
.around(retryPolicy)
.around(circuitBreaker)
.around(timeout)
.get(this::connect); Or both! result = Failsafe.with(retryPolicy)
.around(circuitBreaker)
.around(timeout)
.within(fallback)
.get(this::connect); (That's unambiguous but hard to understand. I imagine people would stick to uniform A minor perq of the fluent form is that you can temporarily comment out a policy like so: result = Failsafe.with(fallback)
.around(retryPolicy)
//.around(circuitBreaker)
.around(timeout)
.get(this::connect); |
Partly naming (I like @whiskeysierra's suggestion of borrowing
Failsafe.with(fallback.compose(retryPolicy)
.compose(circuitBreaker)
.compose(timeout))
.get(this::connect);
Failsafe.with(fallback)
.compose(retryPolicy)
.compose(circuitbreaker)
.compose(timeout)
.get(this::connect); I'd slightly lean towards option 2. Each Failsafe.with(fallback)
.compose(retryPolicy)
.with(executorService)
.compose(circuitBreaker)
.onComplete(e -> ....)
.compose(timeout)
.get(this::connect); ...whereas option 1 wouldn't suffer from that problem. Any thoughts or preferences? |
Pushed a PR for this. Feel free to weigh in there: #285. |
3.0 has been released, which includes this improvement. The policy docs page also describes how composition works with a sequence diagram: |
For some ideas, see:
The text was updated successfully, but these errors were encountered: