UNPKG

bsp-network

Version:

SDK for writing node.js applications to interact with bsp network. This package encapsulates the APIs to connect to a bsp network, submit transactions and perform queries against the ledger.

128 lines 4.71 kB
"use strict"; /** * Copyright 2020 IBM All Rights Reserved. * * SPDX-License-Identifier: Apache-2.0 */ Object.defineProperty(exports, "__esModule", { value: true }); const Logger = require("../../logger"); const GatewayUtils = require("../gatewayutils"); const asyncnotifier_1 = require("./asyncnotifier"); const filteredblockeventfactory_1 = require("./filteredblockeventfactory"); const fullblockeventfactory_1 = require("./fullblockeventfactory"); const orderedblockqueue_1 = require("./orderedblockqueue"); const privateblockeventfactory_1 = require("./privateblockeventfactory"); const Long = require("long"); const logger = Logger.getLogger('BlockEventSource'); const defaultBlockType = 'filtered'; class BlockEventSource { constructor(eventServiceManager, options = {}) { this.listeners = new Set(); this.started = false; this.eventServiceManager = eventServiceManager; this.blockQueue = this.newBlockQueue(options); this.asyncNotifier = new asyncnotifier_1.AsyncNotifier(this.blockQueue.getNextBlock.bind(this.blockQueue), this.notifyListeners.bind(this)); this.blockType = options.type || defaultBlockType; } async addBlockListener(listener) { this.listeners.add(listener); await this.start(); return listener; } removeBlockListener(listener) { this.listeners.delete(listener); } close() { var _a; this.unregisterListener(); (_a = this.eventService) === null || _a === void 0 ? void 0 : _a.close(); this.started = false; } newBlockQueue(options) { const startBlock = options.startBlock ? Long.fromValue(options.startBlock) : undefined; return new orderedblockqueue_1.OrderedBlockQueue(startBlock); } async start() { if (this.started) { return; } this.started = true; try { this.eventService = this.eventServiceManager.newDefaultEventService(); this.registerListener(); // Register before start so no events are missed await this.startEventService(); } catch (error) { logger.error('Failed to start event service', error); this.close(); } } registerListener() { const callback = this.blockEventCallback.bind(this); const options = { startBlock: this.getNextBlockNumber(), unregister: false }; this.eventListener = this.eventService.registerBlockListener(callback, options); } unregisterListener() { var _a; try { (_a = this.eventListener) === null || _a === void 0 ? void 0 : _a.unregisterEventListener(); } catch (error) { logger.warn('Failed to unregister listener', error); } } async startEventService() { const options = { blockType: this.blockType, startBlock: this.getNextBlockNumber() }; await this.eventServiceManager.startEventService(this.eventService, options); } blockEventCallback(error, event) { if (error) { this.close(); setImmediate(() => this.start()); // Must schedule after current event loop to avoid recursion in event service notification } else { this.onBlockEvent(event); } } onBlockEvent(eventInfo) { const blockEvent = this.newBlockEvent(eventInfo); this.blockQueue.addBlock(blockEvent); if (this.blockQueue.size() > 0) { this.asyncNotifier.notify(); } } newBlockEvent(eventInfo) { if (this.blockType === 'filtered') { return filteredblockeventfactory_1.newFilteredBlockEvent(eventInfo); } else if (this.blockType === 'full') { return fullblockeventfactory_1.newFullBlockEvent(eventInfo); } else if (this.blockType === 'private') { return privateblockeventfactory_1.newPrivateBlockEvent(eventInfo); } else { throw new Error('Unsupported event type: ' + this.blockType); } } async notifyListeners(event) { const promises = Array.from(this.listeners).map((listener) => listener(event)); const results = await GatewayUtils.allSettled(promises); for (const result of results) { if (result.status === 'rejected') { logger.warn('Error notifying listener', result.reason); } } } getNextBlockNumber() { return this.blockQueue.getNextBlockNumber(); } } exports.BlockEventSource = BlockEventSource; //# sourceMappingURL=blockeventsource.js.map