Open xlc opened 12 hours ago
Hey, thanks for reaching out!
You can get the same effect as non blocking send by using select:
Task {
await select {
send("b", to: b)
none { // called if send is not ready }
}
}
In this case, the task will never block waiting to send. Does this cover your use case? If not I am happy to work together to find the right API.
Unfortunately I am dealing with C callback here so no async/await allowed. I would like to return an error code when buffer is already full from the callback, which will indicate the library the data is not processed.
Unfortunately I am dealing with C callback here so no async/await allowed.
Given the existing solution you shared - are you able to call that code? Since it also includes an async function as well wrapped in a task.
Conceptually you could also do this:
if channel.count < maxSize {
Task {
await channel.send(data)
}
} else {
// channel full
}
This would generally prevent you from stacking back pressure on the dispatch queue (assuming there are not competing threads writing to the channel).
Yes that will work. In my case there is only a singe writer and single reader. But I still think a sync API will be nice. For example, send
in Rust channel is sync: https://doc.rust-lang.org/std/sync/mpsc/struct.Sender.html#method.send
Can we have a
send
method that is notasync
that only doesnonBlockingSend
and return false if that failed due to buffer full?Use case: I am working with a C networking library. When it received data, my callback is called, and I am doing
and when the buffer is full, the back pressure essentially goes to the dispatch queue, which is not what I wanted. If there is a sync send that fails when buffer is full, then I can tell the networking library to close the connection and notify upstream.
I noted there is a count method so I can inspect it and implements the back pressure correctly, but still with async send, there is still some unnecessary overheads.
I can make a PR if needed.