UNPKG

@glue42/bbg-market-data

Version:

A high-level API that wraps existing Glue42 Bloomberg Bridge Market Data interop methods. The API is based on the jBloomberg open source wrapper.

181 lines 9.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SessionInstance = void 0; const tslib_1 = require("tslib"); const promise_wrapper_1 = require("../promise-wrapper"); const seq_1 = require("../seq"); const utils_1 = require("../utils"); class SessionInstance { constructor(mdfBridge, sessionConfig, logger) { this.mdfBridge = mdfBridge; this.sessionConfig = sessionConfig; this.logger = logger; this.activeRequests = new Map(); } openRequest(requestId, requestConfig, operationArgs, otherSettings, onEvent, messageProcessor, onSuccess, onFail) { var _a; const unsubscribeEvents = this.subscribeMdfEvents(requestId, onEvent, messageProcessor); const reqInfo = { unsubscribeEvents, mdfOpenPW: new promise_wrapper_1.PromiseWrapper(), messageSequence: seq_1.createSequence(), }; this.activeRequests.set(requestId, reqInfo); const mdfArgs = { requestCorrelationId: requestId, operationArgs, settings: Object.assign({ sessionName: this.sessionConfig.name, sessionLifetime: this.sessionConfig.lifetime, sessionOptions: this.sessionConfig.options, sessionIdentityOptions: this.sessionConfig.identityOptions }, otherSettings), operation: requestConfig.operation, service: requestConfig.service, }; (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`Session "${this.sessionConfig.name}/${this.sessionConfig.lifetime}" is attempting to open a non-subscription request with an id "${requestId}".`); this.mdfBridge .createRequest(mdfArgs) .then(() => this.handleOpenSuccess(requestId, onSuccess)) .catch((error) => this.handleOpenFail(requestId, error, onFail)); } openSubscriptionRequest(requestId, config, subscriptions, otherSettings, onEvent, messageProcessor, onSuccess, onFail) { var _a; const unsubscribeEvents = this.subscribeMdfEvents(requestId, onEvent, messageProcessor); const reqInfo = { unsubscribeEvents, mdfOpenPW: new promise_wrapper_1.PromiseWrapper(), messageSequence: seq_1.createSequence(), }; this.activeRequests.set(requestId, reqInfo); const mdfArgs = { requestCorrelationId: requestId, subscriptions, settings: Object.assign({ sessionName: this.sessionConfig.name, sessionLifetime: this.sessionConfig.lifetime, sessionOptions: this.sessionConfig.options, sessionIdentityOptions: this.sessionConfig.identityOptions }, otherSettings), service: config.service, }; (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`Session "${this.sessionConfig.name}/${this.sessionConfig.lifetime}" is attempting to open a subscription request with an id "${requestId}".`); this.mdfBridge .createSubscriptionRequest(mdfArgs) .then(() => this.handleOpenSuccess(requestId, onSuccess)) .catch((error) => this.handleOpenFail(requestId, error, onFail)); } onBloombergEvent(requestId, callback) { return this.mdfBridge.onEvent(requestId, callback); } closeRequest(requestId, onClosed) { var _a, _b; (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`Session "${this.sessionConfig.name}" is attempting to close a request with an id "${requestId}".`); const reqInfo = this.activeRequests.get(requestId); if (!reqInfo) { (_b = this.logger) === null || _b === void 0 ? void 0 : _b.warn(`Session "${this.sessionConfig.name}" cannot close a request with an id "${requestId}", it does not exists in state.`); return Promise.resolve(); } if (reqInfo.closePromise instanceof Promise) { return reqInfo.closePromise; } reqInfo.closePromise = (() => tslib_1.__awaiter(this, void 0, void 0, function* () { var _c; try { const openSuccess = yield ((_c = reqInfo.mdfOpenPW) === null || _c === void 0 ? void 0 : _c.promise); if (openSuccess) { const reason = `User closed request with an id "${requestId}".`; this.dispose(requestId, reason, true); utils_1.callSafe(onClosed); } // eslint-disable-next-line no-empty } catch (_d) { } }))(); return reqInfo.closePromise; } disposeRequest(requestId, reason) { this.dispose(requestId, reason, true); } dispose(requestId, reason, shouldCloseRequest = false) { var _a, _b, _c, _d, _e; return tslib_1.__awaiter(this, void 0, void 0, function* () { const reqInfo = this.activeRequests.get(requestId); if (!reqInfo) { (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`Session "${this.sessionConfig.name}" cannot dispose request with an id "${requestId}", it does not exists in state.`); return; } (_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Session "${this.sessionConfig.name}" is disposing request with an id "${requestId}", reason: ${reason}`); this.activeRequests.delete(requestId); reqInfo.unsubscribeEvents(); reqInfo.messageSequence.clear(); (_c = this.logger) === null || _c === void 0 ? void 0 : _c.info(`Session "${this.sessionConfig.name}" cleaned up request with an id "${requestId}".`); if (shouldCloseRequest) { try { // Clean up resources on the bridge. yield this.mdfBridge.closeRequest(requestId, reason); (_d = this.logger) === null || _d === void 0 ? void 0 : _d.info(`Session "${this.sessionConfig.name}" - bridge closed successfully request with an id "${requestId}".`); // eslint-disable-next-line no-empty } catch (error) { (_e = this.logger) === null || _e === void 0 ? void 0 : _e.warn(`Session "${this.sessionConfig.name}" - bridge failed to close request with an id "${requestId}" - ${JSON.stringify(error)}`); } } }); } handleOpenSuccess(requestId, callback) { var _a, _b; return tslib_1.__awaiter(this, void 0, void 0, function* () { const reqInfo = this.activeRequests.get(requestId); if (!reqInfo) { return; } (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`Session "${this.sessionConfig.name}" - bridge opened successfully a request with an id "${requestId}".`); reqInfo.mdfOpenPW.resolve(true); // Close invoked before the "open" task has completed. if (reqInfo.closePromise instanceof Promise) { (_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Session "${this.sessionConfig.name}" - request with an id "${requestId}" got "close" command before the "open" task completes.`); return reqInfo.closePromise; } utils_1.callSafe(callback); // Start processing messages. setTimeout(() => { var _a, _b; const reqInfo = this.activeRequests.get(requestId); if (reqInfo) { (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`Session "${this.sessionConfig.name}" - starting message processor sequence for request with an id "${requestId}"`); (_b = reqInfo === null || reqInfo === void 0 ? void 0 : reqInfo.messageSequence) === null || _b === void 0 ? void 0 : _b.run(); } }, 0); }); } handleOpenFail(id, error, callback) { var _a; const reqInfo = this.activeRequests.get(id); if (!reqInfo) { return; } (_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`Session "${this.sessionConfig.name}" - failed to open the request with an id "${id}". Will attempt at disposing the request.`); const reason = `Opening request failed with ${error.message}`; this.dispose(id, reason, false); reqInfo.mdfOpenPW.resolve(false); utils_1.callSafe(callback, error); } subscribeMdfEvents(id, onEvent, messageProcessor) { return this.mdfBridge.onEvent(id, (event) => { if (event == null) { // The bridge sends null when the request is completes. return; } const reqInfo = this.activeRequests.get(id); if (!reqInfo) { // TODO: Maybe unsubscribe? return; } const clonedEvent = utils_1.clone(event); onEvent(clonedEvent); const evType = event.eventType; const eventMessages = event.eventMessages; eventMessages.forEach((_a) => { var { correlationIds } = _a, message = tslib_1.__rest(_a, ["correlationIds"]); const eventType = evType; const action = () => tslib_1.__awaiter(this, void 0, void 0, function* () { yield messageProcessor({ correlationIds, message, eventType }); }); reqInfo.messageSequence.enqueue(action); }); }); } } exports.SessionInstance = SessionInstance; //# sourceMappingURL=session-instance.js.map