From 10d605e1f12b7c77852dda3141da1a918cc81f24 Mon Sep 17 00:00:00 2001 From: jsalyers <jsalyers@syncad.com> Date: Thu, 9 Apr 2020 18:30:31 -0400 Subject: [PATCH] [JES] Add automatic failover capability --- config.json | 8 ++--- package.json | 6 ++-- src/api/index.js | 66 +++++++++++++++++++------------------- src/api/transports/http.js | 1 - src/config.js | 24 -------------- 5 files changed, 40 insertions(+), 65 deletions(-) delete mode 100644 src/config.js diff --git a/config.json b/config.json index 3a5eb45..e4da8c5 100644 --- a/config.json +++ b/config.json @@ -1,10 +1,10 @@ { "transport": "http", "websocket": "wss://api.hive.blog:8090", - "uri": "https://anyx.io", - "url": "https://anyx.io", - "dev_uri": "https://api.steemitdev.com", - "stage_uri": "https://api.steemitstage.com", + "uri": "https://api.hive.blog", + "url": "https://api.hive.blog", + "dev_uri": "", + "stage_uri": "", "address_prefix": "STM", "chain_id": "0000000000000000000000000000000000000000000000000000000000000000", "alternative_api_endpoints": ["https://api.hive.blog", "https://anyx.io"], diff --git a/package.json b/package.json index da8a724..95b7bed 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "hive-js-dev", - "version": "0.0.9", - "description": "Steem.js the JavaScript API for Steem blockchain", + "name": "@hiveio/hive-js", + "version": "0.0.2", + "description": "Hive.js the JavaScript API for Hive blockchain", "main": "lib/index.js", "scripts": { "test": "eslint --quiet src test; mocha -t 40000 --require babel-polyfill --require babel-register", diff --git a/src/api/index.js b/src/api/index.js index 26d7dd7..05d7e4f 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -27,8 +27,10 @@ class Steem extends EventEmitter { this._setLogger(options); this.options = options; this.seqNo = 0; // used for rpc calls - this.errorCount = 0; - this.apiIndex = 0; + this.error_count = 0; + this.api_index = 0; + this.error_threshold = 3; + this.alternative_api_endpoints = ['https://api.hive.blog', 'https://anyx.io']; methods.forEach(method => { const methodName = method.method_name || camelCase(method.method); const methodParams = method.params || []; @@ -184,6 +186,12 @@ class Steem extends EventEmitter { setOptions(options) { Object.assign(this.options, options); + + if (options.hasOwnProperty('failover_threshold')) + this.failover_threshold = options.failover_threshold; + if (options.hasOwnProperty('alternative_api_endpoints')) + this.alternative_api_endpoints = options.alternative_api_endpoints; + this._setLogger(options); this._setTransport(options); this.transport.setOptions(options); @@ -191,35 +199,22 @@ class Steem extends EventEmitter { { config.set( 'address_prefix', options.useTestNet ? 'TST' : 'STM' ) } - if (options.hasOwnProperty('failover_threshold')) - { - config.set('failover_threshold', options.failover_threshold); - } - if (options.hasOwnProperty('alternative_api_endpoints')) - { - config.set('alternative_api_endpoints', options.alternative_api_endpoints); - } + if (options.hasOwnProperty('url')) { - if (this.options.alternative_api_endpoints === undefined || this.options.alternative_api_endpoints === null) - { - console.log("no alternative api endpoints found, can't update the index"); - } - let index = 0; - for (var i = 0; i < this.options.alternative_api_endpoints.length; i++) + let new_index = 0; + for (var i = 0; i < this.alternative_api_endpoints.length; i++) { - if (this.options.url === this.options.alternative_api_endpoints[i]) + let temp_endpoint = this.alternative_api_endpoints[i]; + if (temp_endpoint === options.url) { - index = i; + new_index = i; break; } } - this.apiIndex = index; - console.log("updated apiIndex to be ", this.apiIndex); + this.api_index = new_index; + let new_endpoint = this.alternative_api_endpoints[this.api_index]; } - - console.log("done setting options. new options are: ", this.options); - console.log("does failover_threshold still exist? ", this.options.failover_threshold === 'undefined' ? "no" : "yes"); } setWebSocket(url) { @@ -382,26 +377,31 @@ class Steem extends EventEmitter { notifyError(err, ignore=false) { - this.errorCount++; if (ignore) { return; } - if (this.options.failover_threshold === 'undefined') + if (this.failover_threshold === undefined || this.alternative_api_endpoints === undefined) + { + return; + } + if (err && err.toString().includes("overseer")) { - console.log("no failover options are listed, can't failover"); + //overseer was a steem thing, it doesn't exist in hive so don't count this error towards failover return; } - if (this.errorCount >= this.options.failover_threshold) + this.error_count++; + if (this.error_count >= this.failover_threshold) { - console.log("failing over"); - this.errorCount = 0; - this.apiIndex++; - if (this.apiIndex >= this.options.alternative_api_endpoints.length) + let current_url = this.options.url; + this.error_count = 0; + this.api_index++; + if (this.api_index >= this.alternative_api_endpoints.length) { - this.apiIndex = 0; + this.api_index = 0; } - let nextEndpoint = this.options.alternative_api_endpoints[this.apiIndex]; + let nextEndpoint = this.alternative_api_endpoints[this.api_index]; + console.log("failing over. old endpoint was: ", current_url, " new one is: ", nextEndpoint); this.setOptions({url: nextEndpoint}); } } diff --git a/src/api/transports/http.js b/src/api/transports/http.js index e030d80..9ce59e7 100644 --- a/src/api/transports/http.js +++ b/src/api/transports/http.js @@ -45,7 +45,6 @@ export function jsonRpc(uri, {method, id, params, fetchMethod=fetch}) { throw new Error(`Invalid response id: ${ rpcRes.id }`); } if (rpcRes.error) { - console.log("rcpRes error means rpc threw an error. uri, payload are: ", uri, payload); throw new RPCError(rpcRes.error); } return rpcRes.result diff --git a/src/config.js b/src/config.js deleted file mode 100644 index e4febd8..0000000 --- a/src/config.js +++ /dev/null @@ -1,24 +0,0 @@ -import each from 'lodash/each'; -const defaultConfig = require('../config.json'); - -class Config { - constructor(c) { - each(c, (value, key) => { - this[key] = value; - }); - } - - get(k) { - return this[k]; - } - - set(k, v) { - this[k] = v; - } -} - -module.exports = new Config(defaultConfig); -if(typeof module.exports.Config !== 'undefined') { - throw new Error("default config.json file may not contain a property 'Config'"); -} -module.exports.Config = Config; -- GitLab