@launchdarkly/js-server-sdk-common
Version:
LaunchDarkly Server SDK for JavaScript - common code
106 lines • 5.04 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const js_sdk_common_1 = require("@launchdarkly/js-sdk-common");
const serialization_1 = require("../store/serialization");
// TODO: consider naming this StreamingDatasource
class StreamingProcessorFDv2 {
constructor(clientContext, streamUriPath, parameters, _payloadListener, baseHeaders, _diagnosticsManager, _errorHandler, _streamInitialReconnectDelay = 1) {
this._payloadListener = _payloadListener;
this._diagnosticsManager = _diagnosticsManager;
this._errorHandler = _errorHandler;
this._streamInitialReconnectDelay = _streamInitialReconnectDelay;
const { basicConfiguration, platform } = clientContext;
const { logger } = basicConfiguration;
const { requests } = platform;
this._headers = Object.assign({}, baseHeaders);
this._logger = logger;
this._requests = requests;
this._streamUri = (0, js_sdk_common_1.getStreamingUri)(basicConfiguration.serviceEndpoints, streamUriPath, parameters);
}
_logConnectionStarted() {
this._connectionAttemptStartTime = Date.now();
}
_logConnectionResult(success) {
if (this._connectionAttemptStartTime && this._diagnosticsManager) {
this._diagnosticsManager.recordStreamInit(this._connectionAttemptStartTime, !success, Date.now() - this._connectionAttemptStartTime);
}
this._connectionAttemptStartTime = undefined;
}
/**
* This is a wrapper around the passed errorHandler which adds additional
* diagnostics and logging logic.
*
* @param err The error to be logged and handled.
* @return boolean whether to retry the connection.
*
* @private
*/
_retryAndHandleError(err) {
var _a, _b, _c;
if (!(0, js_sdk_common_1.shouldRetry)(err)) {
this._logConnectionResult(false);
(_a = this._errorHandler) === null || _a === void 0 ? void 0 : _a.call(this, new js_sdk_common_1.LDStreamingError(js_sdk_common_1.DataSourceErrorKind.ErrorResponse, err.message, err.status));
(_b = this._logger) === null || _b === void 0 ? void 0 : _b.error((0, js_sdk_common_1.httpErrorMessage)(err, 'streaming request'));
return false;
}
(_c = this._logger) === null || _c === void 0 ? void 0 : _c.warn((0, js_sdk_common_1.httpErrorMessage)(err, 'streaming request', 'will retry'));
this._logConnectionResult(false);
this._logConnectionStarted();
return true;
}
start() {
this._logConnectionStarted();
const eventSource = this._requests.createEventSource(this._streamUri, {
headers: this._headers,
errorFilter: (error) => this._retryAndHandleError(error),
initialRetryDelayMillis: 1000 * this._streamInitialReconnectDelay,
readTimeoutMillis: 5 * 60 * 1000,
retryResetIntervalMillis: 60 * 1000,
});
this._eventSource = eventSource;
const payloadReader = new js_sdk_common_1.internal.PayloadReader(eventSource, {
flag: (flag) => {
(0, serialization_1.processFlag)(flag);
return flag;
},
segment: (segment) => {
(0, serialization_1.processSegment)(segment);
return segment;
},
}, (errorKind, message) => {
var _a;
(_a = this._errorHandler) === null || _a === void 0 ? void 0 : _a.call(this, new js_sdk_common_1.LDStreamingError(errorKind, message));
}, this._logger);
payloadReader.addPayloadListener(() => {
// TODO: discuss if it is satisfactory to switch from setting connection result on single event to getting a payload. Need
// to double check the handling in the ServerIntent:none case. That may not trigger these payload listeners.
this._logConnectionResult(true);
});
payloadReader.addPayloadListener(this._payloadListener);
eventSource.onclose = () => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.info('Closed LaunchDarkly stream connection');
};
eventSource.onerror = () => {
// The work is done by `errorFilter`.
};
eventSource.onopen = () => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.info('Opened LaunchDarkly stream connection');
};
eventSource.onretrying = (e) => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.info(`Will retry stream connection in ${e.delayMillis} milliseconds`);
};
}
stop() {
var _a;
(_a = this._eventSource) === null || _a === void 0 ? void 0 : _a.close();
this._eventSource = undefined;
}
close() {
this.stop();
}
}
exports.default = StreamingProcessorFDv2;
//# sourceMappingURL=StreamingProcessorFDv2.js.map