Kotlin / kotlinx.coroutines

Library support for Kotlin coroutines
Apache License 2.0
13.07k stars 1.85k forks source link

Correct & document odd Flow retry/retryWhen attempts behavior #2842

Open bubenheimer opened 3 years ago

bubenheimer commented 3 years ago

The Flow retry/retryWhen attempt counter never resets; it provides a kind of flow flakiness measure rather than the number of retry attempts after the last failure. This behavior is not clearly documented. I assume the behavior is an oversight, and not really by design; having such a measure seems rarely preferable. Typically, when counting retries, for example in network connectivity, the counter resets after a successful connection. Measuring flakiness would commonly be a secondary concern, perhaps as a kind of probabilistic/fuzzy measure, or for analytics.

I propose changing the behavior to the reset style, or adding a flag or new operator implementing this behavior. In addition, the behavior needs to be documented.

My present use cases for this are tied to network connectivity and interprocess communication.

bubenheimer commented 3 years ago

I forgot to mention that the obscurity of the present behavior is compounded by not being able to easily navigate to the source of these specific methods in the IDE (which I believe is due to current archive format limitations).

bubenheimer commented 3 years ago

A resetting retry count is essential also for implementing backoff (linear or exponential).

elizarov commented 3 years ago

This version of retry operator is far cry from the implementation of a full-blown backoff strategy. We've discussed designing providing one, but have decided that it is too domain-specific and is much better suited to be implemented in a separate library. The current version of retry operator is a mere replacement the corresponding Rx operators.

In light of the problem highlighted in this issue, we can provide a more generic version that does not have a built-in retries counter but will make it possible to keep any flow-associated state (such as retry count, last retry time, etc) to make complex retry/fail decisions. The existing retry implementations can be deprecated with a suggested replacement to more generic ones, thus, effectively, serving as an example of how you could implement a rudimentary retry counting.

bubenheimer commented 3 years ago

Thanks for the elaboration, makes sense!