test(daemon): match a reply by its id instead of taking the next line
A connection that has joined a room receives event notifications on the same socket as its replies, so a notification landing between a request and its answer was read as the answer. Only replies carry an id.
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
# Generated and compared byte-for-byte by `daemon::openrpc::document_is_current`,
|
||||||
|
# which builds its expectation with `\n`. A CRLF checkout would fail that test on
|
||||||
|
# Windows.
|
||||||
|
docs/openrpc.json text eol=lf
|
||||||
@@ -158,9 +158,21 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Send one line and read the reply, `None` if the daemon hung up first.
|
/// Send one line and read the reply, `None` if the daemon hung up first.
|
||||||
|
///
|
||||||
|
/// Events share the socket with replies, so a subscribed connection can
|
||||||
|
/// have a notification land between the request and its answer. Only a
|
||||||
|
/// reply carries an `id`; skip everything that does not.
|
||||||
fn call(&mut self, line: &str) -> Option<String> {
|
fn call(&mut self, line: &str) -> Option<String> {
|
||||||
self.send(line)?;
|
self.send(line)?;
|
||||||
self.read()
|
loop {
|
||||||
|
let reply = self.read()?;
|
||||||
|
let is_notification =
|
||||||
|
serde_json::from_str::<serde_json::Value>(&reply)
|
||||||
|
.is_ok_and(|parsed| parsed.get("id").is_none());
|
||||||
|
if !is_notification {
|
||||||
|
return Some(reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send(&mut self, line: &str) -> Option<()> {
|
fn send(&mut self, line: &str) -> Option<()> {
|
||||||
|
|||||||
Reference in New Issue
Block a user