Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upImprove worker shutdown #26628
Improve worker shutdown #26628
Conversation
highfive
commented
May 24, 2020
|
Heads up! This PR modifies the following files:
|
highfive
commented
May 24, 2020
|
@bors-servo try=wpt |
[WIP] Add mechanism to join on service- and dedicated-worker threads <!-- Please describe your changes on the following line: --> FIX #26548 and also a step towards #26502 --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [ ] `./mach build -d` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #___ (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
|
@asajeffrey r? |
994b56c
to
db402be
|
@asajeffrey Review ping. |
| // and handle the event. | ||
|
|
||
| // Shutdown. | ||
| assert!(msg.is_err()); |
This comment has been minimized.
This comment has been minimized.
asajeffrey
May 29, 2020
Member
Using an error rather than a message for signalling shutdown seems odd?
|
LGTM apart from some nits. |
| /// A receiver of control messages, | ||
| /// currently only used to signal shutdown. | ||
| #[ignore_malloc_size_of = "Channels are hard"] | ||
| control_receiver: Receiver<()>, |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
gterzian
May 30, 2020
•
Author
Member
The idea is that the shutdown is signalled by dropping the sender(and to avoid explicit shutdown messages), and the () is used as a placeholder since no other messages are used for now. Re the sthutdown, I'll answer below.
This comment has been minimized.
This comment has been minimized.
matklad
May 30, 2020
•
I also like using Never as a message type in these cases, which make it clear(I.e statically impossible) to send a message: https://github.com/rust-lang/rls/blob/17a439440e6b00b1f014a49c6cf47752ecae5bb7/rls/src/concurrency.rs#L88
It also removes the question of handling OK case on the receive side (you write an empty match: match never {})
Admittedly, “wtf is Sender<Never>“ is a common reaction when people see such code for the first time. On the flip side, once they learn the pattern, shutdown: Sender<Never> becomes an immediately recognized code shape.
This comment has been minimized.
This comment has been minimized.
| .take() | ||
| .expect("No control sender to worker thread."), | ||
| ); | ||
|
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
gterzian
May 30, 2020
•
Author
Member
I tried to write this down over at #26502
While we use a lot of exit messages throughout the codebase, I think @matklad had a good point that relying on dropping channels is better, because it removes all sort of opportunities for accidental bad designs.
This pattern might not be applicable where there is a process boundary and IPC, and in this case where a thread shuts-down and then needs to shutdown it's worker threads, it seems effective, and I also like that it enforces the need for a dedicated "control" channel for parent -> child communication, whereas with an exit message it would have been tempting to just re-use one of the existing channels.
So for example, if the control channel from the "parent" thread is cloned and passed to child or peer threads somewhere, then the shut-down mechanism will fail, and that would then force us to not clone the control channel and instead introduce a new dedicated kind of channel for the communication pattern at hand.
One could say that you loose the difference between an explicit shutdown, and just a panic from the parent thread, however in practice both should result in shutdown of the worker, and since they're in the same process the panic would take everything down with it right?
Please let me know what you think of this.
This comment has been minimized.
This comment has been minimized.
asajeffrey
Jun 2, 2020
Member
My personal taste would be to use shutdown messages, and reserve dropping channels for the case where the sender has panicked. This is just taste though, it'll be the same shutdown code running in either case.
| .take() | ||
| .expect("No handle to join on worker.") | ||
| .join() | ||
| .expect("Couldn't join on worker thread."); |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
asajeffrey
Jun 2, 2020
Member
Another matter of taste, since I think the join only fails if the worker panics? Personally I'd log an error and try to carry on.
| self.control_sender | ||
| .take() | ||
| .expect("No control sender to worker thread."), | ||
| ); |
This comment has been minimized.
This comment has been minimized.
| /// currently only used to signal shutdown. | ||
| control_sender: Option<Sender<()>>, | ||
| /// A handle to join on the worker thread. | ||
| join_handle: Option<JoinHandle<()>>, |
This comment has been minimized.
This comment has been minimized.
matklad
May 30, 2020
•
There are two places in this PR where we have optional shutdown signal, optional Thread handle, and we do “take then join” in Drop. If we wrap JoinHandle into a type which joins on Drop, than we can remove options and custom code from Drop (and one custom Drop impl altogether) and replace them with // filed(drop) order is significant comment.
https://github.com/rust-analyzer/ra_vfs/blob/c4a2aaaf3c2d5231b11ee21a5f6ca34c3955805c/src/io.rs#L55
This comment has been minimized.
This comment has been minimized.
gterzian
May 30, 2020
•
Author
Member
Thanks, noted, I think that's something I might look into if we end-up doing this in more places.
Personally I'm not sure relying on comments and field order is necessarily more robust than some additional explicit code like with those drop implementations...
In one of the two cases the options seem necessary because the worker thread is not created when the initial struct is created...
This comment has been minimized.
This comment has been minimized.
matklad
May 30, 2020
Yeah, I also prefer to write something than to rely on implicit drop order. What swayed me for VFS case is that I was able to remove the Option(which unfortunately infected code other than Drop). If OptIon is required anyway, manual impl indeed would be better.
40bbd5e
to
45c3ca9
|
@asajeffrey Ok, comments addressed, we can always discuss the various approaches further as part of #26502 |
|
LGTM. |
|
@bors-servo r=asajeffrey |
|
|
Improve worker shutdown <!-- Please describe your changes on the following line: --> FIX #26548 FIX #25212 and also a step towards #26502 --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [ ] `./mach build -d` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #___ (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
|
|
|
@bors-servo retry (the css issue I don't want to look-up right now) |
|
That's #23290. |
|
|
gterzian commentedMay 24, 2020
•
edited
FIX #26548
FIX #25212
and also a step towards #26502
./mach build -ddoes not report any errors./mach test-tidydoes not report any errors