-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
executable file
·64 lines (56 loc) · 2.27 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
'use strict';
const RpcClientBase = require('bitcoind-rpc');
const { promisify } = require('util');
const URL = require('url').URL;
const defaults = { maxRetries: 0, retryDelayMs: 100, logger: console, timeoutMs: 5000 };
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
class RpcClientRetry extends RpcClientBase {
constructor(url, opts={}) {
const {
protocol,
username: user,
password: pass,
hostname: host,
port
} = new URL(url);
super({
protocol: protocol.replace(/:$/, ''),
user,
pass,
host,
port});
this.maxRetries = opts.maxRetries || defaults.maxRetries; // number of retries before throwing an exception (default: 5)
this.retryDelayMs= opts.retryDelayMs || defaults.retryDelayMs; // delay between each retry (default: 100ms)
this.logger = opts.logger || defaults.logger; // setup logger (default: console)
this.timeoutMs = opts.timeoutMs || defaults.timeoutMs; // max timeout for each retry
//Object.setPrototypeOf(RpcClientRetry.prototype, RpcClientBase.prototype);
for (const key of Object.keys(RpcClientBase.callspec)) {
const fn = promisify(RpcClientBase.prototype[key]);
this[key] = async function() {
for(let i = 0; i <= this.maxRetries; i++) {
try {
const timeout = new Promise((resolve, reject) => {
let id = setTimeout(() => {
clearTimeout(id);
reject('Timed out in '+ this.timeoutMs + 'ms.');
}, this.timeoutMs)
})
const { result } = await Promise.race([ Reflect.apply(fn, this, arguments), timeout ]);
return result;
} catch(err) {
if(i + 1 === this.maxRetries)
throw err;
else {
if(this.logger)
this.logger.log("[bitcoin-rpc-promise-retry] Retry", i + 1, key, err);
await sleep(this.retryDelayMs);
}
}
}
throw Error("[bitcoin-rpc-promise-retry] no rpc call made for", key);
};
this[key.toLowerCase()] = this[key];
}
}
}
module.exports = RpcClientRetry;