Skip to content

Tracking Issue for mpmc #126840

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

Open
2 of 4 tasks
obeis opened this issue Jun 22, 2024 · 7 comments
Open
2 of 4 tasks

Tracking Issue for mpmc #126840

obeis opened this issue Jun 22, 2024 · 7 comments
Labels
C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@obeis
Copy link
Contributor

obeis commented Jun 22, 2024

Feature gate: #![feature(mpmc_channel)]

This is a tracking issue for mpmc_channel as described in ACP.

History

@obeis obeis added the C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC label Jun 22, 2024
@jieyouxu jieyouxu added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Jun 24, 2024
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 1, 2024
Add multi-producer, multi-consumer channel (mpmc)

Closes rust-lang#125712

Tracking issue: rust-lang#126840

r? m-ou-se
@ora-0
Copy link

ora-0 commented Jan 13, 2025

The sync::mpsc module's sync_channel function returned a SyncSender and SyncReceiver type, but the new mpmc module's sync_channel returns just a normal Sender and Receiver type. Is this symmetry something we want to preserve?

This shouldn't affect any usage of them, except for the slightly different documentation provided.

@ibraheemdev
Copy link
Member

ibraheemdev commented Jan 24, 2025

I wonder if there's a downside to SyncSender and Sender being separate types, and you would ever need to create an enum (which is unnecessary because they are internally enum) to switch between them dynamically. This seems unlikely as they have different semantics, but theoretically if you are only using try_send you may want to. I think this is less of a concern than keeping the modules consistent, but the SyncSender naming is itself confusing, so I'm not sure.

Zalathar added a commit to Zalathar/rust that referenced this issue Jan 27, 2025
fix doc for std::sync::mpmc

fix document of `std::sync::mpmc` (tracked in rust-lang#126840)
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Jan 27, 2025
fix doc for std::sync::mpmc

fix document of `std::sync::mpmc` (tracked in rust-lang#126840)
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jan 27, 2025
Rollup merge of rust-lang#135876 - usamoi:mpmc-doc, r=tgross35

fix doc for std::sync::mpmc

fix document of `std::sync::mpmc` (tracked in rust-lang#126840)
github-actions bot pushed a commit to tautschnig/verify-rust-std that referenced this issue Mar 11, 2025
fix doc for std::sync::mpmc

fix document of `std::sync::mpmc` (tracked in rust-lang#126840)
@andrew-otiv
Copy link

Does this channel deliver each value to all receivers? Or is it intended for building work queues? This is unclear from the existing documentation.

A multi-consumer channel with backpressure like this one would be most welcome in our application! Thanks everyone who is pushing this forward!

@glyn
Copy link
Contributor

glyn commented Apr 14, 2025

Does this channel deliver each value to all receivers? Or is it intended for building work queues? This is unclear from the existing documentation.

Great question! I've been digging around in the channels code recently trying to understand the precise behaviour and I can't see any evidence of each value being delivered to all receivers. In fact, there are a few indications that delivering each value to all receivers is not the intended behaviour:

  1. ACP (referenced in the OP) has a section "Motivating examples or use cases" which implies each value is delivered to at most one receiver.
  2. The MPMC tests do not clone any receivers.
  3. The crossbeam-channel crate, from which the MPMC code was derived, contains this example, which may settle the matter:
use crossbeam_channel::unbounded;

let (s1, r1) = unbounded();
let (s2, r2) = (s1.clone(), r1.clone());
let (s3, r3) = (s2.clone(), r2.clone());

s1.send(10).unwrap();
s2.send(20).unwrap();
s3.send(30).unwrap();

assert_eq!(r3.recv(), Ok(10));
assert_eq!(r1.recv(), Ok(20));
assert_eq!(r2.recv(), Ok(30));

Comments:

  1. I'd prefer ACP to state the intended behaviour explicitly.
  2. The lack of receiver cloning in the MPMC tests seems like a serious omission, unless this is tested somewhere else.

glyn added a commit to glyn/rust that referenced this issue Apr 15, 2025
Zalathar added a commit to Zalathar/rust that referenced this issue Apr 15, 2025
Zalathar added a commit to Zalathar/rust that referenced this issue Apr 15, 2025
@glyn
Copy link
Contributor

glyn commented Apr 15, 2025

@andrew-otiv I can confirm the following behaviour:

use std::sync::mpmc::*;

#[test]
fn receiver_cloning() {
    let (tx, rx) = channel::<i32>();
    let rx2 = rx.clone();

    tx.send(1).unwrap();
    tx.send(2).unwrap();

    assert_eq!(rx2.recv(), Ok(1));
    assert_eq!(rx.recv(), Ok(2));
}

Notes:

  1. Basic tests of MPMC receiver cloning #139836 passes the above test in CI (and should be merged in due course).
  2. DO NOT MERGE - Checking MPMC tests run by CI #139844 confirms the MPMC tests are actually run by CI.

@andrew-otiv
Copy link

andrew-otiv commented Apr 15, 2025

Thanks for clarifying that! I was hoping for a broadcast channel with try_send so we can panic when the buffer fills. In our application deadlocking or blowing up an unbounded buffer until OOM are both worse than crashing. Every multi consumer channel in both tokio and std can either block the sender, silently "leak" until oom, or drop values.

rust-timer added a commit to rust-lang-ci/rust that referenced this issue Apr 15, 2025
Rollup merge of rust-lang#139836 - glyn:test-mpmc-receiver-cloning, r=jhpratt

Basic tests of MPMC receiver cloning

Ref: rust-lang#126840 (comment)
@Skgland
Copy link
Contributor

Skgland commented Apr 15, 2025

I am not sure I quite understand your problem.

Every multi consumer channel in both tokio and std can either block the sender, silently "leak" until oom, or drop values.

Sender has a try_send, send_timeout and send_deadline methods for non-blocking behaviour and there is sync_channel to limit the amount of values in-flight which should resolve the silent "leak" until oom problem.

So the problem with this is that it drops in-flight values if the last receiver is dropped before all values are received?

Edit: Could there be a miscommunication of what it means that each value is delivered to only one receiver instead of being delivered to all receivers? My understanding is the following:

  • The only time a value is dropped by the channel is if the channel is closed (last receiver is dropped)
    before all in-flight values are received.
  • Otherwise all values send will be received by one of the receivers (the values isn't copied/cloned to all receivers).

github-actions bot pushed a commit to rust-lang/rustc-dev-guide that referenced this issue Apr 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants