Comparing version 0.6.4 to 0.7.0
157
index.js
@@ -49,12 +49,5 @@ /** | ||
fallback: false, | ||
latency: true, | ||
logs: false | ||
}, | ||
// network load balancer | ||
balancer: true, | ||
// remove unresponsive nodes | ||
excision: false, | ||
// use IPC (only available on Node + Linux/OSX) | ||
@@ -75,4 +68,2 @@ ipcpath: null, | ||
BALANCER_SAMPLES: 20, | ||
DEFAULT_GAS: "0x2fd618", | ||
@@ -91,18 +82,2 @@ | ||
primaryNode: null, | ||
// Mean network latency for each node | ||
latency: {}, | ||
// Number of latency samples taken for each node | ||
samples: {}, | ||
// Unweighted mean network latency across all nodes | ||
// (use debug.latency=true to see this) | ||
netLatency: null, | ||
// Total number of samples taken across all nodes | ||
// (use debug.latency=true to see this) | ||
netSamples: 0, | ||
requests: 1, | ||
@@ -256,21 +231,2 @@ | ||
exciseNode: function (err, deadNode, callback) { | ||
if (deadNode && !this.nodes.local && !this.ipcpath) { | ||
if (this.debug.logs) { | ||
console.warn("[ethrpc] request to", deadNode, "failed:", err); | ||
} | ||
var deadIndex = this.nodes.hosted.indexOf(deadNode); | ||
if (deadIndex > -1) { | ||
this.nodes.hosted.splice(deadIndex, 1); | ||
if (!this.nodes.hosted.length) { | ||
if (isFunction(callback)) { | ||
return callback(errors.HOSTED_NODE_FAILURE); | ||
} | ||
throw new this.Error(errors.HOSTED_NODE_FAILURE); | ||
} | ||
} | ||
if (isFunction(callback)) callback(); | ||
} | ||
}, | ||
postSync: function (rpcUrl, command, returns) { | ||
@@ -326,4 +282,2 @@ var timeout, req = null; | ||
return callback(e); | ||
} else if (self.excision) { | ||
return self.exciseNode(err.code, rpcUrl, callback); | ||
} | ||
@@ -341,93 +295,7 @@ console.warn("[ethrpc] asynchronous RPC timed out", rpcUrl, command); | ||
// random primary node selection, weighted by (normalized) | ||
// inverse mean network latency | ||
selectPrimaryNode: function (nodes) { | ||
var select, rand, numNodes, total, weights, cdf, high, low; | ||
rand = Math.random(); | ||
numNodes = nodes.length; | ||
weights = new Array(numNodes); | ||
for (var k = 0; k < numNodes; ++k) { | ||
weights[k] = 1 / this.latency[nodes[k]]; | ||
} | ||
cdf = new Array(numNodes); | ||
total = 0; | ||
for (k = 0; k < numNodes; ++k) { | ||
total += weights[k]; | ||
cdf[k] = total; | ||
} | ||
for (k = 0; k < numNodes; ++k) { | ||
cdf[k] /= total; | ||
} | ||
high = numNodes - 1; | ||
low = 0; | ||
while (low < high) { | ||
select = Math.ceil((high + low) / 2); | ||
if (cdf[select] < rand) { | ||
low = select + 1; | ||
} else if (cdf[select] > rand) { | ||
high = select - 1; | ||
} else { | ||
return nodes[select]; | ||
} | ||
} | ||
if (low != high) { | ||
select = (cdf[low] >= rand) ? low : select; | ||
} else { | ||
select = (cdf[low] >= rand) ? low : low + 1; | ||
} | ||
console.debug("[ethrpc] primary node:", nodes[select]); | ||
return [nodes[select]].concat(nodes); | ||
}, | ||
selectNodes: function () { | ||
if (this.nodes.local) return [this.nodes.local]; | ||
if (!this.balancer || this.nodes.hosted.length === 1) { | ||
return this.nodes.hosted.slice(); | ||
} | ||
// rotate nodes until we have enough samples to weight them | ||
if (!this.samples[HOSTED_NODES[0]] || | ||
this.samples[HOSTED_NODES[0]] < this.BALANCER_SAMPLES) { | ||
this.nodes.hosted.unshift(this.nodes.hosted.pop()); | ||
return this.nodes.hosted.slice(); | ||
// if we have sufficient data, select a primary node | ||
} else { | ||
if (this.primaryNode === null) { | ||
this.primaryNode = this.selectPrimaryNode(this.nodes.hosted); | ||
} | ||
return this.primaryNode; | ||
} | ||
return this.nodes.hosted.slice(); | ||
}, | ||
// update the active node's mean network latency | ||
updateMeanLatency: function (node, latency) { | ||
if (!this.samples[node]) { | ||
this.samples[node] = 1; | ||
this.latency[node] = latency; | ||
} else { | ||
++this.samples[node]; | ||
this.latency[node] = ( | ||
(this.samples[node] - 1)*this.latency[node] + latency | ||
) / this.samples[node]; | ||
} | ||
if (this.debug.latency) { | ||
if (this.netLatency === null) { | ||
this.netSamples = 1; | ||
this.netLatency = latency; | ||
} else { | ||
++this.netSamples; | ||
this.netLatency = ( | ||
(this.netSamples - 1)*this.netLatency + latency | ||
) / this.netSamples; | ||
if (this.debug.logs) { | ||
console.log( | ||
"[" + this.netSamples.toString() + "] mean network latency:", | ||
this.netLatency | ||
); | ||
} | ||
} | ||
} | ||
}, | ||
contracts: function (network) { | ||
@@ -439,3 +307,3 @@ return contracts[network || this.version()]; | ||
broadcast: function (command, callback) { | ||
var start, nodes, numCommands, returns, result, completed, self = this; | ||
var nodes, numCommands, returns, result, completed, self = this; | ||
@@ -534,6 +402,2 @@ if (!command || (command.constructor === Object && !command.method) || | ||
nodes = this.selectNodes(); | ||
// if (command.method === "eth_sendRawTransaction") { | ||
// console.log("command:", JSON.stringify(command)); | ||
// nodes = ["https://morden-state.ether.camp/api/v1/transaction/submit"].concat(nodes); | ||
// } | ||
@@ -548,5 +412,2 @@ // asynchronous request if callback exists | ||
} | ||
if (self.balancer) { | ||
start = new Date().getTime(); | ||
} | ||
self.post(node, command, returns, function (res) { | ||
@@ -565,5 +426,2 @@ if (self.debug.logs) { | ||
completed = true; | ||
if (self.balancer) { | ||
self.updateMeanLatency(node, new Date().getTime() - start); | ||
} | ||
return nextNode({ output: res }); | ||
@@ -587,14 +445,6 @@ } | ||
} | ||
if (this.balancer) { | ||
start = new Date().getTime(); | ||
} | ||
result = this.postSync(nodes[j], command, returns); | ||
if (this.balancer) { | ||
this.updateMeanLatency(nodes[j], new Date().getTime() - start); | ||
} | ||
} catch (e) { | ||
if (this.nodes.local) { | ||
throw new this.Error(errors.LOCAL_NODE_FAILURE); | ||
} else if (this.excision) { | ||
this.exciseNode(e, nodes[j]); | ||
} | ||
@@ -663,4 +513,2 @@ } | ||
clear: function () { | ||
this.latency = {}; | ||
this.samples = {}; | ||
this.txs = {}; | ||
@@ -687,3 +535,2 @@ for (var n in this.notifications) { | ||
raw: function (command, params, f) { | ||
console.log(command, params); | ||
return this.broadcast(this.marshal(command, params, "null"), f); | ||
@@ -690,0 +537,0 @@ }, |
{ | ||
"name": "ethrpc", | ||
"version": "0.6.4", | ||
"version": "0.7.0", | ||
"description": "Ethereum JSON RPC", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
600109
11047