UNPKG

eosplayer

Version:

eosplayer is the glue layer of eosjs, which is packaged based on eosjs and provides better usability for the application layer. It can be used on browsers already installed scatter or in Dapp wallets.

199 lines 11.1 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var libs_1 = require("../types/libs"); var multiSourcePlayer_1 = require("../multiSourcePlayer"); var log_1 = require("../utils/log"); var wait_1 = require("../utils/wait"); var log = log_1.createLogger('readingPlayer'); var defaultConfig = { account: { name: 'eosio', authority: 'active', }, }; var ReadingPlayer = /** @class */ (function (_super) { __extends(ReadingPlayer, _super); function ReadingPlayer(conf) { var _this = _super.call(this, conf) || this; _this._head_block_num = 0; _this._head_retry_count = 0; _this._eosNodes = []; _this._identity = defaultConfig.account; _this._head_block_num = 0; _this._head_retry_count = 0; log.info('[EosReading] ==> Create reading nodes \nCONFIGS:', JSON.stringify(_this._nodeConfigs)); _this._eosNodes = _this._nodeConfigs.map(function (cfg) { var eos = libs_1.Eos(cfg); eos.__conf = cfg; return eos; }); return _this; } Object.defineProperty(ReadingPlayer.prototype, "eosClient", { get: function () { if (!this._eosNodes || this._eosNodes.length <= 0) { throw new Error('EosUtil : No Avaliable Nodes.'); } return this._eosNodes[0]; }, enumerable: true, configurable: true }); ReadingPlayer.prototype.getIdentity = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this._identity]; }); }); }; ReadingPlayer.prototype.checkNodes = function (checkSpanMs, retry_max, blockHeightTolerance) { if (checkSpanMs === void 0) { checkSpanMs = 15000; } if (retry_max === void 0) { retry_max = 4; } if (blockHeightTolerance === void 0) { blockHeightTolerance = 1000; } return __awaiter(this, void 0, void 0, function () { var chainInfo, randomInd, anotherChainInfo, temp, ex_1, ex_2, i, chainInfoNew, temp, ex_3; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!true) return [3 /*break*/, 20]; return [4 /*yield*/, wait_1.forMs(checkSpanMs)]; case 1: _a.sent(); console.log('[EosReading] ==> Start Checking Nodes ', this.eosClient.__conf.httpEndpoint, 'AT', Date.now()); _a.label = 2; case 2: if (!true) return [3 /*break*/, 19]; _a.label = 3; case 3: _a.trys.push([3, 9, , 17]); return [4 /*yield*/, this.eosClient.getInfo({})]; case 4: chainInfo = _a.sent(); this._head_retry_count = 0; if (chainInfo.head_block_num > this._head_block_num) { this._head_block_num = chainInfo.head_block_num; console.log('[EosReading] ==> | Info : new head block num', this._head_block_num, '| Node: ', this.eosClient.__conf.httpEndpoint); } randomInd = Math.floor(Math.random() * this._eosNodes.length); if (randomInd === 0) return [3 /*break*/, 19]; // lucky!! 为 0 的概率越高, 说明配置中的节点越少, 此时降低因为快高切换节点的概率是没毛病的 _a.label = 5; case 5: _a.trys.push([5, 7, , 8]); console.log('[EosReading] ==> | Info : try pick another node by block height | Node: ', this._eosNodes[randomInd].__conf.httpEndpoint); return [4 /*yield*/, this._eosNodes[randomInd].getInfo({})]; case 6: anotherChainInfo = _a.sent(); if (anotherChainInfo.head_block_num - this._head_block_num > blockHeightTolerance) { temp = this._eosNodes[0]; this._eosNodes[0] = this._eosNodes[randomInd]; this._eosNodes[randomInd] = temp; console.log('[EosReading] ==> | Info : new node selected (by head block) | OLD: ', temp.__conf.httpEndpoint, '| NEW:', this.eosClient.__conf.httpEndpoint); // 如果节点发生切换, 就不应该 break 了, 应该走 2000ms 的重试 } else { console.log('[EosReading] ==> | Info : no needs to switch node for block height | ', anotherChainInfo.head_block_num, '-', this._head_block_num, '<', blockHeightTolerance); } return [3 /*break*/, 8]; case 7: ex_1 = _a.sent(); return [3 /*break*/, 19]; // 此时保留原节点并退出 case 8: return [3 /*break*/, 17]; case 9: ex_2 = _a.sent(); if (!(this._head_retry_count < retry_max)) return [3 /*break*/, 10]; console.log('[EosReading] ==> | Error : Current node error | RETRY :', this._head_retry_count, '| NODE: ', this._eosNodes[0].__conf.httpEndpoint); this._head_retry_count += 1; // and retry will start after 2000ms return [3 /*break*/, 16]; case 10: console.log('[EosReading] ==> | Error : Current node error | RETRY : Failed | Node:', this._eosNodes[0].__conf.httpEndpoint); i = 1; _a.label = 11; case 11: if (!(i < this._eosNodes.length)) return [3 /*break*/, 16]; _a.label = 12; case 12: _a.trys.push([12, 14, , 15]); return [4 /*yield*/, this._eosNodes[i].getInfo({})]; case 13: chainInfoNew = _a.sent(); if (chainInfoNew.head_block_num >= this._head_block_num) { temp = this._eosNodes[0]; this._eosNodes[0] = this._eosNodes[i]; this._eosNodes[i] = temp; console.log('[EosReading] ==> Info : new node selected | OLD: ', temp.__conf.httpEndpoint, '| NEW:', this.eosClient.__conf.httpEndpoint); return [3 /*break*/, 16]; // and will be re-test after 2000ms } else { console.log('[EosReading] ==> Info : test node passed | Node: ', this._eosNodes[i].__conf.httpEndpoint, 'Test: ', chainInfoNew.head_block_num, '<', this._head_block_num); } return [3 /*break*/, 15]; case 14: ex_3 = _a.sent(); console.log('[EosReading] ==> Warning : test node error | Node: ', this._eosNodes[i].__conf.httpEndpoint); return [3 /*break*/, 15]; case 15: i++; return [3 /*break*/, 11]; case 16: return [3 /*break*/, 17]; case 17: return [4 /*yield*/, wait_1.forMs(2000)]; case 18: _a.sent(); return [3 /*break*/, 2]; case 19: return [3 /*break*/, 0]; case 20: return [2 /*return*/]; } }); }); }; return ReadingPlayer; }(multiSourcePlayer_1.MultiSourcePlayer)); exports.ReadingPlayer = ReadingPlayer; //# sourceMappingURL=readingPlayer.js.map