-
Notifications
You must be signed in to change notification settings - Fork 950
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
Address review on stable-futures #1373
Conversation
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.
Looks good to me. More details in the log might make it easier for newcomers.
Co-Authored-By: Max Inden <mail@max-inden.de>
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.
👍
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.
I think we should return a Result
from start_broadcast
. A full channel is not the only error condition, the task may be gone for example. Also, the combination of start_broadcast
and poll_ready_broadcast
is racy if I am not mistaken.
There are only two possibilities: a full channel, or the task gone. A task being gone is a normal code path. It's totally possible for the task to close itself right after
For the "full channel" possibility, they can't be racy. They both take a |
I think that an API can only be considered non-racy if the API can ensure that a sequence of operations is not interleaved by multiple threads (or rather that its correctness does not depend on it), but not when relying on the caller to establish this invariant. For example, this API pub fn api(&mut self, ...) {
self.a();
self.b();
}
fn a(&mut self) { ... }
fn b(&mut self) { ... } is non-rancy as the pub fn a(&mut self) { ... }
pub fn b(&mut self) { ... } can not establish this invariant as mentioned here. |
I don't understand the reasoning. // thread 1 (t1: Arc<Mutex<Vec<T>>>):
if !t1.lock().is_empty() {
t1.lock().remove(0);
}
// thread 2 (t2: Arc<Mutex<Vec<T>>>):
if !t2.lock().is_empty() {
t2.lock().remove(0);
} But that doesn't mean that |
It is similar to the |
From my understanding, what makes such an API racy, and the crucial difference to e.g. the Just my two cents. EDIT: @twittner beat me to it. I basically wrote the same thing as the above. |
Returning an error raises another problem: since we send on the channel once for each node, what do we do if for example we successfully send the message to 5 nodes, but the 6th node's channel is full? We obviously can't cancel sending to the first five. |
Yes, that is a problem. Maybe we could do with something like this: pub fn broadcast<I: Clone>(&mut self, event: &I, cx: &mut Context) -> Poll<()> {
for task in self.tasks.values_mut() {
if task.sender.poll_ready(cx).is_not_ready() {
return Poll::Pending
}
}
for task in self.tasks.values_mut() {
task.sender.start_send(...) ...
}
Poll::Ready(())
} |
I changed the PR completely. |
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.
👍
No description provided.