Listen for responses of supervisors
Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
@@ -99,6 +99,16 @@ impl SupervisorClient {
|
||||
})
|
||||
}
|
||||
|
||||
/// Build a supervisor JSON-RPC payload but force a specific id (used for correlation).
|
||||
fn build_supervisor_payload_with_id(&self, method: &str, params: Value, id: u64) -> Value {
|
||||
json!({
|
||||
"jsonrpc": "2.0",
|
||||
"id": id,
|
||||
"method": method,
|
||||
"params": params,
|
||||
})
|
||||
}
|
||||
|
||||
fn encode_payload(payload: &Value) -> Result<String, SupervisorClientError> {
|
||||
let s = serde_json::to_string(payload)?;
|
||||
Ok(BASE64_STANDARD.encode(s.as_bytes()))
|
||||
@@ -147,6 +157,42 @@ impl SupervisorClient {
|
||||
)))
|
||||
}
|
||||
|
||||
/// Variant of call that also returns the inner supervisor JSON-RPC id used in the payload.
|
||||
/// This id is required to correlate asynchronous popMessage replies coming from Mycelium.
|
||||
pub async fn call_with_ids(
|
||||
&self,
|
||||
method: &str,
|
||||
params: Value,
|
||||
) -> Result<(String, u64), SupervisorClientError> {
|
||||
let inner_id = self.next_id();
|
||||
let inner = self.build_supervisor_payload_with_id(method, params, inner_id);
|
||||
let payload_b64 = Self::encode_payload(&inner)?;
|
||||
let result = self
|
||||
.mycelium
|
||||
.push_message(
|
||||
&self.destination,
|
||||
&Self::encode_topic(self.topic.as_bytes()),
|
||||
&payload_b64,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let out_id = if let Some(id) = MyceliumClient::extract_message_id_from_result(&result) {
|
||||
id
|
||||
} else if let Some(arr) = result.as_array()
|
||||
&& arr.len() == 1
|
||||
&& let Some(id) = MyceliumClient::extract_message_id_from_result(&arr[0])
|
||||
{
|
||||
id
|
||||
} else {
|
||||
return Err(SupervisorClientError::InvalidResponse(format!(
|
||||
"result did not contain message id: {result}"
|
||||
)));
|
||||
};
|
||||
|
||||
Ok((out_id, inner_id))
|
||||
}
|
||||
|
||||
/// Synchronous variant: wait for a JSON-RPC reply via Mycelium reply_timeout, and return the inner JSON-RPC "result".
|
||||
/// If the supervisor returns an error object, map to RpcError.
|
||||
pub async fn call_sync(
|
||||
@@ -308,6 +354,19 @@ impl SupervisorClient {
|
||||
self.call("job.run", params).await
|
||||
}
|
||||
|
||||
/// Typed wrapper returning both outbound Mycelium id and inner supervisor JSON-RPC id.
|
||||
pub async fn job_run_with_ids(
|
||||
&self,
|
||||
job: Value,
|
||||
) -> Result<(String, u64), SupervisorClientError> {
|
||||
let secret = self.need_secret()?;
|
||||
let params = json!([{
|
||||
"secret": secret,
|
||||
"job": job
|
||||
}]);
|
||||
self.call_with_ids("job.run", params).await
|
||||
}
|
||||
|
||||
pub async fn job_start(
|
||||
&self,
|
||||
job_id: impl Into<String>,
|
||||
|
Reference in New Issue
Block a user