ts/Task: split iterate into try_next and handle_item
This MR addresses the section "Fix iterate
behaviour" in this plan.
Previous Task iteration model suffered from the following shortcomings:
- When an iteration was engaged it could be cancelled at await points by Stop or Flush state transitions, which could lead to inconsistent states.
- When an iteration was engaged it could not be cancelled by a Pause state transition so as to prevent data loss. This meant we couldn't block on the Pause request because the mechanism couldn't guarantee Paused would be reached in a timely manner.
This commit split the Task iteration into:
-
try_next
: this function returns a future that awaits for a new iteration to begin. The regular use case is to return an item to process. The item can be left to()
iftry_next
acts as a tick generator. It can also return an error. This function can be cancelled at await points when a state transition request occurs. -
handle_item
: this function is called with the item returned bytry_next
and is guaranteed to run to completion even if a transition request is received.
Note that this model plays well with the common Future cancellation pitfalls in Rust.
As with previous rework, I applied limited changes to ts-jitterbuffer
in order to ease rebase of pending changes.