Open hozan23 opened 1 week ago
Thanks. Atomics always have a cost so best to leave it to the user if they're ok with paying that cost.
@zeenix I agree about the cost of using AtomicU64
, but async-broadcast
is generally used for managing many receivers that are shared across many tasks. As a user, I would end up wrapping all the receivers with a Mutex
, which would be more expensive than just using AtomicU64 for pos
field, no?
async-broadcast
is generally used for managing many receivers that are shared across many tasks.
I'd believe so (even though I don't have sufficient data to back it up), yes. However, each task can own a clone of the receiver and don't necessarily need to use interior mutability.
As a user, I would end up wrapping all the receivers with a
Mutex
,
If you need interior mutability in your design, yes.
which would be more expensive than just using AtomicU64 for
pos
field, no?
Perhaps but I don't know how they both compare in terms of performance. If you've some data on this, I'd be very curious to know.
@zeenix Sorry for the late response here.
I'd believe so (even though I don't have sufficient data to back it up), yes. However, each task can own a clone of the receiver and don't necessarily need to use interior mutability.
That's indeed true, but most of the time the task will be spawned inside a method of a struct, and usually the struct will own the receiver (that's how I use it :)). So, I think using interior mutability is important most of the time
Perhaps but I don't know how they both compare in terms of performance. If you've some data on this, I'd be very curious to know.
I will open a draft pull request soon with some benchmarks.
I'd believe so (even though I don't have sufficient data to back it up), yes. However, each task can own a clone of the receiver and don't necessarily need to use interior mutability.
That's indeed true, but most of the time the task will be spawned inside a method of a struct, and usually the struct will own the receiver (that's how I use it :)).
But why does that necessitate interior mutability? You need mutability on the struct level then.
I will open a draft pull request soon with some benchmarks.
👍
But why does that necessitate interior mutability? You need mutability on the struct level then.
Here is an example:
use std::sync::Arc;
struct Task {
stop_signal: async_channel::Receiver<String>,
b_stop_signal: async_broadcast::Receiver<String>,
}
impl Task {
async fn run(self: Arc<Self>) {
smol::spawn({
async move {
loop {
let msg = self.stop_signal.recv().await;
}
}
})
.detach();
}
async fn run2(self: Arc<Self>) {
smol::spawn({
async move {
loop {
// XXX this will not work.
let msg = self.b_stop_signal.recv().await;
}
}
})
.detach();
}
}
Here is an example:
Thanks but I don't need examples of cases where you need interior mutability. In my own project, I need interior mutability. My point was that it all depends on the design. You don't always have to put things in an Arc
.
The question is how much faster are atomic locks compared to (async) mutexes/rwlocks to justify:
&mut self
to &self
isn't a breakage but the other way around is. So if we decide in the future that we actually need mutability, we'll have a problem. Keep in mind, we want to go 1.0 soon (https://github.com/smol-rs/smol/issues/310) of API break would be more an issue after that.Thanks but I don't need examples of cases where you need interior mutability. In my own project, I need interior mutability. My point was that it all depends on the design. You don't always have to put things in an Arc.
Yes indeed, I was just showing an example of the need for interior mutability.
The question is how much faster are atomic locks compared to (async) mutexes/rwlocks to justify:
I am aware that there might be breaking changes in the API. I need to research more about that and conduct some benchmarks.
Keep in mind, we want to go 1.0 soon (https://github.com/smol-rs/smol/issues/310) of API break would be more an issue after that.
That's amazing news!
So if we decide in the future that we actually need mutability, we'll have a problem.
To be honest, I can't imagine any case where mutability is needed. async-channel
doesn't need mutability and is used more widely than async-broadcast
.
Hello,
I noticed that the only reason
recv()
,recv_direct()
, andtry_recv()
need to take&mut self
to modify the value ofself.pos
. IfAtomicU64
is used instead, there will be no need to use&mut self
there.