Fix deadlock on PluginCustomValue drop (#12418)

# Description
Because the plugin interface reader thread can be responsible for
sending a drop notification, it's possible for it to end up in a
deadlock where it's waiting for the response to the drop notification
call.

I decided that the best way to address this is to just discard the
response and not wait for it. It's not really important to synchronize
with the response to `Dropped`, so this is probably faster anyway.

cc @ayax79, this is your issue where polars is getting stuck

# User-Facing Changes
- A bug fix
- Custom value plugin: `custom-value handle update` command

# Tests + Formatting

Tried to add a test with a long pipeline with a lot of drops and run it
over and over to reproduce the deadlock.

- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
This commit is contained in:
Devyn Cairns
2024-04-05 19:57:00 -07:00
committed by GitHub
parent 82b7548c0c
commit c82dfce246
5 changed files with 141 additions and 11 deletions

View File

@ -195,6 +195,28 @@ fn handle_make_then_get_success() {
assert!(actual.status.success());
}
#[test]
fn handle_update_several_times_doesnt_deadlock() {
// Do this in a loop to try to provoke a deadlock on drop
for _ in 0..10 {
let actual = nu_with_plugins!(
cwd: "tests",
plugin: ("nu_plugin_custom_values"),
r#"
"hEllO" |
custom-value handle make |
custom-value handle update { str upcase } |
custom-value handle update { str downcase } |
custom-value handle update { str title-case } |
custom-value handle get
"#
);
assert_eq!(actual.out, "Hello");
assert!(actual.status.success());
}
}
#[test]
fn custom_value_in_example_is_rendered() {
let actual = nu_with_plugins!(