Notify superseded plugin processes and support SDK draining
This commit is contained in:
@@ -201,6 +201,88 @@ fn protocol() {
|
||||
assert_eq!(outgoing["method"], "other.background");
|
||||
p.answer(&outgoing, json!({}));
|
||||
assert!(p.child.wait().unwrap().success());
|
||||
// Replacement is a notification, not EOF. Drain keeps both endpoint handlers
|
||||
// and background calls alive, while closing idle connections and the listener.
|
||||
assert!(
|
||||
!d["result"]["methods"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|m| m["name"] == "rpc.superseded" || m["name"] == "superseded")
|
||||
);
|
||||
std::fs::remove_file(dir.join("stopped")).unwrap();
|
||||
let mut provider = start(&wasm, &dir);
|
||||
provider.request("serve", json!({}));
|
||||
assert_eq!(provider.read()["result"], Value::Null);
|
||||
provider.request("start", json!({}));
|
||||
let first = provider.read();
|
||||
let second = provider.read();
|
||||
let background = if first["method"] == "other.background" {
|
||||
first
|
||||
} else {
|
||||
second
|
||||
};
|
||||
assert_eq!(background["method"], "other.background");
|
||||
let address = std::fs::read_to_string(dir.join("endpoint"))
|
||||
.unwrap()
|
||||
.split_whitespace()
|
||||
.next()
|
||||
.unwrap()
|
||||
.trim_start_matches("tcp:")
|
||||
.to_owned();
|
||||
let mut idle = std::net::TcpStream::connect(&address).unwrap();
|
||||
idle.set_read_timeout(Some(std::time::Duration::from_secs(4)))
|
||||
.unwrap();
|
||||
writeln!(
|
||||
idle,
|
||||
"{}",
|
||||
json!({"jsonrpc":"2.0","id":0,"method":"rpc.endpoint","params":{}})
|
||||
)
|
||||
.unwrap();
|
||||
let mut idle = BufReader::new(idle);
|
||||
let mut line = String::new();
|
||||
idle.read_line(&mut line).unwrap();
|
||||
assert_eq!(
|
||||
sausage_plugin::serde_json::from_str::<Value>(&line).unwrap()["id"],
|
||||
0
|
||||
);
|
||||
let mut active = std::net::TcpStream::connect(&address).unwrap();
|
||||
active
|
||||
.set_read_timeout(Some(std::time::Duration::from_secs(4)))
|
||||
.unwrap();
|
||||
writeln!(
|
||||
active,
|
||||
"{}",
|
||||
json!({"jsonrpc":"2.0","id":1,"method":"wait","params":{}})
|
||||
)
|
||||
.unwrap();
|
||||
let inflight = provider.read();
|
||||
assert_eq!(inflight["method"], "other.inflight");
|
||||
provider
|
||||
.send(json!({"jsonrpc":"2.0","method":"rpc.superseded","params":{"current":"new-hash"}}));
|
||||
let hook = provider.read();
|
||||
assert_eq!(hook["method"], "other.superseded");
|
||||
assert_eq!(hook["params"]["current"], "new-hash");
|
||||
provider.answer(&hook, json!({}));
|
||||
assert_eq!(provider.read()["params"]["name"], "draining");
|
||||
line.clear();
|
||||
assert_eq!(idle.read_line(&mut line).unwrap(), 0);
|
||||
assert!(std::net::TcpStream::connect(&address).is_err());
|
||||
assert!(provider.child.try_wait().unwrap().is_none());
|
||||
provider.answer(&inflight, json!({}));
|
||||
line.clear();
|
||||
BufReader::new(active).read_line(&mut line).unwrap();
|
||||
assert_eq!(
|
||||
sausage_plugin::serde_json::from_str::<Value>(&line).unwrap()["result"],
|
||||
"finished"
|
||||
);
|
||||
assert!(provider.child.try_wait().unwrap().is_none());
|
||||
provider.answer(&background, json!({}));
|
||||
provider.finishes();
|
||||
assert!(
|
||||
!dir.join("stopped").exists(),
|
||||
"drain is not the EOF stop hook"
|
||||
);
|
||||
let provider_doc = &d["result"];
|
||||
let imports = target.join("imports");
|
||||
std::fs::create_dir_all(&imports).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user