Browse Source

Refactor daemon's JSONRPC retries

This should handle also "retriable" JSONRPC errors (e.g. RPC_IN_WARMUP)
refactor-mempool
Roman Zeyde 7 years ago
parent
commit
fc8656f7a4
No known key found for this signature in database GPG Key ID: 87CAE5FA46917CBB
  1. 42
      src/daemon.rs

42
src/daemon.rs

@ -370,11 +370,28 @@ impl Daemon {
Ok(result) Ok(result)
} }
fn retry_call_jsonrpc(&self, method: &str, request: &Value) -> Result<Value> { fn handle_request_batch(&self, method: &str, params_list: &[Value]) -> Result<Vec<Value>> {
let id = self.message_id.next();
let reqs = params_list
.iter()
.map(|params| json!({"method": method, "params": params, "id": id}))
.collect();
let mut results = vec![];
let mut replies = self.call_jsonrpc(method, &reqs)?;
if let Some(replies_vec) = replies.as_array_mut() {
for reply in replies_vec {
results.push(parse_jsonrpc_reply(reply.take(), method, id)?)
}
return Ok(results);
}
bail!("non-array replies: {:?}", replies);
}
fn retry_request_batch(&self, method: &str, params_list: &[Value]) -> Result<Vec<Value>> {
loop { loop {
match self.call_jsonrpc(method, request) { match self.handle_request_batch(method, params_list) {
Err(Error(ErrorKind::Connection(msg), _)) => { Err(Error(ErrorKind::Connection(msg), _)) => {
warn!("connection failed: {}", msg); warn!("reconnecting due to {}", msg);
self.signal.wait(Duration::from_secs(3))?; self.signal.wait(Duration::from_secs(3))?;
let mut conn = self.conn.lock().unwrap(); let mut conn = self.conn.lock().unwrap();
*conn = conn.reconnect()?; *conn = conn.reconnect()?;
@ -386,28 +403,13 @@ impl Daemon {
} }
fn request(&self, method: &str, params: Value) -> Result<Value> { fn request(&self, method: &str, params: Value) -> Result<Value> {
let mut values = self.requests(method, &[params])?; let mut values = self.retry_request_batch(method, &[params])?;
assert_eq!(values.len(), 1); assert_eq!(values.len(), 1);
Ok(values.remove(0)) Ok(values.remove(0))
} }
fn requests(&self, method: &str, params_list: &[Value]) -> Result<Vec<Value>> { fn requests(&self, method: &str, params_list: &[Value]) -> Result<Vec<Value>> {
let id = self.message_id.next(); self.retry_request_batch(method, params_list)
let reqs = params_list
.iter()
.map(|params| json!({"method": method, "params": params, "id": id}))
.collect();
let mut results = vec![];
let mut replies = self
.retry_call_jsonrpc(method, &reqs)
.chain_err(|| format!("RPC failed: {}", reqs))?;
if let Some(replies_vec) = replies.as_array_mut() {
for reply in replies_vec {
results.push(parse_jsonrpc_reply(reply.take(), method, id)?)
}
return Ok(results);
}
bail!("non-array replies: {:?}", replies);
} }
// bitcoind JSONRPC API: // bitcoind JSONRPC API:

Loading…
Cancel
Save