Issue this would address:
Frequently I find myself writing code to dance around the fact that I want to do things like display the number of retry attempts as I'm retrying. Currently, I've just been using a side effect to do that, but it would be nice if I could output the retry attempts or a retry message in to the same output stream.
const retryInfo = new Subject<{ count: number, error: any }>();
source$.pipe(
retry({
delay: (error, count) => {
// log the error so we can see it.
console.error(error);
// Notify some external observer that there's a retry in progress
retryInfo.next({ count, error });
// delay the retry by some time
return timer(5000);
}
})
)
The problem with this approach is I've found it's better to mix connection status, or upload progress, or whatever, into the same stream as the output data, and share/filter it appropriately later.
Proposed solution:
Add a configurable/optional function that can be used to select a temporary observable that will be run until the retry commences. This can also be used for synchronous retry. In this case I'm calling it emitOnRetry, but we can bikeshed that name.
declare const source$: Observable<{ type: 'CONNECTING' | 'CONNECTED' | 'UPDATE', payload?: SomeData[]>;
source$.pipe(
retry({
emitOnRetry: (error, count) => of({ type: 'RETRY', error, count }),
delay: (error, count) => {
// log the error so we can see it.
console.error(error);
// delay the retry by some time
return timer(5000);
}
})
)
The behavior of the above:
- When
source$ errors, call emitOnRetry, and immediately subscribe to the resulting observable input, flattening results into the resulting observable
- Then immediately call and subscribe to the result of
delay.
- When the result of
delay emits, immediately unsubscribe from the emitOnRetry observable and execute appropriate retry logic.
In the synchronous retry case (when delay is not provided), this wouldn't work any different. If emitOnRetry returned a synchronous source, it would have a chance to emit whatever it was before the sync retry logic fired.
Pros
- This would be a powerful feature to add to the new
retry, which is already an improvement over retryWhen and the previous retry.
- The only other way to accomplish this with existing operators before would have been with something like
catchError then repeat, but that would not have allowed for access to the retry count.
Cons
- Added surface area may create some additional confusion. Especially around sync retries?
Issue this would address:
Frequently I find myself writing code to dance around the fact that I want to do things like display the number of retry attempts as I'm retrying. Currently, I've just been using a side effect to do that, but it would be nice if I could output the retry attempts or a retry message in to the same output stream.
The problem with this approach is I've found it's better to mix connection status, or upload progress, or whatever, into the same stream as the output data, and share/filter it appropriately later.
Proposed solution:
Add a configurable/optional function that can be used to select a temporary observable that will be run until the retry commences. This can also be used for synchronous retry. In this case I'm calling it
emitOnRetry, but we can bikeshed that name.The behavior of the above:
source$errors, callemitOnRetry, and immediately subscribe to the resulting observable input, flattening results into the resulting observabledelay.delayemits, immediately unsubscribe from theemitOnRetryobservable and execute appropriate retry logic.In the synchronous retry case (when
delayis not provided), this wouldn't work any different. IfemitOnRetryreturned a synchronous source, it would have a chance to emit whatever it was before the sync retry logic fired.Pros
retry, which is already an improvement overretryWhenand the previous retry.catchErrorthenrepeat, but that would not have allowed for access to the retry count.Cons