3.x: Add eager truncation to bounded replay() to avoid item retention by akarnokd · Pull Request #6532 · ReactiveX/RxJava (original) (raw)
This PR adds the eagerTruncate
option to the replay
operator so that the head
node will lose the item reference it holds upon truncation.
The bounded buffers in replay
implement a linked list that when truncated, moves the head reference forward along the links atomically. This allows late consumers to pick up the head and follow the links between them to get items replayed. However, the truncation may happen concurrently with a consumer working on some prior nodes so if the truncation would null
out the value, the consumer reaching the same node would see null
as well and fail.
To avoid this type of retention, the head node has to be refreshed with a new node still pointing to the next node in the chain but without any value.
The reason this is not the default is that it requires an additional allocation for each new incoming value when the buffer is full, which would reduce performance in cases where the excess retention is not a problem.
Overloads to both the direct and function-variants of both Flowable.replay()
and Observable.replay()
have been added. To avoid too many overloads, only one extra overload has been added extending the signature of the longest parameterized method per each bounds mode (size, time, time+size).
Their unit test files have been cloned so that both the non-eager (original) behavior and the eager behavior is tested separately.
Fixes #6475