Skip to content

Ch 21.3 - recv receives Ok(T) Buffered Messages after Sender has disconnected #4673

@FuPeiJiang

Description

@FuPeiJiang

URL to the section(s) of the book with this problem:

https://doc.rust-lang.org/book/ch21-03-graceful-shutdown-and-cleanup.html

Description of the problem:

Dropping sender closes the channel, which indicates no more messages will be sent. When [that] happens, all the calls to recv that the Worker instances do in the infinite loop will return an error.

that should be: when there are no more messages buffered (and the sender has disconnected)

This causes confusion when interpreting the output:

Worker 0 got a job; executing.
Shutting down.
Shutting down worker 0
Worker 3 got a job; executing.
Worker 1 disconnected; shutting down.
Worker 2 disconnected; shutting down.
Worker 3 disconnected; shutting down.
Worker 0 disconnected; shutting down.
Shutting down worker 1
Shutting down worker 2
Shutting down worker 3

When Shutting down worker 0 is printed, Sender should already have disconnected, yet Worker 3 is still able to receive a message: Worker 3 got a job; executing.

Shutting down worker 0 printed after drop:

        drop(self.sender.take());

        for worker in &mut self.workers {
            println!("Shutting down worker {}", worker.id);
                let message = receiver.lock().unwrap().recv();

                match message {
                    Ok(job) => {
                        println!("Worker {id} got a job; executing.");

Suggested fix:

Add this line:
However, since channels are buffered, messages sent before the disconnect will still be properly received.
From: https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver.html#method.recv


Extra:
is it a bug that during graceful shutdown, all buffered messages will be processed before shutting down ?
There could be potentially thousands of buffered messages.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions