-
Notifications
You must be signed in to change notification settings - Fork 636
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
impl AsyncRead/AsyncWrite for Arc<T> #2139
Conversation
This seems broken for all Unless you can add a constraint that guarantees that the underlying object is able to handle multiple concurrent IOs safely, I don't think this should be added. |
@Matthias247 Both |
My problem with these impls is just that it makes the chance of wrongly interleaved reads/writes higher, I assume in most cases the intention is to just support splitting into a read/write pair, which IMO would be better supported by inherent If these are to be provided, should there be the same for |
Maybe. But letting users guess what is supported just sounds like a bad idea. If a certain implementation supports splitting/cloning, they can directly add methods that indicate that. I am not sure what the benefit of the generalization here is. And some more background: I think |
Can you elaborate what is the problem here? How could operations be interleaved wrongly and under what circumstances? To clarify, I think I understand what you're worried about - it's just that my opinion is that issues in question are so contrived and unrealistic they simply aren't a problem. Not once this came up in async-std's history. And the worst issue I can see is a memory leak. But then again, there are so many other non-contrived memory leaks that make this one not worth thinking about, in my opinion.
Yes - why not! :) Channels in
The point of the generalization is that we're forced to re-invent a fundamental type in
I fully agree! If |
By wrong interleaving I mean things like splinched reads let x = spawn({
let reader = reader.clone();
async move {
let mut buf = [0; 2];
reader.read_exact(&mut buf).await?;
Ok(buf)
}
});
let y = spawn(async move {
let mut buf = [0; 2];
reader.read_exact(&mut buf).await?;
Ok(buf)
});
let (x, y) = try_join(x, y).await?; Depending on exact timings a data stream sent as The same can happen with interleaved writes from concurrent tasks. |
@Nemo157 Thanks for the example! So, I see the issue, but this is also possible with I/O in the standard library, so why apply different standards here? |
I feel like the std shared IO impls were a mistake too, they might more directly match the underlying platform capabilities, but I've not seen the utility of them compared to the potential for issues (though TBH I've not seen any issues actually arise in real code). I'm not really against adding these impls, if IO runtimes want to support shared access then having these will just make using those slightly easier, it's the IO runtime's choice to support them. |
Those types should not implement I think providing blanket impls where possible is a feature. It removes friction when designing API's and also when using them. |
@@ -347,6 +348,29 @@ mod if_std { | |||
deref_async_read!(); | |||
} | |||
|
|||
#[allow(single_use_lifetimes)] // FIXME: https://github.com/rust-lang/rust/issues/69952 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fwiw: This is rust-lang/rust#55058, not 69952
looks like there is no known AsyncRead/AsyncWrite implementation that actually supports any number of concurrent I/O operations (smol-rs/async-io#38 (comment)), so I'll close this for now. |
In
async-std
it is common to share I/O types by storing them inside anArc
. It would be nice then forArc<T>
to also be an I/O type by implementingAsyncRead
andAsyncWrite
. In fact, this is exactly why theio-arc
crate was invented: https://docs.rs/io-arc/1.0.0/io_arc/I'm now working on a new runtime where this pattern is pervasive and am also using a variant of
IoArc
. It would be nice forfutures
to add this impl instead.