You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AsyncStream.Continuation.YieldResult exists in no small part to help implement backpressure. It seems designed to let users respond to slow consumption of a buffered stream.
Unfortunately, it's not really possible to take action based on the return value if you cannot tolerate data loss. In particular, .enqueued(remaining: 0) is a particularly tricky return value. This value signals that the next call to yield may return .dropped.
The problem is that the user of AsyncStream cannot take any action in the face of this return value. There appears to be no way to wait for this situation to resolve itself. As a result, users are forced to essentially sleep for some period of time and then optimistically try again. This either burns CPU (if we poll too frequently) or increases latency (if we poll too infrequently).
This leaves the only backpressure-aware option on AsyncStream as the init(unfolding:onCancellation: model. Unfortunately, this init uses "pull-based" backpressure, where an async function is called whenever there is space. If the user is holding an AsyncSequence of their own then they are forced to manually hold the AsyncIterator in order to implement this.
It would be nice to have a complementary API to the return values of yield that lets us wait until we can be confident that yielding a value is likely to succeed.
The text was updated successfully, but these errors were encountered:
It may be possible to augment this API with an async yield counterpart that would allow suspending until space is available in the buffer...
This limitation came up in real API design in the http client over here: swift-server/async-http-client#406 and if i remember correctly we had discussed it as well during the review of the type's initial introduction. This should be possible to solve on the same type with augmenting its functionality hopefully
Additional Detail from JIRA
md5: a8ee54f92c5ada6649ec437f217b0051
Issue Description:
AsyncStream.Continuation.YieldResult
exists in no small part to help implement backpressure. It seems designed to let users respond to slow consumption of a buffered stream.Unfortunately, it's not really possible to take action based on the return value if you cannot tolerate data loss. In particular,
.enqueued(remaining: 0)
is a particularly tricky return value. This value signals that the next call toyield
may return.dropped
.The problem is that the user of
AsyncStream
cannot take any action in the face of this return value. There appears to be no way to wait for this situation to resolve itself. As a result, users are forced to essentially sleep for some period of time and then optimistically try again. This either burns CPU (if we poll too frequently) or increases latency (if we poll too infrequently).This leaves the only backpressure-aware option on
AsyncStream
as theinit(unfolding:onCancellation:
model. Unfortunately, this init uses "pull-based" backpressure, where anasync
function is called whenever there is space. If the user is holding anAsyncSequence
of their own then they are forced to manually hold theAsyncIterator
in order to implement this.It would be nice to have a complementary API to the return values of
yield
that lets us wait until we can be confident that yielding a value is likely to succeed.The text was updated successfully, but these errors were encountered: