async-stream
async-stream copied to clipboard
try_stream is !Send with ? and MutexGuard or try-block
- MutexGuard
try_stream! {
{
let _guard = mutex.try_lock().unwrap();
Err(200)?;
}
{
yield 100;
}
}
Err(200)? is expanded by try_stream! to something like __yield_tx.send(::core::result::Result::Err(200).await;
This makes the stream !Send.
note: future is not `Send` as this value is used across an await
This can be fixed if async-stream captures the error and tx.send in the outermost block.
let result = Result<_,_> = || {
.. user code ..
};
match result {
Ok(..) => ..
Err(err) => __yield_tx.send(..).await;
}
- try-block
A workaround is to capture the error in result: Result<..> and emit the error after MutexGuard is dropped.
However, async-stream does not recognize ? in try-blocks.
try_stream! {
let result = {
let _guard = mutex.try_lock().unwrap();
let result: Result<..> = try {
Err(200)?; // async-stream expands this to `tx.send(..)`.
Ok(())
};
result
};
result?;
{
yield 100;
}
}
Is this an std::sync::Mutex? The guards on those are not send. If you need to hold a mutex guard over an await boundary, use tokio::sync::Mutex.
crossbeam Mutex is used because I know try_lock() always succeeds in my case and it probably has lower latency than async version.
The issue is that I didn't use the object over an await boundary but try_stream! macro did.