@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.
170 lines (169 loc) • 9.15 kB
JavaScript
import { __awaiter, __rest } from "tslib";
import { PromiseWrapper } from "../promise-wrapper";
import { createSequence } from "../seq";
import { callSafe, clone } from "../utils";
export 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 PromiseWrapper(),
messageSequence: 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 PromiseWrapper(),
messageSequence: 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 = (() => __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);
callSafe(onClosed);
}
}
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 __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 {
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}".`);
}
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 __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);
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;
}
callSafe(callback);
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);
callSafe(callback, error);
}
subscribeMdfEvents(id, onEvent, messageProcessor) {
return this.mdfBridge.onEvent(id, (event) => {
if (event == null) {
return;
}
const reqInfo = this.activeRequests.get(id);
if (!reqInfo) {
return;
}
const clonedEvent = clone(event);
onEvent(clonedEvent);
const evType = event.eventType;
const eventMessages = event.eventMessages;
eventMessages.forEach((_a) => {
var { correlationIds } = _a, message = __rest(_a, ["correlationIds"]);
const eventType = evType;
const action = () => __awaiter(this, void 0, void 0, function* () {
yield messageProcessor({ correlationIds, message, eventType });
});
reqInfo.messageSequence.enqueue(action);
});
});
}
}