@rabbitio/ui-kit 1.0.0-beta.41 → 1.0.0-beta.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1455 -1357
- package/dist/index.cjs.map +1 -1
- package/dist/index.modern.js +684 -620
- package/dist/index.modern.js.map +1 -1
- package/dist/index.module.js +1455 -1358
- package/dist/index.module.js.map +1 -1
- package/dist/index.umd.js +1457 -1359
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/common/external-apis/ipAddressProviders.js +138 -0
- package/src/index.js +1 -0
- package/src/robustExteranlApiCallerService/robustExternalAPICallerService.js +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
var React = require('react');
|
|
2
2
|
var bignumber_js = require('bignumber.js');
|
|
3
3
|
var axios = require('axios');
|
|
4
|
-
var uuid = require('uuid');
|
|
5
|
-
var Hashes = require('jshashes');
|
|
6
4
|
var EventBusInstance = require('eventbusjs');
|
|
5
|
+
var Hashes = require('jshashes');
|
|
6
|
+
var uuid = require('uuid');
|
|
7
7
|
|
|
8
8
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
9
|
|
|
10
10
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
11
11
|
var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
|
|
12
|
-
var Hashes__default = /*#__PURE__*/_interopDefaultLegacy(Hashes);
|
|
13
12
|
var EventBusInstance__default = /*#__PURE__*/_interopDefaultLegacy(EventBusInstance);
|
|
13
|
+
var Hashes__default = /*#__PURE__*/_interopDefaultLegacy(Hashes);
|
|
14
14
|
|
|
15
15
|
function createCommonjsModule(fn) {
|
|
16
16
|
var module = { exports: {} };
|
|
@@ -1630,7 +1630,7 @@ var Logger = /*#__PURE__*/function () {
|
|
|
1630
1630
|
return Logger;
|
|
1631
1631
|
}();
|
|
1632
1632
|
|
|
1633
|
-
function _catch$
|
|
1633
|
+
function _catch$9(body, recover) {
|
|
1634
1634
|
try {
|
|
1635
1635
|
var result = body();
|
|
1636
1636
|
} catch (e) {
|
|
@@ -1646,7 +1646,7 @@ function useCallHandlingErrors() {
|
|
|
1646
1646
|
setState = _useState[1];
|
|
1647
1647
|
return React.useCallback(function (functionToBeCalled, event) {
|
|
1648
1648
|
try {
|
|
1649
|
-
var _temp = _catch$
|
|
1649
|
+
var _temp = _catch$9(function () {
|
|
1650
1650
|
return Promise.resolve(functionToBeCalled(event)).then(function () {});
|
|
1651
1651
|
}, function (error) {
|
|
1652
1652
|
Logger.logError(error, (functionToBeCalled == null ? void 0 : functionToBeCalled.name) || "errorBoundaryTrigger", "Caught by ErrorBoundary");
|
|
@@ -2684,7 +2684,7 @@ var Cache = /*#__PURE__*/function () {
|
|
|
2684
2684
|
return Cache;
|
|
2685
2685
|
}();
|
|
2686
2686
|
|
|
2687
|
-
function _catch$
|
|
2687
|
+
function _catch$8(body, recover) {
|
|
2688
2688
|
try {
|
|
2689
2689
|
var result = body();
|
|
2690
2690
|
} catch (e) {
|
|
@@ -2702,7 +2702,7 @@ function postponeExecution(execution, timeoutMS) {
|
|
|
2702
2702
|
return new Promise(function (resolve, reject) {
|
|
2703
2703
|
setTimeout(function () {
|
|
2704
2704
|
try {
|
|
2705
|
-
var _temp = _catch$
|
|
2705
|
+
var _temp = _catch$8(function () {
|
|
2706
2706
|
return Promise.resolve(execution()).then(function (_execution) {
|
|
2707
2707
|
resolve(_execution);
|
|
2708
2708
|
});
|
|
@@ -2786,7 +2786,7 @@ var AxiosAdapter = /*#__PURE__*/function () {
|
|
|
2786
2786
|
return AxiosAdapter;
|
|
2787
2787
|
}();
|
|
2788
2788
|
|
|
2789
|
-
function _catch$
|
|
2789
|
+
function _catch$7(body, recover) {
|
|
2790
2790
|
try {
|
|
2791
2791
|
var result = body();
|
|
2792
2792
|
} catch (e) {
|
|
@@ -2802,7 +2802,7 @@ var EmailsApi = /*#__PURE__*/function () {
|
|
|
2802
2802
|
EmailsApi.sendEmail = function sendEmail(subject, body) {
|
|
2803
2803
|
try {
|
|
2804
2804
|
var _this = this;
|
|
2805
|
-
var _temp = _catch$
|
|
2805
|
+
var _temp = _catch$7(function () {
|
|
2806
2806
|
var url = window.location.protocol + "//" + window.location.host + "/api/v1/" + _this.serverEndpointEntity;
|
|
2807
2807
|
return Promise.resolve(axios__default["default"].post(url, {
|
|
2808
2808
|
subject: subject,
|
|
@@ -2820,772 +2820,317 @@ var EmailsApi = /*#__PURE__*/function () {
|
|
|
2820
2820
|
}();
|
|
2821
2821
|
EmailsApi.serverEndpointEntity = "emails";
|
|
2822
2822
|
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
*/
|
|
2849
|
-
|
|
2850
|
-
function _settle$2(pact, state, value) {
|
|
2851
|
-
if (!pact.s) {
|
|
2852
|
-
if (value instanceof _Pact$2) {
|
|
2853
|
-
if (value.s) {
|
|
2854
|
-
if (state & 1) {
|
|
2855
|
-
state = value.s;
|
|
2856
|
-
}
|
|
2857
|
-
value = value.v;
|
|
2858
|
-
} else {
|
|
2859
|
-
value.o = _settle$2.bind(null, pact, state);
|
|
2860
|
-
return;
|
|
2861
|
-
}
|
|
2862
|
-
}
|
|
2863
|
-
if (value && value.then) {
|
|
2864
|
-
value.then(_settle$2.bind(null, pact, state), _settle$2.bind(null, pact, 2));
|
|
2865
|
-
return;
|
|
2823
|
+
var ExternalApiProvider = /*#__PURE__*/function () {
|
|
2824
|
+
/**
|
|
2825
|
+
* Creates an instance of external api provider.
|
|
2826
|
+
*
|
|
2827
|
+
* If you need sub-request then use 'subRequestIndex' to check current request index in functions below.
|
|
2828
|
+
* Also use array for 'httpMethod'.
|
|
2829
|
+
*
|
|
2830
|
+
* If the endpoint of dedicated provider has pagination then you should customize the behavior using
|
|
2831
|
+
* "changeQueryParametersForPageNumber", "checkWhetherResponseIsForLastPage".
|
|
2832
|
+
*
|
|
2833
|
+
* We perform RPS counting all over the App to avoid blocking our clients due to abuses of the providers.
|
|
2834
|
+
*
|
|
2835
|
+
* @param endpoint {string} URL to the provider's endpoint. Note: you can customize it using composeQueryString
|
|
2836
|
+
* @param [httpMethod] {string|string[]} one of "get", "post", "put", "patch", "delete" or an array of these values
|
|
2837
|
+
* for request having sub-requests
|
|
2838
|
+
* @param [timeout] {number} number of milliseconds to wait for the response
|
|
2839
|
+
* @param [apiGroup] {ApiGroup} singleton object containing parameters of API group. Helpful when you use the same
|
|
2840
|
+
* api for different providers to avoid hardcoding RPS inside each provider what can cause mistakes
|
|
2841
|
+
* @param [specificHeaders] {Object} contains specific keys (headers) and values (their content) if needed for this provider
|
|
2842
|
+
* @param [maxPageLength] {number} optional number of items per page if the request supports pagination
|
|
2843
|
+
*/
|
|
2844
|
+
function ExternalApiProvider(endpoint, httpMethod, timeout, apiGroup, specificHeaders, maxPageLength) {
|
|
2845
|
+
var _maxPageLength, _specificHeaders;
|
|
2846
|
+
if (specificHeaders === void 0) {
|
|
2847
|
+
specificHeaders = {};
|
|
2866
2848
|
}
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
const observer = pact.o;
|
|
2870
|
-
if (observer) {
|
|
2871
|
-
observer(pact);
|
|
2849
|
+
if (maxPageLength === void 0) {
|
|
2850
|
+
maxPageLength = Number.MAX_SAFE_INTEGER;
|
|
2872
2851
|
}
|
|
2852
|
+
this.endpoint = endpoint;
|
|
2853
|
+
this.httpMethod = httpMethod != null ? httpMethod : "get";
|
|
2854
|
+
// TODO: [refactoring, critical] We have two timeouts for robust data retrieval - here and inside the service method call, need to remain the only
|
|
2855
|
+
this.timeout = timeout != null ? timeout : 10000;
|
|
2856
|
+
// TODO: [refactoring, critical] We need single place for all RPSes as we use them as hardcoded constants now inside different services
|
|
2857
|
+
this.apiGroup = apiGroup;
|
|
2858
|
+
this.maxPageLength = (_maxPageLength = maxPageLength) != null ? _maxPageLength : Number.MAX_SAFE_INTEGER;
|
|
2859
|
+
this.niceFactor = 1;
|
|
2860
|
+
this.specificHeaders = (_specificHeaders = specificHeaders) != null ? _specificHeaders : {};
|
|
2873
2861
|
}
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
* (E.g. getting today coins-fiat rates from some API).
|
|
2879
|
-
*/
|
|
2880
|
-
var _Pact$2 = /*#__PURE__*/function () {
|
|
2881
|
-
function _Pact() {}
|
|
2882
|
-
_Pact.prototype.then = function (onFulfilled, onRejected) {
|
|
2883
|
-
var result = new _Pact();
|
|
2884
|
-
var state = this.s;
|
|
2885
|
-
if (state) {
|
|
2886
|
-
var callback = state & 1 ? onFulfilled : onRejected;
|
|
2887
|
-
if (callback) {
|
|
2888
|
-
try {
|
|
2889
|
-
_settle$2(result, 1, callback(this.v));
|
|
2890
|
-
} catch (e) {
|
|
2891
|
-
_settle$2(result, 2, e);
|
|
2892
|
-
}
|
|
2893
|
-
return result;
|
|
2894
|
-
} else {
|
|
2895
|
-
return this;
|
|
2896
|
-
}
|
|
2897
|
-
}
|
|
2898
|
-
this.o = function (_this) {
|
|
2899
|
-
try {
|
|
2900
|
-
var value = _this.v;
|
|
2901
|
-
if (_this.s & 1) {
|
|
2902
|
-
_settle$2(result, 1, onFulfilled ? onFulfilled(value) : value);
|
|
2903
|
-
} else if (onRejected) {
|
|
2904
|
-
_settle$2(result, 1, onRejected(value));
|
|
2905
|
-
} else {
|
|
2906
|
-
_settle$2(result, 2, value);
|
|
2907
|
-
}
|
|
2908
|
-
} catch (e) {
|
|
2909
|
-
_settle$2(result, 2, e);
|
|
2910
|
-
}
|
|
2911
|
-
};
|
|
2912
|
-
return result;
|
|
2862
|
+
var _proto = ExternalApiProvider.prototype;
|
|
2863
|
+
_proto.getRps = function getRps() {
|
|
2864
|
+
var _this$apiGroup$rps;
|
|
2865
|
+
return (_this$apiGroup$rps = this.apiGroup.rps) != null ? _this$apiGroup$rps : 2;
|
|
2913
2866
|
};
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
var shouldContinue = test();
|
|
2923
|
-
if (_isSettledPact$2(shouldContinue)) {
|
|
2924
|
-
shouldContinue = shouldContinue.v;
|
|
2925
|
-
}
|
|
2926
|
-
if (!shouldContinue) {
|
|
2927
|
-
return result;
|
|
2928
|
-
}
|
|
2929
|
-
if (shouldContinue.then) {
|
|
2930
|
-
stage = 0;
|
|
2931
|
-
break;
|
|
2932
|
-
}
|
|
2933
|
-
var result = body();
|
|
2934
|
-
if (result && result.then) {
|
|
2935
|
-
if (_isSettledPact$2(result)) {
|
|
2936
|
-
result = result.s;
|
|
2937
|
-
} else {
|
|
2938
|
-
stage = 1;
|
|
2939
|
-
break;
|
|
2940
|
-
}
|
|
2941
|
-
}
|
|
2942
|
-
if (update) {
|
|
2943
|
-
var updateValue = update();
|
|
2944
|
-
if (updateValue && updateValue.then && !_isSettledPact$2(updateValue)) {
|
|
2945
|
-
stage = 2;
|
|
2946
|
-
break;
|
|
2947
|
-
}
|
|
2948
|
-
}
|
|
2949
|
-
}
|
|
2950
|
-
var pact = new _Pact$2();
|
|
2951
|
-
var reject = _settle$2.bind(null, pact, 2);
|
|
2952
|
-
(stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject);
|
|
2953
|
-
return pact;
|
|
2954
|
-
function _resumeAfterBody(value) {
|
|
2955
|
-
result = value;
|
|
2956
|
-
do {
|
|
2957
|
-
if (update) {
|
|
2958
|
-
updateValue = update();
|
|
2959
|
-
if (updateValue && updateValue.then && !_isSettledPact$2(updateValue)) {
|
|
2960
|
-
updateValue.then(_resumeAfterUpdate).then(void 0, reject);
|
|
2961
|
-
return;
|
|
2962
|
-
}
|
|
2963
|
-
}
|
|
2964
|
-
shouldContinue = test();
|
|
2965
|
-
if (!shouldContinue || _isSettledPact$2(shouldContinue) && !shouldContinue.v) {
|
|
2966
|
-
_settle$2(pact, 1, result);
|
|
2967
|
-
return;
|
|
2968
|
-
}
|
|
2969
|
-
if (shouldContinue.then) {
|
|
2970
|
-
shouldContinue.then(_resumeAfterTest).then(void 0, reject);
|
|
2971
|
-
return;
|
|
2972
|
-
}
|
|
2973
|
-
result = body();
|
|
2974
|
-
if (_isSettledPact$2(result)) {
|
|
2975
|
-
result = result.v;
|
|
2976
|
-
}
|
|
2977
|
-
} while (!result || !result.then);
|
|
2978
|
-
result.then(_resumeAfterBody).then(void 0, reject);
|
|
2979
|
-
}
|
|
2980
|
-
function _resumeAfterTest(shouldContinue) {
|
|
2981
|
-
if (shouldContinue) {
|
|
2982
|
-
result = body();
|
|
2983
|
-
if (result && result.then) {
|
|
2984
|
-
result.then(_resumeAfterBody).then(void 0, reject);
|
|
2985
|
-
} else {
|
|
2986
|
-
_resumeAfterBody(result);
|
|
2987
|
-
}
|
|
2988
|
-
} else {
|
|
2989
|
-
_settle$2(pact, 1, result);
|
|
2990
|
-
}
|
|
2991
|
-
}
|
|
2992
|
-
function _resumeAfterUpdate() {
|
|
2993
|
-
if (shouldContinue = test()) {
|
|
2994
|
-
if (shouldContinue.then) {
|
|
2995
|
-
shouldContinue.then(_resumeAfterTest).then(void 0, reject);
|
|
2996
|
-
} else {
|
|
2997
|
-
_resumeAfterTest(shouldContinue);
|
|
2998
|
-
}
|
|
2999
|
-
} else {
|
|
3000
|
-
_settle$2(pact, 1, result);
|
|
3001
|
-
}
|
|
3002
|
-
}
|
|
3003
|
-
}
|
|
3004
|
-
function _catch$5(body, recover) {
|
|
3005
|
-
try {
|
|
3006
|
-
var result = body();
|
|
3007
|
-
} catch (e) {
|
|
3008
|
-
return recover(e);
|
|
2867
|
+
_proto.isRpsExceeded = function isRpsExceeded() {
|
|
2868
|
+
return this.apiGroup.isRpsExceeded();
|
|
2869
|
+
};
|
|
2870
|
+
_proto.actualizeLastCalledTimestamp = function actualizeLastCalledTimestamp() {
|
|
2871
|
+
this.apiGroup.actualizeLastCalledTimestamp();
|
|
2872
|
+
};
|
|
2873
|
+
_proto.getApiGroupId = function getApiGroupId() {
|
|
2874
|
+
return this.apiGroup.id;
|
|
3009
2875
|
}
|
|
3010
|
-
|
|
3011
|
-
|
|
2876
|
+
|
|
2877
|
+
/**
|
|
2878
|
+
* Some endpoint can require several sub requests. Example is one request to get confirmed transactions
|
|
2879
|
+
* and another request for unconfirmed transactions. You should override this method to return true for such requests.
|
|
2880
|
+
*
|
|
2881
|
+
* @return {boolean} true if this provider requires several requests to retrieve the data
|
|
2882
|
+
*/;
|
|
2883
|
+
_proto.doesRequireSubRequests = function doesRequireSubRequests() {
|
|
2884
|
+
return false;
|
|
3012
2885
|
}
|
|
3013
|
-
|
|
3014
|
-
}
|
|
3015
|
-
var CacheAndConcurrentRequestsResolver = /*#__PURE__*/function () {
|
|
2886
|
+
|
|
3016
2887
|
/**
|
|
3017
|
-
*
|
|
3018
|
-
*
|
|
3019
|
-
* @
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
* @param [timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished=1000] {number}
|
|
3024
|
-
* timeout ms for polling for a result. if you change maxCallAttemptsToWaitForAlreadyRunningRequest
|
|
3025
|
-
* then this parameter maybe also require the custom value.
|
|
3026
|
-
* @param [removeExpiredCacheAutomatically=true] {boolean}
|
|
3027
|
-
*/
|
|
3028
|
-
function CacheAndConcurrentRequestsResolver(bio, cache, cacheTtl, removeExpiredCacheAutomatically, maxCallAttemptsToWaitForAlreadyRunningRequest, timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished) {
|
|
3029
|
-
if (removeExpiredCacheAutomatically === void 0) {
|
|
3030
|
-
removeExpiredCacheAutomatically = true;
|
|
3031
|
-
}
|
|
3032
|
-
if (maxCallAttemptsToWaitForAlreadyRunningRequest === void 0) {
|
|
3033
|
-
maxCallAttemptsToWaitForAlreadyRunningRequest = 100;
|
|
3034
|
-
}
|
|
3035
|
-
if (timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished === void 0) {
|
|
3036
|
-
timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished = 1000;
|
|
3037
|
-
}
|
|
3038
|
-
if (cacheTtl != null && cacheTtl < timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished * 2) {
|
|
3039
|
-
/*
|
|
3040
|
-
* During the lifetime of this service e.g. if the data is being retrieved slowly we can get
|
|
3041
|
-
* RACE CONDITION when we constantly retrieve data and during retrieval it is expired, so we are trying
|
|
3042
|
-
* to retrieve it again and again.
|
|
3043
|
-
* We have a protection mechanism that we will wait no more than
|
|
3044
|
-
* maxCallAttemptsToWaitForAlreadyRunningRequest * timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished
|
|
3045
|
-
* but this additional check is aimed to reduce potential loading time for some requests.
|
|
3046
|
-
*/
|
|
3047
|
-
throw new Error("DEV: Wrong parameters passed to construct " + bio + " - TTL " + cacheTtl + " should be 2 times greater than " + timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished);
|
|
3048
|
-
}
|
|
3049
|
-
this._bio = bio;
|
|
3050
|
-
this._cache = cache;
|
|
3051
|
-
this._cacheTtlMs = cacheTtl != null ? cacheTtl : null;
|
|
3052
|
-
this._maxExecutionTimeMs = maxCallAttemptsToWaitForAlreadyRunningRequest * timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished;
|
|
3053
|
-
this._removeExpiredCacheAutomatically = removeExpiredCacheAutomatically;
|
|
3054
|
-
this._requestsManager = new ManagerOfRequestsToTheSameResource(bio, maxCallAttemptsToWaitForAlreadyRunningRequest, timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished);
|
|
2888
|
+
* Some endpoint support pagination. Override this method if so and implement corresponding methods.
|
|
2889
|
+
*
|
|
2890
|
+
* @return {boolean} true if this provider requires several requests to retrieve the data
|
|
2891
|
+
*/;
|
|
2892
|
+
_proto.doesSupportPagination = function doesSupportPagination() {
|
|
2893
|
+
return false;
|
|
3055
2894
|
}
|
|
3056
2895
|
|
|
3057
2896
|
/**
|
|
3058
|
-
*
|
|
3059
|
-
* This method checks is there cached data and ether
|
|
3060
|
-
* - returns you flag that you can start requesting data from the shared resource
|
|
3061
|
-
* - or if there is already started calculation waits until it is finished (removed from this service)
|
|
3062
|
-
* and returns you the retrieved data
|
|
3063
|
-
* - or just returns you the cached data
|
|
3064
|
-
*
|
|
3065
|
-
* 'canStartDataRetrieval' equal true means that the lock was acquired, and you should manually call 'saveCachedData'
|
|
3066
|
-
* if needed and then 'releaseLock' to mark this calculation as finished so other
|
|
3067
|
-
* requesters can take their share of the resource.
|
|
2897
|
+
* Composes a query string to be added to the endpoint of this provider.
|
|
3068
2898
|
*
|
|
3069
|
-
* @param
|
|
3070
|
-
* @
|
|
3071
|
-
*
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
* canStartDataRetrieval: false,
|
|
3076
|
-
* cachedData: any
|
|
3077
|
-
* })>}
|
|
3078
|
-
*/
|
|
3079
|
-
var _proto = CacheAndConcurrentRequestsResolver.prototype;
|
|
3080
|
-
_proto.getCachedOrWaitForCachedOrAcquireLock = function getCachedOrWaitForCachedOrAcquireLock(cacheId) {
|
|
3081
|
-
try {
|
|
3082
|
-
var _this = this;
|
|
3083
|
-
return Promise.resolve(_catch$5(function () {
|
|
3084
|
-
function _temp2() {
|
|
3085
|
-
var _cached, _cached2;
|
|
3086
|
-
return calculationId ? {
|
|
3087
|
-
canStartDataRetrieval: true,
|
|
3088
|
-
cachedData: (_cached = cached) != null ? _cached : cachedDataBackupIsPresentButExpired,
|
|
3089
|
-
lockId: calculationId
|
|
3090
|
-
} : {
|
|
3091
|
-
canStartDataRetrieval: false,
|
|
3092
|
-
cachedData: (_cached2 = cached) != null ? _cached2 : cachedDataBackupIsPresentButExpired
|
|
3093
|
-
};
|
|
3094
|
-
}
|
|
3095
|
-
var startedAtTimestamp = Date.now();
|
|
3096
|
-
var cached = _this._cache.get(cacheId);
|
|
3097
|
-
var cachedDataBackupIsPresentButExpired = null;
|
|
3098
|
-
if (cached != null && !_this._removeExpiredCacheAutomatically) {
|
|
3099
|
-
var lastUpdateTimestamp = _this._cache.getLastUpdateTimestamp(cacheId);
|
|
3100
|
-
if ((lastUpdateTimestamp != null ? lastUpdateTimestamp : 0) + _this._cacheTtlMs < Date.now()) {
|
|
3101
|
-
/*
|
|
3102
|
-
* Here we are manually clearing 'cached' value retrieved from cache to force the data loading.
|
|
3103
|
-
* But we save its value first to the backup variable to be able to return this value if ongoing
|
|
3104
|
-
* requesting fails.
|
|
3105
|
-
*/
|
|
3106
|
-
cachedDataBackupIsPresentButExpired = cached;
|
|
3107
|
-
cached = null;
|
|
3108
|
-
}
|
|
3109
|
-
}
|
|
3110
|
-
var calculationId = null;
|
|
3111
|
-
var isRetrievedCacheExpired = true;
|
|
3112
|
-
var isWaitingForActiveCalculationSucceeded;
|
|
3113
|
-
var weStillHaveSomeTimeToProceedExecution = true;
|
|
3114
|
-
var _temp = _for$1(function () {
|
|
3115
|
-
return calculationId == null && cached == null && !!isRetrievedCacheExpired && !!weStillHaveSomeTimeToProceedExecution;
|
|
3116
|
-
}, void 0, function () {
|
|
3117
|
-
return Promise.resolve(_this._requestsManager.startCalculationOrWaitForActiveToFinish(cacheId)).then(function (result) {
|
|
3118
|
-
calculationId = typeof result === "string" ? result : null;
|
|
3119
|
-
isWaitingForActiveCalculationSucceeded = typeof result === "boolean" ? result : null;
|
|
3120
|
-
cached = _this._cache.get(cacheId);
|
|
3121
|
-
isRetrievedCacheExpired = isWaitingForActiveCalculationSucceeded && cached == null;
|
|
3122
|
-
weStillHaveSomeTimeToProceedExecution = Date.now() - startedAtTimestamp < _this._maxExecutionTimeMs;
|
|
3123
|
-
});
|
|
3124
|
-
});
|
|
3125
|
-
return _temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp);
|
|
3126
|
-
}, function (e) {
|
|
3127
|
-
improveAndRethrow(e, _this._bio + ".getCachedOrWaitForCachedOrAcquireLock");
|
|
3128
|
-
}));
|
|
3129
|
-
} catch (e) {
|
|
3130
|
-
return Promise.reject(e);
|
|
3131
|
-
}
|
|
2899
|
+
* @param params {any[]} params array passed to the RobustExternalAPICallerService
|
|
2900
|
+
* @param [subRequestIndex] {number} optional number of the sub-request the call is performed for
|
|
2901
|
+
* @returns {string} query string to be concatenated with endpoint
|
|
2902
|
+
*/;
|
|
2903
|
+
_proto.composeQueryString = function composeQueryString(params, subRequestIndex) {
|
|
2904
|
+
return "";
|
|
3132
2905
|
}
|
|
2906
|
+
|
|
3133
2907
|
/**
|
|
3134
|
-
*
|
|
3135
|
-
* Doesn't wait for the active calculation, doesn't acquire lock, just retrieves the current cache as it is.
|
|
2908
|
+
* Composes a body to be added to the request
|
|
3136
2909
|
*
|
|
3137
|
-
* @param
|
|
3138
|
-
* @
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
_proto.
|
|
3142
|
-
|
|
3143
|
-
return this._cache.get(cacheId);
|
|
3144
|
-
} catch (e) {
|
|
3145
|
-
improveAndRethrow(e, "getCached");
|
|
3146
|
-
}
|
|
3147
|
-
};
|
|
3148
|
-
_proto._getTtl = function _getTtl() {
|
|
3149
|
-
return this._removeExpiredCacheAutomatically ? this._cacheTtlMs : null;
|
|
2910
|
+
* @param params {any[]} params array passed to the RobustExternalAPICallerService
|
|
2911
|
+
* @param [subRequestIndex] {number} optional number of the sub-request the call is performed for
|
|
2912
|
+
* @returns {string}
|
|
2913
|
+
*/;
|
|
2914
|
+
_proto.composeBody = function composeBody(params, subRequestIndex) {
|
|
2915
|
+
return "";
|
|
3150
2916
|
}
|
|
3151
2917
|
|
|
3152
2918
|
/**
|
|
3153
|
-
*
|
|
3154
|
-
* So if this method returns result === true you can start the data retrieval.
|
|
2919
|
+
* Extracts data from the response and returns it
|
|
3155
2920
|
*
|
|
3156
|
-
* @param
|
|
3157
|
-
* @
|
|
2921
|
+
* @param response {Object} HTTP response returned by provider
|
|
2922
|
+
* @param [params] {any[]} params array passed to the RobustExternalAPICallerService
|
|
2923
|
+
* @param [subRequestIndex] {number} optional number of the sub-request the call is performed for
|
|
2924
|
+
* @param iterationsData {any[]} array of data retrieved from previous sub-requests
|
|
2925
|
+
* @returns {any}
|
|
3158
2926
|
*/;
|
|
3159
|
-
_proto.
|
|
3160
|
-
|
|
3161
|
-
var _this2 = this;
|
|
3162
|
-
return Promise.resolve(_catch$5(function () {
|
|
3163
|
-
return Promise.resolve(_this2._requestsManager.acquireLock(cacheId));
|
|
3164
|
-
}, function (e) {
|
|
3165
|
-
improveAndRethrow(e, "acquireLock");
|
|
3166
|
-
}));
|
|
3167
|
-
} catch (e) {
|
|
3168
|
-
return Promise.reject(e);
|
|
3169
|
-
}
|
|
2927
|
+
_proto.getDataByResponse = function getDataByResponse(response, params, subRequestIndex, iterationsData) {
|
|
2928
|
+
return [];
|
|
3170
2929
|
}
|
|
2930
|
+
|
|
3171
2931
|
/**
|
|
3172
|
-
*
|
|
3173
|
-
*
|
|
3174
|
-
* If the current lock id is not equal to the passed one the passed data will be ignored.
|
|
3175
|
-
* Or you can do the synchronous data merging on your side and pass the
|
|
3176
|
-
* wasDataMergedSynchronouslyWithMostRecentCacheState=true so your data will be stored
|
|
3177
|
-
* despite on the lockId.
|
|
3178
|
-
* WARNING: you should do this only if you are sure you perform the synchronous update.
|
|
2932
|
+
* Function changing the query string according to page number and previous response
|
|
2933
|
+
* Only for endpoints supporting pagination
|
|
3179
2934
|
*
|
|
3180
|
-
* @param
|
|
3181
|
-
* @param
|
|
3182
|
-
* @param
|
|
3183
|
-
*
|
|
3184
|
-
* @param [
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
_proto.
|
|
3188
|
-
|
|
3189
|
-
sessionDependentData = true;
|
|
3190
|
-
}
|
|
3191
|
-
if (wasDataMergedSynchronouslyWithMostRecentCacheState === void 0) {
|
|
3192
|
-
wasDataMergedSynchronouslyWithMostRecentCacheState = false;
|
|
3193
|
-
}
|
|
3194
|
-
try {
|
|
3195
|
-
if (wasDataMergedSynchronouslyWithMostRecentCacheState || this._requestsManager.isTheLockActiveOne(cacheId, lockId)) {
|
|
3196
|
-
/* We save passed data only if the <caller> has the currently acquired lockId.
|
|
3197
|
-
* If the passed lockId is not the active one it means that other code cleared/stopped the lock
|
|
3198
|
-
* acquired by the <caller> recently due to some urgent/more prior changes.
|
|
3199
|
-
*
|
|
3200
|
-
* But we allow user to pass the 'wasDataMergedSynchronouslyWithMostRecentCacheState' flag
|
|
3201
|
-
* that tells us that the user had taken the most recent cache value and merged his new data
|
|
3202
|
-
* with that cached value (AFTER possibly performing async data retrieval). This means that we
|
|
3203
|
-
* can ignore the fact that his lockId is no more relevant and save the passed data
|
|
3204
|
-
* as it is synchronously merged with the most recent cached data. (Synchronously merged means that
|
|
3205
|
-
* the lost update cannot occur during the merge time as JS execute the synchronous functions\
|
|
3206
|
-
* till the end).
|
|
3207
|
-
*/
|
|
3208
|
-
if (sessionDependentData) {
|
|
3209
|
-
this._cache.putSessionDependentData(cacheId, data, this._getTtl());
|
|
3210
|
-
} else {
|
|
3211
|
-
this._cache.put(cacheId, data, this._getTtl());
|
|
3212
|
-
}
|
|
3213
|
-
}
|
|
3214
|
-
} catch (e) {
|
|
3215
|
-
improveAndRethrow(e, this._bio + ".saveCachedData");
|
|
3216
|
-
}
|
|
2935
|
+
* @param params {any[]} params array passed to the RobustExternalAPICallerService
|
|
2936
|
+
* @param previousResponse {Object} HTTP response returned by provider for previous call (previous page)
|
|
2937
|
+
* @param pageNumber {number} new page number. We count from 0. You need to manually increment with 1 if your
|
|
2938
|
+
* provider counts pages starting with 1
|
|
2939
|
+
* @param [subRequestIndex] {number} optional number of the sub-request the call is performed for
|
|
2940
|
+
* @returns {any[]}
|
|
2941
|
+
*/;
|
|
2942
|
+
_proto.changeQueryParametersForPageNumber = function changeQueryParametersForPageNumber(params, previousResponse, pageNumber, subRequestIndex) {
|
|
2943
|
+
return params;
|
|
3217
2944
|
}
|
|
3218
2945
|
|
|
3219
2946
|
/**
|
|
3220
|
-
*
|
|
2947
|
+
* Function checking whether the response is for the last page to stop requesting for a next page.
|
|
2948
|
+
* Only for endpoints supporting pagination.
|
|
3221
2949
|
*
|
|
3222
|
-
* @param
|
|
3223
|
-
* @param
|
|
2950
|
+
* @param previousResponse {Object} HTTP response returned by provider for previous call (previous page)
|
|
2951
|
+
* @param currentResponse {Object} HTTP response returned by provider for current call (current page, next after the previous)
|
|
2952
|
+
* @param currentPageNumber {number} current page number (for current response)
|
|
2953
|
+
* @param [subRequestIndex] {number} optional number of the sub-request the call is performed for
|
|
2954
|
+
* @returns {boolean}
|
|
3224
2955
|
*/;
|
|
3225
|
-
_proto.
|
|
3226
|
-
|
|
3227
|
-
if (this._requestsManager.isTheLockActiveOne(cacheId, lockId)) {
|
|
3228
|
-
this._requestsManager.finishActiveCalculation(cacheId);
|
|
3229
|
-
}
|
|
3230
|
-
} catch (e) {
|
|
3231
|
-
improveAndRethrow(e, this._bio + ".releaseLock");
|
|
3232
|
-
}
|
|
2956
|
+
_proto.checkWhetherResponseIsForLastPage = function checkWhetherResponseIsForLastPage(previousResponse, currentResponse, currentPageNumber, subRequestIndex) {
|
|
2957
|
+
return true;
|
|
3233
2958
|
}
|
|
3234
2959
|
|
|
3235
2960
|
/**
|
|
3236
|
-
*
|
|
2961
|
+
* Resets the nice factor to default value
|
|
2962
|
+
*/;
|
|
2963
|
+
_proto.resetNiceFactor = function resetNiceFactor() {
|
|
2964
|
+
this.niceFactor = 1;
|
|
2965
|
+
}
|
|
2966
|
+
|
|
2967
|
+
/**
|
|
2968
|
+
* Internal method used for requests requiring sub-requests.
|
|
3237
2969
|
*
|
|
3238
|
-
* @param
|
|
3239
|
-
* @
|
|
3240
|
-
* an object in following format:
|
|
3241
|
-
* {
|
|
3242
|
-
* isModified: boolean,
|
|
3243
|
-
* data: any
|
|
3244
|
-
* }
|
|
3245
|
-
* the flag signals whether data was changed during the processing or not
|
|
3246
|
-
* @param [sessionDependent=true] {boolean} whether to mark the cache entry as session-dependent
|
|
2970
|
+
* @param iterationsData {any[]} iterations data retrieved from getDataByResponse called per sub-request.
|
|
2971
|
+
* @return {any} by default flatten the passed iterations data array. Should be redefined if you need another logic.
|
|
3247
2972
|
*/;
|
|
3248
|
-
_proto.
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
var cached = this._cache.get(cacheId);
|
|
3254
|
-
var result = synchronousCurrentCacheProcessor(cached);
|
|
3255
|
-
if (result != null && result.isModified && (result == null ? void 0 : result.data) != null) {
|
|
3256
|
-
if (sessionDependent) {
|
|
3257
|
-
this._cache.putSessionDependentData(cacheId, result == null ? void 0 : result.data, this._getTtl());
|
|
3258
|
-
} else {
|
|
3259
|
-
this._cache.put(cacheId, result == null ? void 0 : result.data, this._getTtl());
|
|
3260
|
-
}
|
|
2973
|
+
_proto.incorporateIterationsData = function incorporateIterationsData(iterationsData) {
|
|
2974
|
+
return iterationsData.flat();
|
|
2975
|
+
};
|
|
2976
|
+
return ExternalApiProvider;
|
|
2977
|
+
}();
|
|
3261
2978
|
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
* So we better lose some data retrieval (means abusing the resource a bit) than lose
|
|
3273
|
-
* the instant update expected after this method execution.
|
|
3274
|
-
*/
|
|
3275
|
-
this._requestsManager.finishActiveCalculation(cacheId);
|
|
3276
|
-
}
|
|
3277
|
-
} catch (e) {
|
|
3278
|
-
improveAndRethrow(e, this._bio + ".actualizeCachedData");
|
|
2979
|
+
/**
|
|
2980
|
+
* Models a group of APIs provided by the same owner and used for different services in our app.
|
|
2981
|
+
* It means we need to mention RPS several times for each usage and also have some holder of last call timestamp per
|
|
2982
|
+
* api group. So this concept allows to use it for exact ExternalApiProvider and make sure that you use the same
|
|
2983
|
+
* RPS value and make decisions on base of the same timestamp of last call to the API group owner.
|
|
2984
|
+
*/
|
|
2985
|
+
var ApiGroup = /*#__PURE__*/function () {
|
|
2986
|
+
function ApiGroup(id, rps, backendProxyIdGenerator) {
|
|
2987
|
+
if (backendProxyIdGenerator === void 0) {
|
|
2988
|
+
backendProxyIdGenerator = null;
|
|
3279
2989
|
}
|
|
2990
|
+
this.id = id;
|
|
2991
|
+
this.rps = rps;
|
|
2992
|
+
this.lastCalledTimestamp = null;
|
|
2993
|
+
this.backendProxyIdGenerator = backendProxyIdGenerator;
|
|
2994
|
+
}
|
|
2995
|
+
var _proto = ApiGroup.prototype;
|
|
2996
|
+
_proto.isRpsExceeded = function isRpsExceeded() {
|
|
2997
|
+
var _this$lastCalledTimes;
|
|
2998
|
+
return ((_this$lastCalledTimes = this.lastCalledTimestamp) != null ? _this$lastCalledTimes : 0) + Math.floor(1000 / this.rps) > Date.now();
|
|
3280
2999
|
};
|
|
3281
|
-
_proto.
|
|
3282
|
-
this.
|
|
3283
|
-
this._requestsManager.finishActiveCalculation(key);
|
|
3284
|
-
};
|
|
3285
|
-
_proto.invalidateContaining = function invalidateContaining(keyPart) {
|
|
3286
|
-
this._cache.invalidateContaining(keyPart);
|
|
3287
|
-
this._requestsManager.finishAllActiveCalculations(keyPart);
|
|
3288
|
-
};
|
|
3289
|
-
_proto.markAsExpiredButDontRemove = function markAsExpiredButDontRemove(key) {
|
|
3290
|
-
if (this._removeExpiredCacheAutomatically) {
|
|
3291
|
-
this._cache.markCacheItemAsExpiredButDontRemove(key, this._cacheTtlMs);
|
|
3292
|
-
} else {
|
|
3293
|
-
this._cache.setLastUpdateTimestamp(key, Date.now() - this._cacheTtlMs - 1);
|
|
3294
|
-
}
|
|
3295
|
-
this._requestsManager.finishAllActiveCalculations(key);
|
|
3000
|
+
_proto.actualizeLastCalledTimestamp = function actualizeLastCalledTimestamp() {
|
|
3001
|
+
this.lastCalledTimestamp = Date.now();
|
|
3296
3002
|
};
|
|
3297
|
-
return
|
|
3003
|
+
return ApiGroup;
|
|
3298
3004
|
}();
|
|
3299
|
-
var
|
|
3005
|
+
var ApiGroups = {
|
|
3300
3006
|
/**
|
|
3301
|
-
*
|
|
3302
|
-
*
|
|
3303
|
-
* @param [timeoutDuration=1000] {number} timeout between the polls for a lock acquisition
|
|
3007
|
+
* Currently we use free version of etherscan provider with 0.2 RPS. But we have API key with 100k requests free
|
|
3008
|
+
* per month. So we can add it if not enough current RPS.
|
|
3304
3009
|
*/
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3010
|
+
ETHERSCAN: new ApiGroup("etherscan", 0.17),
|
|
3011
|
+
// Actually 0.2 but fails sometime, so we use smaller
|
|
3012
|
+
ALCHEMY: new ApiGroup("alchemy", 0.3, function (networkKey) {
|
|
3013
|
+
return "alchemy-" + networkKey;
|
|
3014
|
+
}),
|
|
3015
|
+
BLOCKSTREAM: new ApiGroup("blockstream", 0.2),
|
|
3016
|
+
BLOCKCHAIN_INFO: new ApiGroup("blockchain.info", 1),
|
|
3017
|
+
BLOCKNATIVE: new ApiGroup("blocknative", 0.5),
|
|
3018
|
+
ETHGASSTATION: new ApiGroup("ethgasstation", 0.5),
|
|
3019
|
+
TRONGRID: new ApiGroup("trongrid", 0.3, function (networkKey) {
|
|
3020
|
+
return "trongrid-" + networkKey;
|
|
3021
|
+
}),
|
|
3022
|
+
TRONSCAN: new ApiGroup("tronscan", 0.3),
|
|
3023
|
+
GETBLOCK: new ApiGroup("getblock", 0.3),
|
|
3024
|
+
COINCAP: new ApiGroup("coincap", 0.5),
|
|
3025
|
+
// 200 per minute without API key
|
|
3026
|
+
COINGECKO: new ApiGroup("coingecko", 0.9),
|
|
3027
|
+
// actually 0.13-0.5 according to the docs but we use smaller due to expirienced frequent abuses
|
|
3028
|
+
MESSARI: new ApiGroup("messari", 0.2),
|
|
3029
|
+
BTCCOM: new ApiGroup("btccom", 0.2),
|
|
3030
|
+
BITAPS: new ApiGroup("bitaps", 0.25),
|
|
3031
|
+
// Docs say that RPS is 3 but using it causes frequent 429 HTTP errors
|
|
3032
|
+
CEX: new ApiGroup("cex", 0.5),
|
|
3033
|
+
// Just assumption for RPS
|
|
3034
|
+
BIGDATACLOUD: new ApiGroup("bigdatacloud", 1),
|
|
3035
|
+
// Just assumption for RPS
|
|
3036
|
+
TRACKIP: new ApiGroup("trackip", 1),
|
|
3037
|
+
// Just assumption for RPS
|
|
3038
|
+
IPIFY: new ApiGroup("ipify", 1),
|
|
3039
|
+
// Just assumption for RPS
|
|
3040
|
+
WHATISMYIPADDRESS: new ApiGroup("whatismyipaddress", 1),
|
|
3041
|
+
// Just assumption for RPS
|
|
3042
|
+
EXCHANGERATE: new ApiGroup("exchangerate", 1),
|
|
3043
|
+
// Just assumption for RPS
|
|
3044
|
+
FRANKFURTER: new ApiGroup("frankfurter", 1),
|
|
3045
|
+
// Just assumption for RPS
|
|
3046
|
+
BITGO: new ApiGroup("bitgo", 1),
|
|
3047
|
+
// Just assumption for RPS
|
|
3048
|
+
BITCOINER: new ApiGroup("bitcoiner", 1),
|
|
3049
|
+
// Just assumption for RPS
|
|
3050
|
+
BITCORE: new ApiGroup("bitcore", 1),
|
|
3051
|
+
// Just assumption for RPS
|
|
3052
|
+
// BLOCKCHAIR: new ApiGroup("blockchair", 0.04), // this provider require API key for commercial use (10usd 10000 reqs), we will add it later
|
|
3053
|
+
MEMPOOL: new ApiGroup("mempool", 0.2) // Just assumption for RPS
|
|
3054
|
+
};
|
|
3055
|
+
|
|
3056
|
+
// TODO: [refactoring, low] Consider removing this logic task_id=c360f2af75764bde8badd9ff1cc00d48
|
|
3057
|
+
var ConcurrentCalculationsMetadataHolder = /*#__PURE__*/function () {
|
|
3058
|
+
function ConcurrentCalculationsMetadataHolder() {
|
|
3059
|
+
this._calculations = {};
|
|
3060
|
+
}
|
|
3061
|
+
var _proto = ConcurrentCalculationsMetadataHolder.prototype;
|
|
3062
|
+
_proto.startCalculation = function startCalculation(domain, calculationsHistoryMaxLength) {
|
|
3063
|
+
if (calculationsHistoryMaxLength === void 0) {
|
|
3064
|
+
calculationsHistoryMaxLength = 100;
|
|
3308
3065
|
}
|
|
3309
|
-
if (
|
|
3310
|
-
|
|
3066
|
+
if (!this._calculations[domain]) {
|
|
3067
|
+
this._calculations[domain] = [];
|
|
3068
|
+
}
|
|
3069
|
+
if (this._calculations[domain].length > calculationsHistoryMaxLength) {
|
|
3070
|
+
this._calculations[domain] = this._calculations[domain].slice(Math.round(calculationsHistoryMaxLength * 0.2));
|
|
3071
|
+
}
|
|
3072
|
+
var newCalculation = {
|
|
3073
|
+
startTimestamp: Date.now(),
|
|
3074
|
+
endTimestamp: null,
|
|
3075
|
+
uuid: uuid.v4()
|
|
3076
|
+
};
|
|
3077
|
+
this._calculations[domain].push(newCalculation);
|
|
3078
|
+
return newCalculation.uuid;
|
|
3079
|
+
};
|
|
3080
|
+
_proto.endCalculation = function endCalculation(domain, uuid, isFailed) {
|
|
3081
|
+
if (isFailed === void 0) {
|
|
3082
|
+
isFailed = false;
|
|
3311
3083
|
}
|
|
3312
|
-
this.bio = bio;
|
|
3313
|
-
this.maxPollsCount = maxPollsCount;
|
|
3314
|
-
this.timeoutDuration = timeoutDuration;
|
|
3315
|
-
this._activeCalculationsIds = new Map();
|
|
3316
|
-
this._nextCalculationIds = new Map();
|
|
3317
|
-
}
|
|
3318
|
-
|
|
3319
|
-
/**
|
|
3320
|
-
* If there is no active calculation just creates uuid and returns it.
|
|
3321
|
-
* If there is active calculation waits until it removed from the active calculation uuid variable.
|
|
3322
|
-
*
|
|
3323
|
-
* @param requestHash {string}
|
|
3324
|
-
* @return {Promise<string|boolean>} returns uuid of new active calculation or true if waiting for active
|
|
3325
|
-
* calculation succeed or false if max attempts count exceeded
|
|
3326
|
-
*/
|
|
3327
|
-
var _proto2 = ManagerOfRequestsToTheSameResource.prototype;
|
|
3328
|
-
_proto2.startCalculationOrWaitForActiveToFinish = function startCalculationOrWaitForActiveToFinish(requestHash) {
|
|
3329
3084
|
try {
|
|
3330
|
-
var
|
|
3331
|
-
var
|
|
3332
|
-
|
|
3333
|
-
var activeCalculationIdForHash = _this3._activeCalculationsIds.get(requestHash);
|
|
3334
|
-
if (activeCalculationIdForHash == null) {
|
|
3335
|
-
var id = uuid.v4();
|
|
3336
|
-
_this3._activeCalculationsIds.set(requestHash, id);
|
|
3337
|
-
_exit = 1;
|
|
3338
|
-
return id;
|
|
3339
|
-
}
|
|
3340
|
-
return Promise.resolve(_this3._waitForCalculationIdToFinish(requestHash, activeCalculationIdForHash, 0)).then(function (_await$_this3$_waitFo) {
|
|
3341
|
-
_exit = 1;
|
|
3342
|
-
return _await$_this3$_waitFo;
|
|
3343
|
-
});
|
|
3344
|
-
}, function (e) {
|
|
3345
|
-
Logger.logError(e, "startCalculationOrWaitForActiveToFinish_" + _this3.bio);
|
|
3085
|
+
var _calculation$endTimes, _calculation$startTim, _calculation$uuid;
|
|
3086
|
+
var calculation = this._calculations[domain].find(function (calculation) {
|
|
3087
|
+
return (calculation == null ? void 0 : calculation.uuid) === uuid;
|
|
3346
3088
|
});
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3089
|
+
if (calculation) {
|
|
3090
|
+
calculation.endTimestamp = Date.now();
|
|
3091
|
+
calculation.isFiled = isFailed;
|
|
3092
|
+
}
|
|
3093
|
+
var elapsed = ((((_calculation$endTimes = calculation == null ? void 0 : calculation.endTimestamp) != null ? _calculation$endTimes : 0) - ((_calculation$startTim = calculation == null ? void 0 : calculation.startTimestamp) != null ? _calculation$startTim : 0)) / 1000).toFixed(1);
|
|
3094
|
+
Logger.log("endCalculation", elapsed + " ms: " + domain + "." + ((_calculation$uuid = calculation == null ? void 0 : calculation.uuid) != null ? _calculation$uuid : "").slice(0, 7));
|
|
3095
|
+
return calculation;
|
|
3350
3096
|
} catch (e) {
|
|
3351
|
-
|
|
3097
|
+
Logger.logError(e, "endCalculation");
|
|
3098
|
+
}
|
|
3099
|
+
};
|
|
3100
|
+
_proto.isCalculationLate = function isCalculationLate(domain, uuid) {
|
|
3101
|
+
var queue = this._calculations[domain];
|
|
3102
|
+
var analysingCalculation = queue.find(function (item) {
|
|
3103
|
+
return item.uuid === uuid;
|
|
3104
|
+
});
|
|
3105
|
+
return analysingCalculation && !!queue.find(function (calculation) {
|
|
3106
|
+
return calculation.endTimestamp != null && calculation.startTimestamp > analysingCalculation.startTimestamp;
|
|
3107
|
+
});
|
|
3108
|
+
};
|
|
3109
|
+
_proto.printCalculationsWaitingMoreThanSpecifiedSeconds = function printCalculationsWaitingMoreThanSpecifiedSeconds(waitingLastsMs) {
|
|
3110
|
+
var _this = this;
|
|
3111
|
+
if (waitingLastsMs === void 0) {
|
|
3112
|
+
waitingLastsMs = 2000;
|
|
3352
3113
|
}
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
result: true,
|
|
3374
|
-
lockId: nextId
|
|
3375
|
-
};
|
|
3376
|
-
}
|
|
3377
|
-
var currentNext = (_this4$_nextCalculati = _this4._nextCalculationIds.get(requestHash)) != null ? _this4$_nextCalculati : [];
|
|
3378
|
-
currentNext.push(nextId);
|
|
3379
|
-
_this4._nextCalculationIds.set(requestHash, currentNext);
|
|
3380
|
-
return Promise.resolve(_this4._waitForCalculationIdToFinish(requestHash, activeId, 0, nextId)).then(function (waitingResult) {
|
|
3381
|
-
return {
|
|
3382
|
-
result: waitingResult,
|
|
3383
|
-
lockId: waitingResult ? nextId : undefined
|
|
3384
|
-
};
|
|
3385
|
-
});
|
|
3386
|
-
}, function (e) {
|
|
3387
|
-
improveAndRethrow(e, "acquireLock");
|
|
3388
|
-
}));
|
|
3389
|
-
} catch (e) {
|
|
3390
|
-
return Promise.reject(e);
|
|
3391
|
-
}
|
|
3392
|
-
}
|
|
3393
|
-
/**
|
|
3394
|
-
* Clears active calculation id.
|
|
3395
|
-
* WARNING: if you forget to call this method the start* one will perform maxPollsCount attempts before finishing
|
|
3396
|
-
* @param requestHash {string} hash of request. Helps to distinct the request for the same resource but
|
|
3397
|
-
* having different request parameters and hold a dedicated calculation id per this hash
|
|
3398
|
-
*/
|
|
3399
|
-
;
|
|
3400
|
-
_proto2.finishActiveCalculation = function finishActiveCalculation(requestHash) {
|
|
3401
|
-
if (requestHash === void 0) {
|
|
3402
|
-
requestHash = "default";
|
|
3403
|
-
}
|
|
3404
|
-
try {
|
|
3405
|
-
var _this$_nextCalculatio;
|
|
3406
|
-
this._activeCalculationsIds["delete"](requestHash);
|
|
3407
|
-
var next = (_this$_nextCalculatio = this._nextCalculationIds.get(requestHash)) != null ? _this$_nextCalculatio : [];
|
|
3408
|
-
if (next.length) {
|
|
3409
|
-
this._activeCalculationsIds.set(requestHash, next[0]);
|
|
3410
|
-
this._nextCalculationIds.set(requestHash, next.slice(1));
|
|
3411
|
-
}
|
|
3412
|
-
} catch (e) {
|
|
3413
|
-
improveAndRethrow(e, "finishActiveCalculation");
|
|
3414
|
-
}
|
|
3415
|
-
};
|
|
3416
|
-
_proto2.finishAllActiveCalculations = function finishAllActiveCalculations(keyPart) {
|
|
3417
|
-
var _this5 = this;
|
|
3418
|
-
if (keyPart === void 0) {
|
|
3419
|
-
keyPart = "";
|
|
3420
|
-
}
|
|
3421
|
-
try {
|
|
3422
|
-
Array.from(this._activeCalculationsIds.keys()).forEach(function (hash) {
|
|
3423
|
-
if (typeof hash === "string" && new RegExp(keyPart).test(hash)) {
|
|
3424
|
-
_this5.finishActiveCalculation(hash);
|
|
3425
|
-
}
|
|
3426
|
-
});
|
|
3427
|
-
} catch (e) {
|
|
3428
|
-
improveAndRethrow(e, "finishAllActiveCalculations");
|
|
3429
|
-
}
|
|
3430
|
-
}
|
|
3431
|
-
|
|
3432
|
-
/**
|
|
3433
|
-
* @param requestHash {string}
|
|
3434
|
-
* @param lockId {string}
|
|
3435
|
-
* @return {boolean}
|
|
3436
|
-
*/;
|
|
3437
|
-
_proto2.isTheLockActiveOne = function isTheLockActiveOne(requestHash, lockId) {
|
|
3438
|
-
try {
|
|
3439
|
-
return this._activeCalculationsIds.get(requestHash) === lockId;
|
|
3440
|
-
} catch (e) {
|
|
3441
|
-
improveAndRethrow(e, "isTheLockActiveOne");
|
|
3442
|
-
}
|
|
3443
|
-
}
|
|
3444
|
-
|
|
3445
|
-
/**
|
|
3446
|
-
* @param requestHash {string}
|
|
3447
|
-
* @param activeCalculationId {string|null}
|
|
3448
|
-
* @param [attemptIndex=0] {number}
|
|
3449
|
-
* @param waitForCalculationId {string|null} if you want to wait for an exact id to appear as active then pass this parameter
|
|
3450
|
-
* @return {Promise<boolean>} true
|
|
3451
|
-
* - if the given calculation id is no more an active one
|
|
3452
|
-
* - or it is equal to waitForCalculationId
|
|
3453
|
-
* false
|
|
3454
|
-
* - if waiting period exceeds the max allowed waiting time or unexpected error occurs
|
|
3455
|
-
* @private
|
|
3456
|
-
*/;
|
|
3457
|
-
_proto2._waitForCalculationIdToFinish = function _waitForCalculationIdToFinish(requestHash, activeCalculationId, attemptIndex, waitForCalculationId) {
|
|
3458
|
-
if (attemptIndex === void 0) {
|
|
3459
|
-
attemptIndex = 0;
|
|
3460
|
-
}
|
|
3461
|
-
if (waitForCalculationId === void 0) {
|
|
3462
|
-
waitForCalculationId = null;
|
|
3463
|
-
}
|
|
3464
|
-
try {
|
|
3465
|
-
var _this6 = this;
|
|
3466
|
-
try {
|
|
3467
|
-
if (attemptIndex + 1 > _this6.maxPollsCount) {
|
|
3468
|
-
// Max number of polls for active calculation id change is achieved. So we return false.
|
|
3469
|
-
return Promise.resolve(false);
|
|
3470
|
-
}
|
|
3471
|
-
var currentId = _this6._activeCalculationsIds.get(requestHash);
|
|
3472
|
-
if (waitForCalculationId == null ? currentId !== activeCalculationId : currentId === waitForCalculationId) {
|
|
3473
|
-
/* We return true depending on the usage of this function:
|
|
3474
|
-
* 1. if there is calculation id that we should wait for to become an active then we return true only
|
|
3475
|
-
* if this id becomes the active one.
|
|
3476
|
-
*
|
|
3477
|
-
* Theoretically we can fail to wait for the desired calculation id. This can be caused by wrong use of
|
|
3478
|
-
* this service or by any other mistakes/errors. But this waiting function will return false anyway if
|
|
3479
|
-
* the number of polls done exceeds the max allowed.
|
|
3480
|
-
*
|
|
3481
|
-
* 2. if we just wait for the currently active calculation id to be finished then we return true
|
|
3482
|
-
* when we notice that the current active id differs from the original passed into this function.
|
|
3483
|
-
*/
|
|
3484
|
-
return Promise.resolve(true);
|
|
3485
|
-
} else {
|
|
3486
|
-
/* The original calculation id is still the active one, so we are scheduling a new attempt to check
|
|
3487
|
-
* whether the active calculation id changed or not in timeoutDuration milliseconds.
|
|
3488
|
-
*/
|
|
3489
|
-
var it = _this6;
|
|
3490
|
-
return Promise.resolve(new Promise(function (resolve, reject) {
|
|
3491
|
-
setTimeout(function () {
|
|
3492
|
-
try {
|
|
3493
|
-
resolve(it._waitForCalculationIdToFinish(requestHash, activeCalculationId, attemptIndex + 1));
|
|
3494
|
-
} catch (e) {
|
|
3495
|
-
reject(e);
|
|
3496
|
-
}
|
|
3497
|
-
}, _this6.timeoutDuration);
|
|
3498
|
-
}));
|
|
3499
|
-
}
|
|
3500
|
-
} catch (e) {
|
|
3501
|
-
Logger.logError(e, "_waitForCalculationIdToFinish", "Failed to wait for active calculation id change.");
|
|
3502
|
-
return Promise.resolve(false);
|
|
3503
|
-
}
|
|
3504
|
-
} catch (e) {
|
|
3505
|
-
return Promise.reject(e);
|
|
3506
|
-
}
|
|
3507
|
-
};
|
|
3508
|
-
return ManagerOfRequestsToTheSameResource;
|
|
3509
|
-
}();
|
|
3510
|
-
|
|
3511
|
-
// TODO: [refactoring, low] Consider removing this logic task_id=c360f2af75764bde8badd9ff1cc00d48
|
|
3512
|
-
var ConcurrentCalculationsMetadataHolder = /*#__PURE__*/function () {
|
|
3513
|
-
function ConcurrentCalculationsMetadataHolder() {
|
|
3514
|
-
this._calculations = {};
|
|
3515
|
-
}
|
|
3516
|
-
var _proto = ConcurrentCalculationsMetadataHolder.prototype;
|
|
3517
|
-
_proto.startCalculation = function startCalculation(domain, calculationsHistoryMaxLength) {
|
|
3518
|
-
if (calculationsHistoryMaxLength === void 0) {
|
|
3519
|
-
calculationsHistoryMaxLength = 100;
|
|
3520
|
-
}
|
|
3521
|
-
if (!this._calculations[domain]) {
|
|
3522
|
-
this._calculations[domain] = [];
|
|
3523
|
-
}
|
|
3524
|
-
if (this._calculations[domain].length > calculationsHistoryMaxLength) {
|
|
3525
|
-
this._calculations[domain] = this._calculations[domain].slice(Math.round(calculationsHistoryMaxLength * 0.2));
|
|
3526
|
-
}
|
|
3527
|
-
var newCalculation = {
|
|
3528
|
-
startTimestamp: Date.now(),
|
|
3529
|
-
endTimestamp: null,
|
|
3530
|
-
uuid: uuid.v4()
|
|
3531
|
-
};
|
|
3532
|
-
this._calculations[domain].push(newCalculation);
|
|
3533
|
-
return newCalculation.uuid;
|
|
3534
|
-
};
|
|
3535
|
-
_proto.endCalculation = function endCalculation(domain, uuid, isFailed) {
|
|
3536
|
-
if (isFailed === void 0) {
|
|
3537
|
-
isFailed = false;
|
|
3538
|
-
}
|
|
3539
|
-
try {
|
|
3540
|
-
var _calculation$endTimes, _calculation$startTim, _calculation$uuid;
|
|
3541
|
-
var calculation = this._calculations[domain].find(function (calculation) {
|
|
3542
|
-
return (calculation == null ? void 0 : calculation.uuid) === uuid;
|
|
3543
|
-
});
|
|
3544
|
-
if (calculation) {
|
|
3545
|
-
calculation.endTimestamp = Date.now();
|
|
3546
|
-
calculation.isFiled = isFailed;
|
|
3547
|
-
}
|
|
3548
|
-
var elapsed = ((((_calculation$endTimes = calculation == null ? void 0 : calculation.endTimestamp) != null ? _calculation$endTimes : 0) - ((_calculation$startTim = calculation == null ? void 0 : calculation.startTimestamp) != null ? _calculation$startTim : 0)) / 1000).toFixed(1);
|
|
3549
|
-
Logger.log("endCalculation", elapsed + " ms: " + domain + "." + ((_calculation$uuid = calculation == null ? void 0 : calculation.uuid) != null ? _calculation$uuid : "").slice(0, 7));
|
|
3550
|
-
return calculation;
|
|
3551
|
-
} catch (e) {
|
|
3552
|
-
Logger.logError(e, "endCalculation");
|
|
3553
|
-
}
|
|
3554
|
-
};
|
|
3555
|
-
_proto.isCalculationLate = function isCalculationLate(domain, uuid) {
|
|
3556
|
-
var queue = this._calculations[domain];
|
|
3557
|
-
var analysingCalculation = queue.find(function (item) {
|
|
3558
|
-
return item.uuid === uuid;
|
|
3559
|
-
});
|
|
3560
|
-
return analysingCalculation && !!queue.find(function (calculation) {
|
|
3561
|
-
return calculation.endTimestamp != null && calculation.startTimestamp > analysingCalculation.startTimestamp;
|
|
3562
|
-
});
|
|
3563
|
-
};
|
|
3564
|
-
_proto.printCalculationsWaitingMoreThanSpecifiedSeconds = function printCalculationsWaitingMoreThanSpecifiedSeconds(waitingLastsMs) {
|
|
3565
|
-
var _this = this;
|
|
3566
|
-
if (waitingLastsMs === void 0) {
|
|
3567
|
-
waitingLastsMs = 2000;
|
|
3568
|
-
}
|
|
3569
|
-
var calculations = Object.keys(this._calculations).map(function (domain) {
|
|
3570
|
-
return _this._calculations[domain].map(function (c) {
|
|
3571
|
-
return _extends({}, c, {
|
|
3572
|
-
domain: domain
|
|
3573
|
-
});
|
|
3574
|
-
});
|
|
3575
|
-
}).flat().filter(function (c) {
|
|
3576
|
-
return c.endTimestamp === null && Date.now() - c.startTimestamp > waitingLastsMs;
|
|
3577
|
-
});
|
|
3578
|
-
Logger.log("printCalculationsWaitingMoreThanSpecifiedSeconds", "Calculations waiting more than " + (waitingLastsMs / 1000).toFixed(1) + "s:\n" + calculations.map(function (c) {
|
|
3579
|
-
return c.domain + "." + c.uuid.slice(0, 8) + ": " + (Date.now() - c.startTimestamp) + "\n";
|
|
3580
|
-
}));
|
|
3581
|
-
};
|
|
3582
|
-
return ConcurrentCalculationsMetadataHolder;
|
|
3583
|
-
}();
|
|
3584
|
-
var concurrentCalculationsMetadataHolder = new ConcurrentCalculationsMetadataHolder();
|
|
3585
|
-
|
|
3586
|
-
var ExternalServicesStatsCollector = /*#__PURE__*/function () {
|
|
3587
|
-
function ExternalServicesStatsCollector() {
|
|
3588
|
-
this.stats = new Map();
|
|
3114
|
+
var calculations = Object.keys(this._calculations).map(function (domain) {
|
|
3115
|
+
return _this._calculations[domain].map(function (c) {
|
|
3116
|
+
return _extends({}, c, {
|
|
3117
|
+
domain: domain
|
|
3118
|
+
});
|
|
3119
|
+
});
|
|
3120
|
+
}).flat().filter(function (c) {
|
|
3121
|
+
return c.endTimestamp === null && Date.now() - c.startTimestamp > waitingLastsMs;
|
|
3122
|
+
});
|
|
3123
|
+
Logger.log("printCalculationsWaitingMoreThanSpecifiedSeconds", "Calculations waiting more than " + (waitingLastsMs / 1000).toFixed(1) + "s:\n" + calculations.map(function (c) {
|
|
3124
|
+
return c.domain + "." + c.uuid.slice(0, 8) + ": " + (Date.now() - c.startTimestamp) + "\n";
|
|
3125
|
+
}));
|
|
3126
|
+
};
|
|
3127
|
+
return ConcurrentCalculationsMetadataHolder;
|
|
3128
|
+
}();
|
|
3129
|
+
var concurrentCalculationsMetadataHolder = new ConcurrentCalculationsMetadataHolder();
|
|
3130
|
+
|
|
3131
|
+
var ExternalServicesStatsCollector = /*#__PURE__*/function () {
|
|
3132
|
+
function ExternalServicesStatsCollector() {
|
|
3133
|
+
this.stats = new Map();
|
|
3589
3134
|
}
|
|
3590
3135
|
var _proto = ExternalServicesStatsCollector.prototype;
|
|
3591
3136
|
_proto.externalServiceFailed = function externalServiceFailed(serviceUrl, message) {
|
|
@@ -3675,7 +3220,7 @@ var ExternalServicesStatsCollector = /*#__PURE__*/function () {
|
|
|
3675
3220
|
* improve the reliability of a data retrieval.
|
|
3676
3221
|
*/
|
|
3677
3222
|
|
|
3678
|
-
function _catch$
|
|
3223
|
+
function _catch$6(body, recover) {
|
|
3679
3224
|
try {
|
|
3680
3225
|
var result = body();
|
|
3681
3226
|
} catch (e) {
|
|
@@ -3686,21 +3231,21 @@ function _catch$4(body, recover) {
|
|
|
3686
3231
|
}
|
|
3687
3232
|
return result;
|
|
3688
3233
|
}
|
|
3689
|
-
function _settle$
|
|
3234
|
+
function _settle$2(pact, state, value) {
|
|
3690
3235
|
if (!pact.s) {
|
|
3691
|
-
if (value instanceof _Pact$
|
|
3236
|
+
if (value instanceof _Pact$2) {
|
|
3692
3237
|
if (value.s) {
|
|
3693
3238
|
if (state & 1) {
|
|
3694
3239
|
state = value.s;
|
|
3695
3240
|
}
|
|
3696
3241
|
value = value.v;
|
|
3697
3242
|
} else {
|
|
3698
|
-
value.o = _settle$
|
|
3243
|
+
value.o = _settle$2.bind(null, pact, state);
|
|
3699
3244
|
return;
|
|
3700
3245
|
}
|
|
3701
3246
|
}
|
|
3702
3247
|
if (value && value.then) {
|
|
3703
|
-
value.then(_settle$
|
|
3248
|
+
value.then(_settle$2.bind(null, pact, state), _settle$2.bind(null, pact, 2));
|
|
3704
3249
|
return;
|
|
3705
3250
|
}
|
|
3706
3251
|
pact.s = state;
|
|
@@ -3711,7 +3256,7 @@ function _settle$1(pact, state, value) {
|
|
|
3711
3256
|
}
|
|
3712
3257
|
}
|
|
3713
3258
|
}
|
|
3714
|
-
var _Pact$
|
|
3259
|
+
var _Pact$2 = /*#__PURE__*/function () {
|
|
3715
3260
|
function _Pact() {}
|
|
3716
3261
|
_Pact.prototype.then = function (onFulfilled, onRejected) {
|
|
3717
3262
|
var result = new _Pact();
|
|
@@ -3720,9 +3265,9 @@ var _Pact$1 = /*#__PURE__*/function () {
|
|
|
3720
3265
|
var callback = state & 1 ? onFulfilled : onRejected;
|
|
3721
3266
|
if (callback) {
|
|
3722
3267
|
try {
|
|
3723
|
-
_settle$
|
|
3268
|
+
_settle$2(result, 1, callback(this.v));
|
|
3724
3269
|
} catch (e) {
|
|
3725
|
-
_settle$
|
|
3270
|
+
_settle$2(result, 2, e);
|
|
3726
3271
|
}
|
|
3727
3272
|
return result;
|
|
3728
3273
|
} else {
|
|
@@ -3733,28 +3278,28 @@ var _Pact$1 = /*#__PURE__*/function () {
|
|
|
3733
3278
|
try {
|
|
3734
3279
|
var value = _this.v;
|
|
3735
3280
|
if (_this.s & 1) {
|
|
3736
|
-
_settle$
|
|
3281
|
+
_settle$2(result, 1, onFulfilled ? onFulfilled(value) : value);
|
|
3737
3282
|
} else if (onRejected) {
|
|
3738
|
-
_settle$
|
|
3283
|
+
_settle$2(result, 1, onRejected(value));
|
|
3739
3284
|
} else {
|
|
3740
|
-
_settle$
|
|
3285
|
+
_settle$2(result, 2, value);
|
|
3741
3286
|
}
|
|
3742
3287
|
} catch (e) {
|
|
3743
|
-
_settle$
|
|
3288
|
+
_settle$2(result, 2, e);
|
|
3744
3289
|
}
|
|
3745
3290
|
};
|
|
3746
3291
|
return result;
|
|
3747
3292
|
};
|
|
3748
3293
|
return _Pact;
|
|
3749
3294
|
}();
|
|
3750
|
-
function _isSettledPact$
|
|
3751
|
-
return thenable instanceof _Pact$
|
|
3752
|
-
}
|
|
3753
|
-
function _for(test, update, body) {
|
|
3295
|
+
function _isSettledPact$2(thenable) {
|
|
3296
|
+
return thenable instanceof _Pact$2 && thenable.s & 1;
|
|
3297
|
+
}
|
|
3298
|
+
function _for$1(test, update, body) {
|
|
3754
3299
|
var stage;
|
|
3755
3300
|
for (;;) {
|
|
3756
3301
|
var shouldContinue = test();
|
|
3757
|
-
if (_isSettledPact$
|
|
3302
|
+
if (_isSettledPact$2(shouldContinue)) {
|
|
3758
3303
|
shouldContinue = shouldContinue.v;
|
|
3759
3304
|
}
|
|
3760
3305
|
if (!shouldContinue) {
|
|
@@ -3766,7 +3311,7 @@ function _for(test, update, body) {
|
|
|
3766
3311
|
}
|
|
3767
3312
|
var result = body();
|
|
3768
3313
|
if (result && result.then) {
|
|
3769
|
-
if (_isSettledPact$
|
|
3314
|
+
if (_isSettledPact$2(result)) {
|
|
3770
3315
|
result = result.s;
|
|
3771
3316
|
} else {
|
|
3772
3317
|
stage = 1;
|
|
@@ -3775,14 +3320,14 @@ function _for(test, update, body) {
|
|
|
3775
3320
|
}
|
|
3776
3321
|
if (update) {
|
|
3777
3322
|
var updateValue = update();
|
|
3778
|
-
if (updateValue && updateValue.then && !_isSettledPact$
|
|
3323
|
+
if (updateValue && updateValue.then && !_isSettledPact$2(updateValue)) {
|
|
3779
3324
|
stage = 2;
|
|
3780
3325
|
break;
|
|
3781
3326
|
}
|
|
3782
3327
|
}
|
|
3783
3328
|
}
|
|
3784
|
-
var pact = new _Pact$
|
|
3785
|
-
var reject = _settle$
|
|
3329
|
+
var pact = new _Pact$2();
|
|
3330
|
+
var reject = _settle$2.bind(null, pact, 2);
|
|
3786
3331
|
(stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject);
|
|
3787
3332
|
return pact;
|
|
3788
3333
|
function _resumeAfterBody(value) {
|
|
@@ -3790,14 +3335,14 @@ function _for(test, update, body) {
|
|
|
3790
3335
|
do {
|
|
3791
3336
|
if (update) {
|
|
3792
3337
|
updateValue = update();
|
|
3793
|
-
if (updateValue && updateValue.then && !_isSettledPact$
|
|
3338
|
+
if (updateValue && updateValue.then && !_isSettledPact$2(updateValue)) {
|
|
3794
3339
|
updateValue.then(_resumeAfterUpdate).then(void 0, reject);
|
|
3795
3340
|
return;
|
|
3796
3341
|
}
|
|
3797
3342
|
}
|
|
3798
3343
|
shouldContinue = test();
|
|
3799
|
-
if (!shouldContinue || _isSettledPact$
|
|
3800
|
-
_settle$
|
|
3344
|
+
if (!shouldContinue || _isSettledPact$2(shouldContinue) && !shouldContinue.v) {
|
|
3345
|
+
_settle$2(pact, 1, result);
|
|
3801
3346
|
return;
|
|
3802
3347
|
}
|
|
3803
3348
|
if (shouldContinue.then) {
|
|
@@ -3805,7 +3350,7 @@ function _for(test, update, body) {
|
|
|
3805
3350
|
return;
|
|
3806
3351
|
}
|
|
3807
3352
|
result = body();
|
|
3808
|
-
if (_isSettledPact$
|
|
3353
|
+
if (_isSettledPact$2(result)) {
|
|
3809
3354
|
result = result.v;
|
|
3810
3355
|
}
|
|
3811
3356
|
} while (!result || !result.then);
|
|
@@ -3820,7 +3365,7 @@ function _for(test, update, body) {
|
|
|
3820
3365
|
_resumeAfterBody(result);
|
|
3821
3366
|
}
|
|
3822
3367
|
} else {
|
|
3823
|
-
_settle$
|
|
3368
|
+
_settle$2(pact, 1, result);
|
|
3824
3369
|
}
|
|
3825
3370
|
}
|
|
3826
3371
|
function _resumeAfterUpdate() {
|
|
@@ -3831,7 +3376,7 @@ function _for(test, update, body) {
|
|
|
3831
3376
|
_resumeAfterTest(shouldContinue);
|
|
3832
3377
|
}
|
|
3833
3378
|
} else {
|
|
3834
|
-
_settle$
|
|
3379
|
+
_settle$2(pact, 1, result);
|
|
3835
3380
|
}
|
|
3836
3381
|
}
|
|
3837
3382
|
}
|
|
@@ -3851,7 +3396,7 @@ function _do(body, test) {
|
|
|
3851
3396
|
do {
|
|
3852
3397
|
var result = body();
|
|
3853
3398
|
if (result && result.then) {
|
|
3854
|
-
if (_isSettledPact$
|
|
3399
|
+
if (_isSettledPact$2(result)) {
|
|
3855
3400
|
result = result.v;
|
|
3856
3401
|
} else {
|
|
3857
3402
|
awaitBody = true;
|
|
@@ -3859,22 +3404,22 @@ function _do(body, test) {
|
|
|
3859
3404
|
}
|
|
3860
3405
|
}
|
|
3861
3406
|
var shouldContinue = test();
|
|
3862
|
-
if (_isSettledPact$
|
|
3407
|
+
if (_isSettledPact$2(shouldContinue)) {
|
|
3863
3408
|
shouldContinue = shouldContinue.v;
|
|
3864
3409
|
}
|
|
3865
3410
|
if (!shouldContinue) {
|
|
3866
3411
|
return result;
|
|
3867
3412
|
}
|
|
3868
3413
|
} while (!shouldContinue.then);
|
|
3869
|
-
var pact = new _Pact$
|
|
3870
|
-
var reject = _settle$
|
|
3414
|
+
var pact = new _Pact$2();
|
|
3415
|
+
var reject = _settle$2.bind(null, pact, 2);
|
|
3871
3416
|
(awaitBody ? result.then(_resumeAfterBody) : shouldContinue.then(_resumeAfterTest)).then(void 0, reject);
|
|
3872
3417
|
return pact;
|
|
3873
3418
|
function _resumeAfterBody(value) {
|
|
3874
3419
|
result = value;
|
|
3875
3420
|
for (;;) {
|
|
3876
3421
|
shouldContinue = test();
|
|
3877
|
-
if (_isSettledPact$
|
|
3422
|
+
if (_isSettledPact$2(shouldContinue)) {
|
|
3878
3423
|
shouldContinue = shouldContinue.v;
|
|
3879
3424
|
}
|
|
3880
3425
|
if (!shouldContinue) {
|
|
@@ -3886,7 +3431,7 @@ function _do(body, test) {
|
|
|
3886
3431
|
}
|
|
3887
3432
|
result = body();
|
|
3888
3433
|
if (result && result.then) {
|
|
3889
|
-
if (_isSettledPact$
|
|
3434
|
+
if (_isSettledPact$2(result)) {
|
|
3890
3435
|
result = result.v;
|
|
3891
3436
|
} else {
|
|
3892
3437
|
result.then(_resumeAfterBody).then(void 0, reject);
|
|
@@ -3894,14 +3439,14 @@ function _do(body, test) {
|
|
|
3894
3439
|
}
|
|
3895
3440
|
}
|
|
3896
3441
|
}
|
|
3897
|
-
_settle$
|
|
3442
|
+
_settle$2(pact, 1, result);
|
|
3898
3443
|
}
|
|
3899
3444
|
function _resumeAfterTest(shouldContinue) {
|
|
3900
3445
|
if (shouldContinue) {
|
|
3901
3446
|
do {
|
|
3902
3447
|
result = body();
|
|
3903
3448
|
if (result && result.then) {
|
|
3904
|
-
if (_isSettledPact$
|
|
3449
|
+
if (_isSettledPact$2(result)) {
|
|
3905
3450
|
result = result.v;
|
|
3906
3451
|
} else {
|
|
3907
3452
|
result.then(_resumeAfterBody).then(void 0, reject);
|
|
@@ -3909,381 +3454,1069 @@ function _do(body, test) {
|
|
|
3909
3454
|
}
|
|
3910
3455
|
}
|
|
3911
3456
|
shouldContinue = test();
|
|
3912
|
-
if (_isSettledPact$
|
|
3457
|
+
if (_isSettledPact$2(shouldContinue)) {
|
|
3913
3458
|
shouldContinue = shouldContinue.v;
|
|
3914
3459
|
}
|
|
3915
3460
|
if (!shouldContinue) {
|
|
3916
|
-
_settle$
|
|
3461
|
+
_settle$2(pact, 1, result);
|
|
3917
3462
|
return;
|
|
3918
3463
|
}
|
|
3919
3464
|
} while (!shouldContinue.then);
|
|
3920
3465
|
shouldContinue.then(_resumeAfterTest).then(void 0, reject);
|
|
3921
3466
|
} else {
|
|
3922
|
-
_settle$
|
|
3467
|
+
_settle$2(pact, 1, result);
|
|
3468
|
+
}
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
function _forTo$1(array, body, check) {
|
|
3472
|
+
var i = -1,
|
|
3473
|
+
pact,
|
|
3474
|
+
reject;
|
|
3475
|
+
function _cycle(result) {
|
|
3476
|
+
try {
|
|
3477
|
+
while (++i < array.length && (!check || !check())) {
|
|
3478
|
+
result = body(i);
|
|
3479
|
+
if (result && result.then) {
|
|
3480
|
+
if (_isSettledPact$2(result)) {
|
|
3481
|
+
result = result.v;
|
|
3482
|
+
} else {
|
|
3483
|
+
result.then(_cycle, reject || (reject = _settle$2.bind(null, pact = new _Pact$2(), 2)));
|
|
3484
|
+
return;
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
if (pact) {
|
|
3489
|
+
_settle$2(pact, 1, result);
|
|
3490
|
+
} else {
|
|
3491
|
+
pact = result;
|
|
3492
|
+
}
|
|
3493
|
+
} catch (e) {
|
|
3494
|
+
_settle$2(pact || (pact = new _Pact$2()), 2, e);
|
|
3495
|
+
}
|
|
3496
|
+
}
|
|
3497
|
+
_cycle();
|
|
3498
|
+
return pact;
|
|
3499
|
+
}
|
|
3500
|
+
var RobustExternalAPICallerService = /*#__PURE__*/function () {
|
|
3501
|
+
RobustExternalAPICallerService.getStats = function getStats() {
|
|
3502
|
+
return this.statsCollector.getStats();
|
|
3503
|
+
}
|
|
3504
|
+
|
|
3505
|
+
/**
|
|
3506
|
+
* @param bio {string} service name for logging
|
|
3507
|
+
* @param providersData {ExternalApiProvider[]} array of providers
|
|
3508
|
+
* @param [logger] {function} function to be used for logging
|
|
3509
|
+
*/;
|
|
3510
|
+
function RobustExternalAPICallerService(bio, providersData, logger) {
|
|
3511
|
+
providersData.forEach(function (provider) {
|
|
3512
|
+
if (!provider.endpoint && provider.endpoint !== "" || !provider.httpMethod) {
|
|
3513
|
+
throw new Error("Wrong format of providers data for: " + JSON.stringify(provider));
|
|
3514
|
+
}
|
|
3515
|
+
});
|
|
3516
|
+
|
|
3517
|
+
// We add niceFactor - just number to order the providers array by. It is helpful to call
|
|
3518
|
+
// less robust APIs only if more robust fails
|
|
3519
|
+
this.providers = providersData;
|
|
3520
|
+
providersData.forEach(function (provider) {
|
|
3521
|
+
return provider.resetNiceFactor();
|
|
3522
|
+
});
|
|
3523
|
+
this.bio = bio;
|
|
3524
|
+
this._logger = Logger.logError;
|
|
3525
|
+
}
|
|
3526
|
+
var _proto = RobustExternalAPICallerService.prototype;
|
|
3527
|
+
/**
|
|
3528
|
+
* Performs data retrieval from external APIs. Tries providers till the data is retrieved.
|
|
3529
|
+
*
|
|
3530
|
+
* @param parametersValues {array} array of values of the parameters for URL query string [and/or body]
|
|
3531
|
+
* @param timeoutMS {number} http timeout to wait for response. If provider has its specific timeout value then it is used
|
|
3532
|
+
* @param [cancelToken] {object|undefined} axios token to force-cancel requests from high-level code
|
|
3533
|
+
* @param [attemptsCount] {number|undefined} number of attempts to be performed
|
|
3534
|
+
* @param [doNotFailForNowData] {boolean|undefined} pass true if you do not want us to throw an error if we retrieved null data from all the providers
|
|
3535
|
+
* @return {Promise<any>} resolving to retrieved data (or array of results if specific provider requires
|
|
3536
|
+
* several requests. NOTE: we flatten nested arrays - results of each separate request done for the specific provider)
|
|
3537
|
+
* @throws Error if requests to all providers are failed
|
|
3538
|
+
*/
|
|
3539
|
+
_proto.callExternalAPI = function callExternalAPI(parametersValues, timeoutMS, cancelToken, attemptsCount, doNotFailForNowData) {
|
|
3540
|
+
if (parametersValues === void 0) {
|
|
3541
|
+
parametersValues = [];
|
|
3542
|
+
}
|
|
3543
|
+
if (timeoutMS === void 0) {
|
|
3544
|
+
timeoutMS = 3500;
|
|
3545
|
+
}
|
|
3546
|
+
if (cancelToken === void 0) {
|
|
3547
|
+
cancelToken = null;
|
|
3548
|
+
}
|
|
3549
|
+
if (attemptsCount === void 0) {
|
|
3550
|
+
attemptsCount = 1;
|
|
3551
|
+
}
|
|
3552
|
+
if (doNotFailForNowData === void 0) {
|
|
3553
|
+
doNotFailForNowData = false;
|
|
3554
|
+
}
|
|
3555
|
+
try {
|
|
3556
|
+
var _this = this;
|
|
3557
|
+
var result;
|
|
3558
|
+
var calculationUuid = concurrentCalculationsMetadataHolder.startCalculation(_this.bio);
|
|
3559
|
+
return Promise.resolve(_finallyRethrows$1(function () {
|
|
3560
|
+
return _catch$6(function () {
|
|
3561
|
+
function _temp5() {
|
|
3562
|
+
var _result2, _result3;
|
|
3563
|
+
if (((_result2 = result) == null ? void 0 : _result2.data) == null) {
|
|
3564
|
+
// TODO: [feature, moderate] looks like we should not fail for null data as it is strange - the provider will fail when processing data internally
|
|
3565
|
+
var error = new Error("Failed to retrieve data. It means all attempts have been failed. DEV: add more attempts to this data retrieval");
|
|
3566
|
+
if (!doNotFailForNowData) {
|
|
3567
|
+
throw error;
|
|
3568
|
+
} else {
|
|
3569
|
+
_this._logger(error, _this.bio + ".callExternalAPI");
|
|
3570
|
+
}
|
|
3571
|
+
}
|
|
3572
|
+
return (_result3 = result) == null ? void 0 : _result3.data;
|
|
3573
|
+
}
|
|
3574
|
+
var i = 0;
|
|
3575
|
+
var _temp4 = _for$1(function () {
|
|
3576
|
+
var _result4, _result5;
|
|
3577
|
+
return (i < attemptsCount || !!((_result4 = result) != null && _result4.shouldBeForceRetried)) && ((_result5 = result) == null ? void 0 : _result5.data) == null;
|
|
3578
|
+
}, function () {
|
|
3579
|
+
return ++i;
|
|
3580
|
+
}, function () {
|
|
3581
|
+
/**
|
|
3582
|
+
* We use rpsFactor to improve re-attempting to call the providers if the last attempt resulted with
|
|
3583
|
+
* the fail due to abused RPSes of some (most part of) providers.
|
|
3584
|
+
* The _performCallAttempt in such a case will return increased rpsFactor inside the result object.
|
|
3585
|
+
*/
|
|
3586
|
+
var rpsFactor = result ? result.rpsFactor : RobustExternalAPICallerService.defaultRPSFactor;
|
|
3587
|
+
result = null;
|
|
3588
|
+
var _temp3 = _catch$6(function () {
|
|
3589
|
+
function _temp2() {
|
|
3590
|
+
var _result$errors;
|
|
3591
|
+
if ((_result$errors = result.errors) != null && _result$errors.length) {
|
|
3592
|
+
var errors = result.errors;
|
|
3593
|
+
_this._logger(new Error("Failed at attempt " + i + ". " + errors.length + " errors. Messages: " + safeStringify(errors.map(function (error) {
|
|
3594
|
+
return error.message;
|
|
3595
|
+
})) + ": " + safeStringify(errors) + "."), _this.bio + ".callExternalAPI", "", true);
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
var _temp = function (_result6) {
|
|
3599
|
+
if (i === 0 && !((_result6 = result) != null && _result6.shouldBeForceRetried)) {
|
|
3600
|
+
return Promise.resolve(_this._performCallAttempt(parametersValues, timeoutMS, cancelToken, rpsFactor, doNotFailForNowData)).then(function (_this$_performCallAtt) {
|
|
3601
|
+
result = _this$_performCallAtt;
|
|
3602
|
+
});
|
|
3603
|
+
} else {
|
|
3604
|
+
var maxRps = Math.max.apply(Math, _this.providers.map(function (provider) {
|
|
3605
|
+
var _provider$getRps;
|
|
3606
|
+
return (_provider$getRps = provider.getRps()) != null ? _provider$getRps : 0;
|
|
3607
|
+
}));
|
|
3608
|
+
var waitingTimeMs = maxRps ? 1000 / (maxRps / rpsFactor) : 0;
|
|
3609
|
+
return Promise.resolve(new Promise(function (resolve, reject) {
|
|
3610
|
+
setTimeout(function () {
|
|
3611
|
+
try {
|
|
3612
|
+
var _temp6 = _catch$6(function () {
|
|
3613
|
+
return Promise.resolve(_this._performCallAttempt(parametersValues, timeoutMS, cancelToken, rpsFactor, doNotFailForNowData)).then(function (_this$_performCallAtt2) {
|
|
3614
|
+
resolve(_this$_performCallAtt2);
|
|
3615
|
+
});
|
|
3616
|
+
}, function (e) {
|
|
3617
|
+
reject(e);
|
|
3618
|
+
});
|
|
3619
|
+
return Promise.resolve(_temp6 && _temp6.then ? _temp6.then(function () {}) : void 0);
|
|
3620
|
+
} catch (e) {
|
|
3621
|
+
return Promise.reject(e);
|
|
3622
|
+
}
|
|
3623
|
+
}, waitingTimeMs);
|
|
3624
|
+
})).then(function (_Promise) {
|
|
3625
|
+
result = _Promise;
|
|
3626
|
+
});
|
|
3627
|
+
}
|
|
3628
|
+
}();
|
|
3629
|
+
return _temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp);
|
|
3630
|
+
}, function (e) {
|
|
3631
|
+
_this._logger(e, _this.bio + ".callExternalAPI", "Failed to perform external providers calling");
|
|
3632
|
+
});
|
|
3633
|
+
if (_temp3 && _temp3.then) return _temp3.then(function () {});
|
|
3634
|
+
});
|
|
3635
|
+
return _temp4 && _temp4.then ? _temp4.then(_temp5) : _temp5(_temp4);
|
|
3636
|
+
}, function (e) {
|
|
3637
|
+
improveAndRethrow(e, _this.bio + ".callExternalAPI");
|
|
3638
|
+
});
|
|
3639
|
+
}, function (_wasThrown, _result) {
|
|
3640
|
+
concurrentCalculationsMetadataHolder.endCalculation(_this.bio, calculationUuid);
|
|
3641
|
+
if (_wasThrown) throw _result;
|
|
3642
|
+
return _result;
|
|
3643
|
+
}));
|
|
3644
|
+
} catch (e) {
|
|
3645
|
+
return Promise.reject(e);
|
|
3646
|
+
}
|
|
3647
|
+
};
|
|
3648
|
+
_proto._performCallAttempt = function _performCallAttempt(parametersValues, timeoutMS, cancelToken, rpsFactor, doNotFailForNowData) {
|
|
3649
|
+
try {
|
|
3650
|
+
var _temp15 = function _temp15() {
|
|
3651
|
+
var _data;
|
|
3652
|
+
// If we are declining more than 50% of providers (by exceeding RPS) then we note that it better to retry the whole process of providers requesting
|
|
3653
|
+
var shouldBeForceRetried = data == null && countOfRequestsDeclinedByRps > Math.floor(providers.length * 0.5);
|
|
3654
|
+
var rpsMultiplier = shouldBeForceRetried ? RobustExternalAPICallerService.rpsMultiplier : 1;
|
|
3655
|
+
return {
|
|
3656
|
+
data: (_data = data) != null ? _data : null,
|
|
3657
|
+
shouldBeForceRetried: shouldBeForceRetried,
|
|
3658
|
+
rpsFactor: rpsFactor * rpsMultiplier,
|
|
3659
|
+
errors: errors
|
|
3660
|
+
};
|
|
3661
|
+
};
|
|
3662
|
+
var _this2 = this;
|
|
3663
|
+
var providers = _this2._reorderProvidersByNiceFactor();
|
|
3664
|
+
var data = undefined,
|
|
3665
|
+
providerIndex = 0,
|
|
3666
|
+
countOfRequestsDeclinedByRps = 0,
|
|
3667
|
+
errors = [];
|
|
3668
|
+
var _temp14 = _for$1(function () {
|
|
3669
|
+
return !data && providerIndex < providers.length;
|
|
3670
|
+
}, void 0, function () {
|
|
3671
|
+
var provider = providers[providerIndex];
|
|
3672
|
+
if (provider.isRpsExceeded()) {
|
|
3673
|
+
/**
|
|
3674
|
+
* Current provider's RPS is exceeded, so we try next provider. Also, we count such cases to make
|
|
3675
|
+
* a decision about the force-retry need.
|
|
3676
|
+
*/
|
|
3677
|
+
++providerIndex;
|
|
3678
|
+
++countOfRequestsDeclinedByRps;
|
|
3679
|
+
return;
|
|
3680
|
+
}
|
|
3681
|
+
var _temp13 = _finallyRethrows$1(function () {
|
|
3682
|
+
return _catch$6(function () {
|
|
3683
|
+
var _provider$specificHea;
|
|
3684
|
+
function _temp12() {
|
|
3685
|
+
if (iterationsData.length) {
|
|
3686
|
+
if (httpMethods.length > 1) {
|
|
3687
|
+
data = provider.incorporateIterationsData(iterationsData);
|
|
3688
|
+
} else {
|
|
3689
|
+
data = iterationsData[0];
|
|
3690
|
+
}
|
|
3691
|
+
} else if (!doNotFailForNowData) {
|
|
3692
|
+
RobustExternalAPICallerService.statsCollector.externalServiceFailed(provider.getApiGroupId(), "Response data was null for some reason");
|
|
3693
|
+
punishProvider(provider);
|
|
3694
|
+
}
|
|
3695
|
+
}
|
|
3696
|
+
var axiosConfig = _extends({}, cancelToken ? {
|
|
3697
|
+
cancelToken: cancelToken
|
|
3698
|
+
} : {}, {
|
|
3699
|
+
timeout: provider.timeout || timeoutMS,
|
|
3700
|
+
headers: (_provider$specificHea = provider.specificHeaders) != null ? _provider$specificHea : {}
|
|
3701
|
+
});
|
|
3702
|
+
var httpMethods = Array.isArray(provider.httpMethod) ? provider.httpMethod : [provider.httpMethod];
|
|
3703
|
+
var iterationsData = [];
|
|
3704
|
+
var _temp11 = _forTo$1(httpMethods, function (subRequestIndex) {
|
|
3705
|
+
function _temp10() {
|
|
3706
|
+
var responsesDataForPages = responsesForPages.map(function (response) {
|
|
3707
|
+
return provider.getDataByResponse(response, parametersValues, subRequestIndex, iterationsData);
|
|
3708
|
+
});
|
|
3709
|
+
var allData = responsesDataForPages;
|
|
3710
|
+
if (Array.isArray(responsesDataForPages[0])) {
|
|
3711
|
+
allData = responsesDataForPages.flat();
|
|
3712
|
+
} else if (responsesDataForPages.length === 1) {
|
|
3713
|
+
allData = responsesDataForPages[0];
|
|
3714
|
+
}
|
|
3715
|
+
iterationsData.push(allData);
|
|
3716
|
+
}
|
|
3717
|
+
var query = provider.composeQueryString(parametersValues, subRequestIndex);
|
|
3718
|
+
var endpoint = "" + provider.endpoint + query;
|
|
3719
|
+
var axiosParams = [endpoint, axiosConfig];
|
|
3720
|
+
if (["post", "put", "patch"].find(function (method) {
|
|
3721
|
+
return method === httpMethods[subRequestIndex];
|
|
3722
|
+
})) {
|
|
3723
|
+
var _provider$composeBody;
|
|
3724
|
+
var body = (_provider$composeBody = provider.composeBody(parametersValues, subRequestIndex)) != null ? _provider$composeBody : null;
|
|
3725
|
+
axiosParams.splice(1, 0, body);
|
|
3726
|
+
}
|
|
3727
|
+
var pageNumber = 0;
|
|
3728
|
+
var responsesForPages = [];
|
|
3729
|
+
var hasNextPage = provider.doesSupportPagination();
|
|
3730
|
+
var _temp9 = _do(function () {
|
|
3731
|
+
function _temp8() {
|
|
3732
|
+
if (hasNextPage) {
|
|
3733
|
+
hasNextPage = !provider.checkWhetherResponseIsForLastPage(responsesForPages[pageNumber - 1], responsesForPages[pageNumber], pageNumber, subRequestIndex);
|
|
3734
|
+
}
|
|
3735
|
+
pageNumber++;
|
|
3736
|
+
}
|
|
3737
|
+
var _temp7 = function () {
|
|
3738
|
+
if (subRequestIndex === 0 && pageNumber === 0) {
|
|
3739
|
+
provider.actualizeLastCalledTimestamp();
|
|
3740
|
+
return Promise.resolve(AxiosAdapter.call.apply(AxiosAdapter, [httpMethods[subRequestIndex]].concat(axiosParams))).then(function (_AxiosAdapter$call) {
|
|
3741
|
+
responsesForPages[pageNumber] = _AxiosAdapter$call;
|
|
3742
|
+
RobustExternalAPICallerService.statsCollector.externalServiceCalledWithoutError(provider.getApiGroupId());
|
|
3743
|
+
});
|
|
3744
|
+
} else {
|
|
3745
|
+
if (pageNumber > 0) {
|
|
3746
|
+
var actualizedParams = provider.changeQueryParametersForPageNumber(parametersValues, responsesForPages[pageNumber - 1], pageNumber, subRequestIndex);
|
|
3747
|
+
var _query = provider.composeQueryString(actualizedParams, subRequestIndex);
|
|
3748
|
+
axiosParams[0] = "" + provider.endpoint + _query;
|
|
3749
|
+
}
|
|
3750
|
+
/**
|
|
3751
|
+
* For second and more request we postpone each request to not exceed RPS
|
|
3752
|
+
* of current provider. We use rpsFactor to dynamically increase the rps to avoid
|
|
3753
|
+
* too frequent calls if we continue failing to retrieve the data due to RPS exceeding.
|
|
3754
|
+
* TODO: [dev] test RPS factor logic (units or integration)
|
|
3755
|
+
*/
|
|
3756
|
+
|
|
3757
|
+
var waitingTimeMS = provider.getRps() ? 1000 / (provider.getRps() / rpsFactor) : 0;
|
|
3758
|
+
var postponeUntilRpsExceeded = function postponeUntilRpsExceeded(recursionLevel) {
|
|
3759
|
+
if (recursionLevel === void 0) {
|
|
3760
|
+
recursionLevel = 0;
|
|
3761
|
+
}
|
|
3762
|
+
try {
|
|
3763
|
+
return Promise.resolve(postponeExecution(function () {
|
|
3764
|
+
try {
|
|
3765
|
+
var _temp17 = function _temp17(_result8) {
|
|
3766
|
+
if (_exit) return _result8;
|
|
3767
|
+
provider.actualizeLastCalledTimestamp();
|
|
3768
|
+
return Promise.resolve(AxiosAdapter.call.apply(AxiosAdapter, [httpMethods[subRequestIndex]].concat(axiosParams)));
|
|
3769
|
+
};
|
|
3770
|
+
var _exit;
|
|
3771
|
+
var maxCountOfPostponingAttempts = 2;
|
|
3772
|
+
var _temp16 = function () {
|
|
3773
|
+
if (provider.isRpsExceeded() && recursionLevel < maxCountOfPostponingAttempts) {
|
|
3774
|
+
return Promise.resolve(postponeUntilRpsExceeded(recursionLevel + 1)).then(function (_await$postponeUntilR) {
|
|
3775
|
+
_exit = 1;
|
|
3776
|
+
return _await$postponeUntilR;
|
|
3777
|
+
});
|
|
3778
|
+
}
|
|
3779
|
+
}();
|
|
3780
|
+
return Promise.resolve(_temp16 && _temp16.then ? _temp16.then(_temp17) : _temp17(_temp16));
|
|
3781
|
+
} catch (e) {
|
|
3782
|
+
return Promise.reject(e);
|
|
3783
|
+
}
|
|
3784
|
+
}, waitingTimeMS));
|
|
3785
|
+
} catch (e) {
|
|
3786
|
+
return Promise.reject(e);
|
|
3787
|
+
}
|
|
3788
|
+
};
|
|
3789
|
+
return Promise.resolve(postponeUntilRpsExceeded()).then(function (_postponeUntilRpsExce) {
|
|
3790
|
+
responsesForPages[pageNumber] = _postponeUntilRpsExce;
|
|
3791
|
+
});
|
|
3792
|
+
}
|
|
3793
|
+
}();
|
|
3794
|
+
return _temp7 && _temp7.then ? _temp7.then(_temp8) : _temp8(_temp7);
|
|
3795
|
+
}, function () {
|
|
3796
|
+
return !!hasNextPage;
|
|
3797
|
+
});
|
|
3798
|
+
return _temp9 && _temp9.then ? _temp9.then(_temp10) : _temp10(_temp9);
|
|
3799
|
+
});
|
|
3800
|
+
return _temp11 && _temp11.then ? _temp11.then(_temp12) : _temp12(_temp11);
|
|
3801
|
+
}, function (e) {
|
|
3802
|
+
punishProvider(provider);
|
|
3803
|
+
RobustExternalAPICallerService.statsCollector.externalServiceFailed(provider.getApiGroupId(), e == null ? void 0 : e.message);
|
|
3804
|
+
errors.push(e);
|
|
3805
|
+
});
|
|
3806
|
+
}, function (_wasThrown2, _result7) {
|
|
3807
|
+
providerIndex++;
|
|
3808
|
+
if (_wasThrown2) throw _result7;
|
|
3809
|
+
return _result7;
|
|
3810
|
+
});
|
|
3811
|
+
if (_temp13 && _temp13.then) return _temp13.then(function () {});
|
|
3812
|
+
});
|
|
3813
|
+
return Promise.resolve(_temp14 && _temp14.then ? _temp14.then(_temp15) : _temp15(_temp14));
|
|
3814
|
+
} catch (e) {
|
|
3815
|
+
return Promise.reject(e);
|
|
3816
|
+
}
|
|
3817
|
+
};
|
|
3818
|
+
_proto._reorderProvidersByNiceFactor = function _reorderProvidersByNiceFactor() {
|
|
3819
|
+
var providersCopy = [].concat(this.providers);
|
|
3820
|
+
return providersCopy.sort(function (p1, p2) {
|
|
3821
|
+
return p2.niceFactor - p1.niceFactor;
|
|
3822
|
+
});
|
|
3823
|
+
};
|
|
3824
|
+
return RobustExternalAPICallerService;
|
|
3825
|
+
}();
|
|
3826
|
+
RobustExternalAPICallerService.statsCollector = new ExternalServicesStatsCollector();
|
|
3827
|
+
RobustExternalAPICallerService.defaultRPSFactor = 1;
|
|
3828
|
+
RobustExternalAPICallerService.rpsMultiplier = 1.05;
|
|
3829
|
+
function punishProvider(provider) {
|
|
3830
|
+
provider.niceFactor = provider.niceFactor - 1;
|
|
3831
|
+
}
|
|
3832
|
+
|
|
3833
|
+
/**
|
|
3834
|
+
* This util helps to avoid duplicated calls to a shared resource.
|
|
3835
|
+
* It tracks is there currently active calculation for the specific cache id and make all other requests
|
|
3836
|
+
* with the same cache id waiting for this active calculation to be finished. When the calculation ends
|
|
3837
|
+
* the resolver allows all the waiting requesters to get the data from cache and start their own calculations.
|
|
3838
|
+
*
|
|
3839
|
+
* This class should be instantiated inside some other service where you need to request some resource concurrently.
|
|
3840
|
+
* Rules:
|
|
3841
|
+
* 1. When you need to make a request inside your main service call 'getCachedOrWaitForCachedOrAcquireLock'
|
|
3842
|
+
* on the instance of this class and await for the result. If the flag allowing to start calculation is true
|
|
3843
|
+
* then you can request data inside your main service. Otherwise you should use the cached data as an another
|
|
3844
|
+
* requester just finished the most resent requesting and there is actual data in the cache that
|
|
3845
|
+
* is returned to you here.
|
|
3846
|
+
* 1.1 Also you can acquire a lock directly if you don't want to get cached data. Use the corresponding method 'acquireLock'.
|
|
3847
|
+
*
|
|
3848
|
+
* 2. If you start requesting (when you successfully acquired the lock) then after receiving the result of your
|
|
3849
|
+
* requesting you should call the 'saveCachedData' so the retrieved data will appear in the cache.
|
|
3850
|
+
*
|
|
3851
|
+
* 3. If you successfully acquired the lock then you should after calling the 'saveCachedData' call
|
|
3852
|
+
* the 'releaseLock' - this is mandatory to release the lock and allow other requesters to perform their requests.
|
|
3853
|
+
* WARNING: If for any reason you forget to call this method then this class instance will wait perpetually for
|
|
3854
|
+
* the lock releasing and all your attempts to request the data will constantly fail. So usually call it
|
|
3855
|
+
* inside the 'finally' block.
|
|
3856
|
+
*
|
|
3857
|
+
* TODO: [tests, critical++] add unit tests - massively used logic and can produce sophisticated concurrency bugs
|
|
3858
|
+
*/
|
|
3859
|
+
|
|
3860
|
+
function _settle$1(pact, state, value) {
|
|
3861
|
+
if (!pact.s) {
|
|
3862
|
+
if (value instanceof _Pact$1) {
|
|
3863
|
+
if (value.s) {
|
|
3864
|
+
if (state & 1) {
|
|
3865
|
+
state = value.s;
|
|
3866
|
+
}
|
|
3867
|
+
value = value.v;
|
|
3868
|
+
} else {
|
|
3869
|
+
value.o = _settle$1.bind(null, pact, state);
|
|
3870
|
+
return;
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3873
|
+
if (value && value.then) {
|
|
3874
|
+
value.then(_settle$1.bind(null, pact, state), _settle$1.bind(null, pact, 2));
|
|
3875
|
+
return;
|
|
3876
|
+
}
|
|
3877
|
+
pact.s = state;
|
|
3878
|
+
pact.v = value;
|
|
3879
|
+
const observer = pact.o;
|
|
3880
|
+
if (observer) {
|
|
3881
|
+
observer(pact);
|
|
3882
|
+
}
|
|
3883
|
+
}
|
|
3884
|
+
}
|
|
3885
|
+
|
|
3886
|
+
/**
|
|
3887
|
+
* Util class to control access to a resource when it can be called in parallel for the same result.
|
|
3888
|
+
* (E.g. getting today coins-fiat rates from some API).
|
|
3889
|
+
*/
|
|
3890
|
+
var _Pact$1 = /*#__PURE__*/function () {
|
|
3891
|
+
function _Pact() {}
|
|
3892
|
+
_Pact.prototype.then = function (onFulfilled, onRejected) {
|
|
3893
|
+
var result = new _Pact();
|
|
3894
|
+
var state = this.s;
|
|
3895
|
+
if (state) {
|
|
3896
|
+
var callback = state & 1 ? onFulfilled : onRejected;
|
|
3897
|
+
if (callback) {
|
|
3898
|
+
try {
|
|
3899
|
+
_settle$1(result, 1, callback(this.v));
|
|
3900
|
+
} catch (e) {
|
|
3901
|
+
_settle$1(result, 2, e);
|
|
3902
|
+
}
|
|
3903
|
+
return result;
|
|
3904
|
+
} else {
|
|
3905
|
+
return this;
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
this.o = function (_this) {
|
|
3909
|
+
try {
|
|
3910
|
+
var value = _this.v;
|
|
3911
|
+
if (_this.s & 1) {
|
|
3912
|
+
_settle$1(result, 1, onFulfilled ? onFulfilled(value) : value);
|
|
3913
|
+
} else if (onRejected) {
|
|
3914
|
+
_settle$1(result, 1, onRejected(value));
|
|
3915
|
+
} else {
|
|
3916
|
+
_settle$1(result, 2, value);
|
|
3917
|
+
}
|
|
3918
|
+
} catch (e) {
|
|
3919
|
+
_settle$1(result, 2, e);
|
|
3920
|
+
}
|
|
3921
|
+
};
|
|
3922
|
+
return result;
|
|
3923
|
+
};
|
|
3924
|
+
return _Pact;
|
|
3925
|
+
}();
|
|
3926
|
+
function _isSettledPact$1(thenable) {
|
|
3927
|
+
return thenable instanceof _Pact$1 && thenable.s & 1;
|
|
3928
|
+
}
|
|
3929
|
+
function _for(test, update, body) {
|
|
3930
|
+
var stage;
|
|
3931
|
+
for (;;) {
|
|
3932
|
+
var shouldContinue = test();
|
|
3933
|
+
if (_isSettledPact$1(shouldContinue)) {
|
|
3934
|
+
shouldContinue = shouldContinue.v;
|
|
3935
|
+
}
|
|
3936
|
+
if (!shouldContinue) {
|
|
3937
|
+
return result;
|
|
3938
|
+
}
|
|
3939
|
+
if (shouldContinue.then) {
|
|
3940
|
+
stage = 0;
|
|
3941
|
+
break;
|
|
3942
|
+
}
|
|
3943
|
+
var result = body();
|
|
3944
|
+
if (result && result.then) {
|
|
3945
|
+
if (_isSettledPact$1(result)) {
|
|
3946
|
+
result = result.s;
|
|
3947
|
+
} else {
|
|
3948
|
+
stage = 1;
|
|
3949
|
+
break;
|
|
3950
|
+
}
|
|
3951
|
+
}
|
|
3952
|
+
if (update) {
|
|
3953
|
+
var updateValue = update();
|
|
3954
|
+
if (updateValue && updateValue.then && !_isSettledPact$1(updateValue)) {
|
|
3955
|
+
stage = 2;
|
|
3956
|
+
break;
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
var pact = new _Pact$1();
|
|
3961
|
+
var reject = _settle$1.bind(null, pact, 2);
|
|
3962
|
+
(stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject);
|
|
3963
|
+
return pact;
|
|
3964
|
+
function _resumeAfterBody(value) {
|
|
3965
|
+
result = value;
|
|
3966
|
+
do {
|
|
3967
|
+
if (update) {
|
|
3968
|
+
updateValue = update();
|
|
3969
|
+
if (updateValue && updateValue.then && !_isSettledPact$1(updateValue)) {
|
|
3970
|
+
updateValue.then(_resumeAfterUpdate).then(void 0, reject);
|
|
3971
|
+
return;
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
shouldContinue = test();
|
|
3975
|
+
if (!shouldContinue || _isSettledPact$1(shouldContinue) && !shouldContinue.v) {
|
|
3976
|
+
_settle$1(pact, 1, result);
|
|
3977
|
+
return;
|
|
3978
|
+
}
|
|
3979
|
+
if (shouldContinue.then) {
|
|
3980
|
+
shouldContinue.then(_resumeAfterTest).then(void 0, reject);
|
|
3981
|
+
return;
|
|
3982
|
+
}
|
|
3983
|
+
result = body();
|
|
3984
|
+
if (_isSettledPact$1(result)) {
|
|
3985
|
+
result = result.v;
|
|
3986
|
+
}
|
|
3987
|
+
} while (!result || !result.then);
|
|
3988
|
+
result.then(_resumeAfterBody).then(void 0, reject);
|
|
3989
|
+
}
|
|
3990
|
+
function _resumeAfterTest(shouldContinue) {
|
|
3991
|
+
if (shouldContinue) {
|
|
3992
|
+
result = body();
|
|
3993
|
+
if (result && result.then) {
|
|
3994
|
+
result.then(_resumeAfterBody).then(void 0, reject);
|
|
3995
|
+
} else {
|
|
3996
|
+
_resumeAfterBody(result);
|
|
3997
|
+
}
|
|
3998
|
+
} else {
|
|
3999
|
+
_settle$1(pact, 1, result);
|
|
4000
|
+
}
|
|
4001
|
+
}
|
|
4002
|
+
function _resumeAfterUpdate() {
|
|
4003
|
+
if (shouldContinue = test()) {
|
|
4004
|
+
if (shouldContinue.then) {
|
|
4005
|
+
shouldContinue.then(_resumeAfterTest).then(void 0, reject);
|
|
4006
|
+
} else {
|
|
4007
|
+
_resumeAfterTest(shouldContinue);
|
|
4008
|
+
}
|
|
4009
|
+
} else {
|
|
4010
|
+
_settle$1(pact, 1, result);
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
}
|
|
4014
|
+
function _catch$5(body, recover) {
|
|
4015
|
+
try {
|
|
4016
|
+
var result = body();
|
|
4017
|
+
} catch (e) {
|
|
4018
|
+
return recover(e);
|
|
4019
|
+
}
|
|
4020
|
+
if (result && result.then) {
|
|
4021
|
+
return result.then(void 0, recover);
|
|
4022
|
+
}
|
|
4023
|
+
return result;
|
|
4024
|
+
}
|
|
4025
|
+
var CacheAndConcurrentRequestsResolver = /*#__PURE__*/function () {
|
|
4026
|
+
/**
|
|
4027
|
+
* @param bio {string} unique identifier for the exact service
|
|
4028
|
+
* @param cache {Cache} cache
|
|
4029
|
+
* @param cacheTtl {number|null} time to live for cache ms. 0 or null means the cache cannot expire
|
|
4030
|
+
* @param [maxCallAttemptsToWaitForAlreadyRunningRequest=100] {number} number of request allowed to do waiting for
|
|
4031
|
+
* result before we fail the original request. Use custom value only if you need to make the attempts count
|
|
4032
|
+
* and polling interval changes.
|
|
4033
|
+
* @param [timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished=1000] {number}
|
|
4034
|
+
* timeout ms for polling for a result. if you change maxCallAttemptsToWaitForAlreadyRunningRequest
|
|
4035
|
+
* then this parameter maybe also require the custom value.
|
|
4036
|
+
* @param [removeExpiredCacheAutomatically=true] {boolean}
|
|
4037
|
+
*/
|
|
4038
|
+
function CacheAndConcurrentRequestsResolver(bio, cache, cacheTtl, removeExpiredCacheAutomatically, maxCallAttemptsToWaitForAlreadyRunningRequest, timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished) {
|
|
4039
|
+
if (removeExpiredCacheAutomatically === void 0) {
|
|
4040
|
+
removeExpiredCacheAutomatically = true;
|
|
4041
|
+
}
|
|
4042
|
+
if (maxCallAttemptsToWaitForAlreadyRunningRequest === void 0) {
|
|
4043
|
+
maxCallAttemptsToWaitForAlreadyRunningRequest = 100;
|
|
4044
|
+
}
|
|
4045
|
+
if (timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished === void 0) {
|
|
4046
|
+
timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished = 1000;
|
|
4047
|
+
}
|
|
4048
|
+
if (cacheTtl != null && cacheTtl < timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished * 2) {
|
|
4049
|
+
/*
|
|
4050
|
+
* During the lifetime of this service e.g. if the data is being retrieved slowly we can get
|
|
4051
|
+
* RACE CONDITION when we constantly retrieve data and during retrieval it is expired, so we are trying
|
|
4052
|
+
* to retrieve it again and again.
|
|
4053
|
+
* We have a protection mechanism that we will wait no more than
|
|
4054
|
+
* maxCallAttemptsToWaitForAlreadyRunningRequest * timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished
|
|
4055
|
+
* but this additional check is aimed to reduce potential loading time for some requests.
|
|
4056
|
+
*/
|
|
4057
|
+
throw new Error("DEV: Wrong parameters passed to construct " + bio + " - TTL " + cacheTtl + " should be 2 times greater than " + timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished);
|
|
4058
|
+
}
|
|
4059
|
+
this._bio = bio;
|
|
4060
|
+
this._cache = cache;
|
|
4061
|
+
this._cacheTtlMs = cacheTtl != null ? cacheTtl : null;
|
|
4062
|
+
this._maxExecutionTimeMs = maxCallAttemptsToWaitForAlreadyRunningRequest * timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished;
|
|
4063
|
+
this._removeExpiredCacheAutomatically = removeExpiredCacheAutomatically;
|
|
4064
|
+
this._requestsManager = new ManagerOfRequestsToTheSameResource(bio, maxCallAttemptsToWaitForAlreadyRunningRequest, timeoutBetweenAttemptsToCheckWhetherAlreadyRunningRequestFinished);
|
|
4065
|
+
}
|
|
4066
|
+
|
|
4067
|
+
/**
|
|
4068
|
+
* When using this service this is the major method you should call to get data by cache id.
|
|
4069
|
+
* This method checks is there cached data and ether
|
|
4070
|
+
* - returns you flag that you can start requesting data from the shared resource
|
|
4071
|
+
* - or if there is already started calculation waits until it is finished (removed from this service)
|
|
4072
|
+
* and returns you the retrieved data
|
|
4073
|
+
* - or just returns you the cached data
|
|
4074
|
+
*
|
|
4075
|
+
* 'canStartDataRetrieval' equal true means that the lock was acquired, and you should manually call 'saveCachedData'
|
|
4076
|
+
* if needed and then 'releaseLock' to mark this calculation as finished so other
|
|
4077
|
+
* requesters can take their share of the resource.
|
|
4078
|
+
*
|
|
4079
|
+
* @param cacheId {string}
|
|
4080
|
+
* @return {Promise<({
|
|
4081
|
+
* canStartDataRetrieval: true,
|
|
4082
|
+
* cachedData: any,
|
|
4083
|
+
* lockId: string
|
|
4084
|
+
* }|{
|
|
4085
|
+
* canStartDataRetrieval: false,
|
|
4086
|
+
* cachedData: any
|
|
4087
|
+
* })>}
|
|
4088
|
+
*/
|
|
4089
|
+
var _proto = CacheAndConcurrentRequestsResolver.prototype;
|
|
4090
|
+
_proto.getCachedOrWaitForCachedOrAcquireLock = function getCachedOrWaitForCachedOrAcquireLock(cacheId) {
|
|
4091
|
+
try {
|
|
4092
|
+
var _this = this;
|
|
4093
|
+
return Promise.resolve(_catch$5(function () {
|
|
4094
|
+
function _temp2() {
|
|
4095
|
+
var _cached, _cached2;
|
|
4096
|
+
return calculationId ? {
|
|
4097
|
+
canStartDataRetrieval: true,
|
|
4098
|
+
cachedData: (_cached = cached) != null ? _cached : cachedDataBackupIsPresentButExpired,
|
|
4099
|
+
lockId: calculationId
|
|
4100
|
+
} : {
|
|
4101
|
+
canStartDataRetrieval: false,
|
|
4102
|
+
cachedData: (_cached2 = cached) != null ? _cached2 : cachedDataBackupIsPresentButExpired
|
|
4103
|
+
};
|
|
4104
|
+
}
|
|
4105
|
+
var startedAtTimestamp = Date.now();
|
|
4106
|
+
var cached = _this._cache.get(cacheId);
|
|
4107
|
+
var cachedDataBackupIsPresentButExpired = null;
|
|
4108
|
+
if (cached != null && !_this._removeExpiredCacheAutomatically) {
|
|
4109
|
+
var lastUpdateTimestamp = _this._cache.getLastUpdateTimestamp(cacheId);
|
|
4110
|
+
if ((lastUpdateTimestamp != null ? lastUpdateTimestamp : 0) + _this._cacheTtlMs < Date.now()) {
|
|
4111
|
+
/*
|
|
4112
|
+
* Here we are manually clearing 'cached' value retrieved from cache to force the data loading.
|
|
4113
|
+
* But we save its value first to the backup variable to be able to return this value if ongoing
|
|
4114
|
+
* requesting fails.
|
|
4115
|
+
*/
|
|
4116
|
+
cachedDataBackupIsPresentButExpired = cached;
|
|
4117
|
+
cached = null;
|
|
4118
|
+
}
|
|
4119
|
+
}
|
|
4120
|
+
var calculationId = null;
|
|
4121
|
+
var isRetrievedCacheExpired = true;
|
|
4122
|
+
var isWaitingForActiveCalculationSucceeded;
|
|
4123
|
+
var weStillHaveSomeTimeToProceedExecution = true;
|
|
4124
|
+
var _temp = _for(function () {
|
|
4125
|
+
return calculationId == null && cached == null && !!isRetrievedCacheExpired && !!weStillHaveSomeTimeToProceedExecution;
|
|
4126
|
+
}, void 0, function () {
|
|
4127
|
+
return Promise.resolve(_this._requestsManager.startCalculationOrWaitForActiveToFinish(cacheId)).then(function (result) {
|
|
4128
|
+
calculationId = typeof result === "string" ? result : null;
|
|
4129
|
+
isWaitingForActiveCalculationSucceeded = typeof result === "boolean" ? result : null;
|
|
4130
|
+
cached = _this._cache.get(cacheId);
|
|
4131
|
+
isRetrievedCacheExpired = isWaitingForActiveCalculationSucceeded && cached == null;
|
|
4132
|
+
weStillHaveSomeTimeToProceedExecution = Date.now() - startedAtTimestamp < _this._maxExecutionTimeMs;
|
|
4133
|
+
});
|
|
4134
|
+
});
|
|
4135
|
+
return _temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp);
|
|
4136
|
+
}, function (e) {
|
|
4137
|
+
improveAndRethrow(e, _this._bio + ".getCachedOrWaitForCachedOrAcquireLock");
|
|
4138
|
+
}));
|
|
4139
|
+
} catch (e) {
|
|
4140
|
+
return Promise.reject(e);
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
/**
|
|
4144
|
+
* Returns just the current cache value for the given id.
|
|
4145
|
+
* Doesn't wait for the active calculation, doesn't acquire lock, just retrieves the current cache as it is.
|
|
4146
|
+
*
|
|
4147
|
+
* @param cacheId {string}
|
|
4148
|
+
* @return {any}
|
|
4149
|
+
*/
|
|
4150
|
+
;
|
|
4151
|
+
_proto.getCached = function getCached(cacheId) {
|
|
4152
|
+
try {
|
|
4153
|
+
return this._cache.get(cacheId);
|
|
4154
|
+
} catch (e) {
|
|
4155
|
+
improveAndRethrow(e, "getCached");
|
|
4156
|
+
}
|
|
4157
|
+
};
|
|
4158
|
+
_proto._getTtl = function _getTtl() {
|
|
4159
|
+
return this._removeExpiredCacheAutomatically ? this._cacheTtlMs : null;
|
|
4160
|
+
}
|
|
4161
|
+
|
|
4162
|
+
/**
|
|
4163
|
+
* Directly acquires the lock despite on cached data availability.
|
|
4164
|
+
* So if this method returns result === true you can start the data retrieval.
|
|
4165
|
+
*
|
|
4166
|
+
* @param cacheId {string}
|
|
4167
|
+
* @return {Promise<{ result: true, lockId: string }|{ result: false }>}
|
|
4168
|
+
*/;
|
|
4169
|
+
_proto.acquireLock = function acquireLock(cacheId) {
|
|
4170
|
+
try {
|
|
4171
|
+
var _this2 = this;
|
|
4172
|
+
return Promise.resolve(_catch$5(function () {
|
|
4173
|
+
return Promise.resolve(_this2._requestsManager.acquireLock(cacheId));
|
|
4174
|
+
}, function (e) {
|
|
4175
|
+
improveAndRethrow(e, "acquireLock");
|
|
4176
|
+
}));
|
|
4177
|
+
} catch (e) {
|
|
4178
|
+
return Promise.reject(e);
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
/**
|
|
4182
|
+
* This method should be called only if you acquired a lock successfully.
|
|
4183
|
+
*
|
|
4184
|
+
* If the current lock id is not equal to the passed one the passed data will be ignored.
|
|
4185
|
+
* Or you can do the synchronous data merging on your side and pass the
|
|
4186
|
+
* wasDataMergedSynchronouslyWithMostRecentCacheState=true so your data will be stored
|
|
4187
|
+
* despite on the lockId.
|
|
4188
|
+
* WARNING: you should do this only if you are sure you perform the synchronous update.
|
|
4189
|
+
*
|
|
4190
|
+
* @param cacheId {string}
|
|
4191
|
+
* @param lockId {string}
|
|
4192
|
+
* @param data {any}
|
|
4193
|
+
* @param [sessionDependentData=true] {boolean}
|
|
4194
|
+
* @param [wasDataMergedSynchronouslyWithMostRecentCacheState=false]
|
|
4195
|
+
*/
|
|
4196
|
+
;
|
|
4197
|
+
_proto.saveCachedData = function saveCachedData(cacheId, lockId, data, sessionDependentData, wasDataMergedSynchronouslyWithMostRecentCacheState) {
|
|
4198
|
+
if (sessionDependentData === void 0) {
|
|
4199
|
+
sessionDependentData = true;
|
|
4200
|
+
}
|
|
4201
|
+
if (wasDataMergedSynchronouslyWithMostRecentCacheState === void 0) {
|
|
4202
|
+
wasDataMergedSynchronouslyWithMostRecentCacheState = false;
|
|
4203
|
+
}
|
|
4204
|
+
try {
|
|
4205
|
+
if (wasDataMergedSynchronouslyWithMostRecentCacheState || this._requestsManager.isTheLockActiveOne(cacheId, lockId)) {
|
|
4206
|
+
/* We save passed data only if the <caller> has the currently acquired lockId.
|
|
4207
|
+
* If the passed lockId is not the active one it means that other code cleared/stopped the lock
|
|
4208
|
+
* acquired by the <caller> recently due to some urgent/more prior changes.
|
|
4209
|
+
*
|
|
4210
|
+
* But we allow user to pass the 'wasDataMergedSynchronouslyWithMostRecentCacheState' flag
|
|
4211
|
+
* that tells us that the user had taken the most recent cache value and merged his new data
|
|
4212
|
+
* with that cached value (AFTER possibly performing async data retrieval). This means that we
|
|
4213
|
+
* can ignore the fact that his lockId is no more relevant and save the passed data
|
|
4214
|
+
* as it is synchronously merged with the most recent cached data. (Synchronously merged means that
|
|
4215
|
+
* the lost update cannot occur during the merge time as JS execute the synchronous functions\
|
|
4216
|
+
* till the end).
|
|
4217
|
+
*/
|
|
4218
|
+
if (sessionDependentData) {
|
|
4219
|
+
this._cache.putSessionDependentData(cacheId, data, this._getTtl());
|
|
4220
|
+
} else {
|
|
4221
|
+
this._cache.put(cacheId, data, this._getTtl());
|
|
4222
|
+
}
|
|
4223
|
+
}
|
|
4224
|
+
} catch (e) {
|
|
4225
|
+
improveAndRethrow(e, this._bio + ".saveCachedData");
|
|
4226
|
+
}
|
|
4227
|
+
}
|
|
4228
|
+
|
|
4229
|
+
/**
|
|
4230
|
+
* Should be called then and only then if you successfully acquired a lock with the lock id.
|
|
4231
|
+
*
|
|
4232
|
+
* @param cacheId {string}
|
|
4233
|
+
* @param lockId {string}
|
|
4234
|
+
*/;
|
|
4235
|
+
_proto.releaseLock = function releaseLock(cacheId, lockId) {
|
|
4236
|
+
try {
|
|
4237
|
+
if (this._requestsManager.isTheLockActiveOne(cacheId, lockId)) {
|
|
4238
|
+
this._requestsManager.finishActiveCalculation(cacheId);
|
|
4239
|
+
}
|
|
4240
|
+
} catch (e) {
|
|
4241
|
+
improveAndRethrow(e, this._bio + ".releaseLock");
|
|
4242
|
+
}
|
|
4243
|
+
}
|
|
4244
|
+
|
|
4245
|
+
/**
|
|
4246
|
+
* Actualized currently present cached data by key. Applies the provided function to the cached data.
|
|
4247
|
+
*
|
|
4248
|
+
* @param cacheId {string} id of cache entry
|
|
4249
|
+
* @param synchronousCurrentCacheProcessor (function|null} synchronous function accepting cache entry. Should return
|
|
4250
|
+
* an object in following format:
|
|
4251
|
+
* {
|
|
4252
|
+
* isModified: boolean,
|
|
4253
|
+
* data: any
|
|
4254
|
+
* }
|
|
4255
|
+
* the flag signals whether data was changed during the processing or not
|
|
4256
|
+
* @param [sessionDependent=true] {boolean} whether to mark the cache entry as session-dependent
|
|
4257
|
+
*/;
|
|
4258
|
+
_proto.actualizeCachedData = function actualizeCachedData(cacheId, synchronousCurrentCacheProcessor, sessionDependent) {
|
|
4259
|
+
if (sessionDependent === void 0) {
|
|
4260
|
+
sessionDependent = true;
|
|
4261
|
+
}
|
|
4262
|
+
try {
|
|
4263
|
+
var cached = this._cache.get(cacheId);
|
|
4264
|
+
var result = synchronousCurrentCacheProcessor(cached);
|
|
4265
|
+
if (result != null && result.isModified && (result == null ? void 0 : result.data) != null) {
|
|
4266
|
+
if (sessionDependent) {
|
|
4267
|
+
this._cache.putSessionDependentData(cacheId, result == null ? void 0 : result.data, this._getTtl());
|
|
4268
|
+
} else {
|
|
4269
|
+
this._cache.put(cacheId, result == null ? void 0 : result.data, this._getTtl());
|
|
4270
|
+
}
|
|
4271
|
+
|
|
4272
|
+
/* Here we call the lock releasing to ensure the currently active calculation will be ignored.
|
|
4273
|
+
* This is needed to ensure no 'lost update'.
|
|
4274
|
+
* Lost update can occur if we change data in this method and after that some calculation finishes
|
|
4275
|
+
* having the earlier data as its base to calculate its data set result. And the earlier data
|
|
4276
|
+
* has no changes applied inside this method, so we will lose them.
|
|
4277
|
+
*
|
|
4278
|
+
* This is not so good solution: ideally, we should acquire lock before performing any data updating.
|
|
4279
|
+
* But the goal of this method is to provide an instant ability to update the cached data.
|
|
4280
|
+
* And if we start acquiring the lock here the data update can be postponed significantly.
|
|
4281
|
+
* And this kills the desired nature of this method.
|
|
4282
|
+
* So we better lose some data retrieval (means abusing the resource a bit) than lose
|
|
4283
|
+
* the instant update expected after this method execution.
|
|
4284
|
+
*/
|
|
4285
|
+
this._requestsManager.finishActiveCalculation(cacheId);
|
|
4286
|
+
}
|
|
4287
|
+
} catch (e) {
|
|
4288
|
+
improveAndRethrow(e, this._bio + ".actualizeCachedData");
|
|
4289
|
+
}
|
|
4290
|
+
};
|
|
4291
|
+
_proto.invalidate = function invalidate(key) {
|
|
4292
|
+
this._cache.invalidate(key);
|
|
4293
|
+
this._requestsManager.finishActiveCalculation(key);
|
|
4294
|
+
};
|
|
4295
|
+
_proto.invalidateContaining = function invalidateContaining(keyPart) {
|
|
4296
|
+
this._cache.invalidateContaining(keyPart);
|
|
4297
|
+
this._requestsManager.finishAllActiveCalculations(keyPart);
|
|
4298
|
+
};
|
|
4299
|
+
_proto.markAsExpiredButDontRemove = function markAsExpiredButDontRemove(key) {
|
|
4300
|
+
if (this._removeExpiredCacheAutomatically) {
|
|
4301
|
+
this._cache.markCacheItemAsExpiredButDontRemove(key, this._cacheTtlMs);
|
|
4302
|
+
} else {
|
|
4303
|
+
this._cache.setLastUpdateTimestamp(key, Date.now() - this._cacheTtlMs - 1);
|
|
4304
|
+
}
|
|
4305
|
+
this._requestsManager.finishAllActiveCalculations(key);
|
|
4306
|
+
};
|
|
4307
|
+
return CacheAndConcurrentRequestsResolver;
|
|
4308
|
+
}();
|
|
4309
|
+
var ManagerOfRequestsToTheSameResource = /*#__PURE__*/function () {
|
|
4310
|
+
/**
|
|
4311
|
+
* @param bio {string} resource-related identifier for logging
|
|
4312
|
+
* @param [maxPollsCount=100] {number} max number of attempts to wait when waiting for a lock acquisition
|
|
4313
|
+
* @param [timeoutDuration=1000] {number} timeout between the polls for a lock acquisition
|
|
4314
|
+
*/
|
|
4315
|
+
function ManagerOfRequestsToTheSameResource(bio, maxPollsCount, timeoutDuration) {
|
|
4316
|
+
if (maxPollsCount === void 0) {
|
|
4317
|
+
maxPollsCount = 100;
|
|
4318
|
+
}
|
|
4319
|
+
if (timeoutDuration === void 0) {
|
|
4320
|
+
timeoutDuration = 1000;
|
|
4321
|
+
}
|
|
4322
|
+
this.bio = bio;
|
|
4323
|
+
this.maxPollsCount = maxPollsCount;
|
|
4324
|
+
this.timeoutDuration = timeoutDuration;
|
|
4325
|
+
this._activeCalculationsIds = new Map();
|
|
4326
|
+
this._nextCalculationIds = new Map();
|
|
4327
|
+
}
|
|
4328
|
+
|
|
4329
|
+
/**
|
|
4330
|
+
* If there is no active calculation just creates uuid and returns it.
|
|
4331
|
+
* If there is active calculation waits until it removed from the active calculation uuid variable.
|
|
4332
|
+
*
|
|
4333
|
+
* @param requestHash {string}
|
|
4334
|
+
* @return {Promise<string|boolean>} returns uuid of new active calculation or true if waiting for active
|
|
4335
|
+
* calculation succeed or false if max attempts count exceeded
|
|
4336
|
+
*/
|
|
4337
|
+
var _proto2 = ManagerOfRequestsToTheSameResource.prototype;
|
|
4338
|
+
_proto2.startCalculationOrWaitForActiveToFinish = function startCalculationOrWaitForActiveToFinish(requestHash) {
|
|
4339
|
+
try {
|
|
4340
|
+
var _exit;
|
|
4341
|
+
var _this3 = this;
|
|
4342
|
+
var _temp3 = _catch$5(function () {
|
|
4343
|
+
var activeCalculationIdForHash = _this3._activeCalculationsIds.get(requestHash);
|
|
4344
|
+
if (activeCalculationIdForHash == null) {
|
|
4345
|
+
var id = uuid.v4();
|
|
4346
|
+
_this3._activeCalculationsIds.set(requestHash, id);
|
|
4347
|
+
_exit = 1;
|
|
4348
|
+
return id;
|
|
4349
|
+
}
|
|
4350
|
+
return Promise.resolve(_this3._waitForCalculationIdToFinish(requestHash, activeCalculationIdForHash, 0)).then(function (_await$_this3$_waitFo) {
|
|
4351
|
+
_exit = 1;
|
|
4352
|
+
return _await$_this3$_waitFo;
|
|
4353
|
+
});
|
|
4354
|
+
}, function (e) {
|
|
4355
|
+
Logger.logError(e, "startCalculationOrWaitForActiveToFinish_" + _this3.bio);
|
|
4356
|
+
});
|
|
4357
|
+
return Promise.resolve(_temp3 && _temp3.then ? _temp3.then(function (_result3) {
|
|
4358
|
+
return _exit ? _result3 : null;
|
|
4359
|
+
}) : _exit ? _temp3 : null);
|
|
4360
|
+
} catch (e) {
|
|
4361
|
+
return Promise.reject(e);
|
|
3923
4362
|
}
|
|
3924
4363
|
}
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
4364
|
+
/**
|
|
4365
|
+
* Acquires lock to the resource by the provided hash.
|
|
4366
|
+
*
|
|
4367
|
+
* @param requestHash {string}
|
|
4368
|
+
* @return {Promise<{ result: true, lockId: string }|{ result: false }>} result is true if the lock is successfully
|
|
4369
|
+
* acquired, false if the max allowed time to wait for acquisition expired or any unexpected error occurs
|
|
4370
|
+
* during the waiting.
|
|
4371
|
+
*/
|
|
4372
|
+
;
|
|
4373
|
+
_proto2.acquireLock = function acquireLock(requestHash) {
|
|
3931
4374
|
try {
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
4375
|
+
var _this4 = this;
|
|
4376
|
+
return Promise.resolve(_catch$5(function () {
|
|
4377
|
+
var _this4$_nextCalculati;
|
|
4378
|
+
var activeId = _this4._activeCalculationsIds.get(requestHash);
|
|
4379
|
+
var nextId = uuid.v4();
|
|
4380
|
+
if (activeId == null) {
|
|
4381
|
+
_this4._activeCalculationsIds.set(requestHash, nextId);
|
|
4382
|
+
return {
|
|
4383
|
+
result: true,
|
|
4384
|
+
lockId: nextId
|
|
4385
|
+
};
|
|
3941
4386
|
}
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
4387
|
+
var currentNext = (_this4$_nextCalculati = _this4._nextCalculationIds.get(requestHash)) != null ? _this4$_nextCalculati : [];
|
|
4388
|
+
currentNext.push(nextId);
|
|
4389
|
+
_this4._nextCalculationIds.set(requestHash, currentNext);
|
|
4390
|
+
return Promise.resolve(_this4._waitForCalculationIdToFinish(requestHash, activeId, 0, nextId)).then(function (waitingResult) {
|
|
4391
|
+
return {
|
|
4392
|
+
result: waitingResult,
|
|
4393
|
+
lockId: waitingResult ? nextId : undefined
|
|
4394
|
+
};
|
|
4395
|
+
});
|
|
4396
|
+
}, function (e) {
|
|
4397
|
+
improveAndRethrow(e, "acquireLock");
|
|
4398
|
+
}));
|
|
3948
4399
|
} catch (e) {
|
|
3949
|
-
|
|
4400
|
+
return Promise.reject(e);
|
|
3950
4401
|
}
|
|
3951
4402
|
}
|
|
3952
|
-
_cycle();
|
|
3953
|
-
return pact;
|
|
3954
|
-
}
|
|
3955
|
-
var RobustExternalAPICallerService = /*#__PURE__*/function () {
|
|
3956
|
-
RobustExternalAPICallerService.getStats = function getStats() {
|
|
3957
|
-
this.statsCollector.getStats();
|
|
3958
|
-
}
|
|
3959
|
-
|
|
3960
|
-
/**
|
|
3961
|
-
* @param bio {string} service name for logging
|
|
3962
|
-
* @param providersData {ExternalApiProvider[]} array of providers
|
|
3963
|
-
* @param [logger] {function} function to be used for logging
|
|
3964
|
-
*/;
|
|
3965
|
-
function RobustExternalAPICallerService(bio, providersData, logger) {
|
|
3966
|
-
providersData.forEach(function (provider) {
|
|
3967
|
-
if (!provider.endpoint && provider.endpoint !== "" || !provider.httpMethod) {
|
|
3968
|
-
throw new Error("Wrong format of providers data for: " + JSON.stringify(provider));
|
|
3969
|
-
}
|
|
3970
|
-
});
|
|
3971
|
-
|
|
3972
|
-
// We add niceFactor - just number to order the providers array by. It is helpful to call
|
|
3973
|
-
// less robust APIs only if more robust fails
|
|
3974
|
-
this.providers = providersData;
|
|
3975
|
-
providersData.forEach(function (provider) {
|
|
3976
|
-
return provider.resetNiceFactor();
|
|
3977
|
-
});
|
|
3978
|
-
this.bio = bio;
|
|
3979
|
-
this._logger = Logger.logError;
|
|
3980
|
-
}
|
|
3981
|
-
var _proto = RobustExternalAPICallerService.prototype;
|
|
3982
4403
|
/**
|
|
3983
|
-
*
|
|
3984
|
-
*
|
|
3985
|
-
* @param
|
|
3986
|
-
*
|
|
3987
|
-
* @param [cancelToken] {object|undefined} axios token to force-cancel requests from high-level code
|
|
3988
|
-
* @param [attemptsCount] {number|undefined} number of attempts to be performed
|
|
3989
|
-
* @param [doNotFailForNowData] {boolean|undefined} pass true if you do not want us to throw an error if we retrieved null data from all the providers
|
|
3990
|
-
* @return {Promise<any>} resolving to retrieved data (or array of results if specific provider requires
|
|
3991
|
-
* several requests. NOTE: we flatten nested arrays - results of each separate request done for the specific provider)
|
|
3992
|
-
* @throws Error if requests to all providers are failed
|
|
4404
|
+
* Clears active calculation id.
|
|
4405
|
+
* WARNING: if you forget to call this method the start* one will perform maxPollsCount attempts before finishing
|
|
4406
|
+
* @param requestHash {string} hash of request. Helps to distinct the request for the same resource but
|
|
4407
|
+
* having different request parameters and hold a dedicated calculation id per this hash
|
|
3993
4408
|
*/
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
if (timeoutMS === void 0) {
|
|
3999
|
-
timeoutMS = 3500;
|
|
4409
|
+
;
|
|
4410
|
+
_proto2.finishActiveCalculation = function finishActiveCalculation(requestHash) {
|
|
4411
|
+
if (requestHash === void 0) {
|
|
4412
|
+
requestHash = "default";
|
|
4000
4413
|
}
|
|
4001
|
-
|
|
4002
|
-
|
|
4414
|
+
try {
|
|
4415
|
+
var _this$_nextCalculatio;
|
|
4416
|
+
this._activeCalculationsIds["delete"](requestHash);
|
|
4417
|
+
var next = (_this$_nextCalculatio = this._nextCalculationIds.get(requestHash)) != null ? _this$_nextCalculatio : [];
|
|
4418
|
+
if (next.length) {
|
|
4419
|
+
this._activeCalculationsIds.set(requestHash, next[0]);
|
|
4420
|
+
this._nextCalculationIds.set(requestHash, next.slice(1));
|
|
4421
|
+
}
|
|
4422
|
+
} catch (e) {
|
|
4423
|
+
improveAndRethrow(e, "finishActiveCalculation");
|
|
4003
4424
|
}
|
|
4004
|
-
|
|
4005
|
-
|
|
4425
|
+
};
|
|
4426
|
+
_proto2.finishAllActiveCalculations = function finishAllActiveCalculations(keyPart) {
|
|
4427
|
+
var _this5 = this;
|
|
4428
|
+
if (keyPart === void 0) {
|
|
4429
|
+
keyPart = "";
|
|
4006
4430
|
}
|
|
4007
|
-
|
|
4008
|
-
|
|
4431
|
+
try {
|
|
4432
|
+
Array.from(this._activeCalculationsIds.keys()).forEach(function (hash) {
|
|
4433
|
+
if (typeof hash === "string" && new RegExp(keyPart).test(hash)) {
|
|
4434
|
+
_this5.finishActiveCalculation(hash);
|
|
4435
|
+
}
|
|
4436
|
+
});
|
|
4437
|
+
} catch (e) {
|
|
4438
|
+
improveAndRethrow(e, "finishAllActiveCalculations");
|
|
4009
4439
|
}
|
|
4440
|
+
}
|
|
4441
|
+
|
|
4442
|
+
/**
|
|
4443
|
+
* @param requestHash {string}
|
|
4444
|
+
* @param lockId {string}
|
|
4445
|
+
* @return {boolean}
|
|
4446
|
+
*/;
|
|
4447
|
+
_proto2.isTheLockActiveOne = function isTheLockActiveOne(requestHash, lockId) {
|
|
4010
4448
|
try {
|
|
4011
|
-
|
|
4012
|
-
var result;
|
|
4013
|
-
var calculationUuid = concurrentCalculationsMetadataHolder.startCalculation(_this.bio);
|
|
4014
|
-
return Promise.resolve(_finallyRethrows$1(function () {
|
|
4015
|
-
return _catch$4(function () {
|
|
4016
|
-
function _temp5() {
|
|
4017
|
-
var _result2, _result3;
|
|
4018
|
-
if (((_result2 = result) == null ? void 0 : _result2.data) == null) {
|
|
4019
|
-
// TODO: [feature, moderate] looks like we should not fail for null data as it is strange - the provider will fail when processing data internally
|
|
4020
|
-
var error = new Error("Failed to retrieve data. It means all attempts have been failed. DEV: add more attempts to this data retrieval");
|
|
4021
|
-
if (!doNotFailForNowData) {
|
|
4022
|
-
throw error;
|
|
4023
|
-
} else {
|
|
4024
|
-
_this._logger(error, _this.bio + ".callExternalAPI");
|
|
4025
|
-
}
|
|
4026
|
-
}
|
|
4027
|
-
return (_result3 = result) == null ? void 0 : _result3.data;
|
|
4028
|
-
}
|
|
4029
|
-
var i = 0;
|
|
4030
|
-
var _temp4 = _for(function () {
|
|
4031
|
-
var _result4, _result5;
|
|
4032
|
-
return (i < attemptsCount || !!((_result4 = result) != null && _result4.shouldBeForceRetried)) && ((_result5 = result) == null ? void 0 : _result5.data) == null;
|
|
4033
|
-
}, function () {
|
|
4034
|
-
return ++i;
|
|
4035
|
-
}, function () {
|
|
4036
|
-
/**
|
|
4037
|
-
* We use rpsFactor to improve re-attempting to call the providers if the last attempt resulted with
|
|
4038
|
-
* the fail due to abused RPSes of some (most part of) providers.
|
|
4039
|
-
* The _performCallAttempt in such a case will return increased rpsFactor inside the result object.
|
|
4040
|
-
*/
|
|
4041
|
-
var rpsFactor = result ? result.rpsFactor : RobustExternalAPICallerService.defaultRPSFactor;
|
|
4042
|
-
result = null;
|
|
4043
|
-
var _temp3 = _catch$4(function () {
|
|
4044
|
-
function _temp2() {
|
|
4045
|
-
var _result$errors;
|
|
4046
|
-
if ((_result$errors = result.errors) != null && _result$errors.length) {
|
|
4047
|
-
var errors = result.errors;
|
|
4048
|
-
_this._logger(new Error("Failed at attempt " + i + ". " + errors.length + " errors. Messages: " + safeStringify(errors.map(function (error) {
|
|
4049
|
-
return error.message;
|
|
4050
|
-
})) + ": " + safeStringify(errors) + "."), _this.bio + ".callExternalAPI", "", true);
|
|
4051
|
-
}
|
|
4052
|
-
}
|
|
4053
|
-
var _temp = function (_result6) {
|
|
4054
|
-
if (i === 0 && !((_result6 = result) != null && _result6.shouldBeForceRetried)) {
|
|
4055
|
-
return Promise.resolve(_this._performCallAttempt(parametersValues, timeoutMS, cancelToken, rpsFactor, doNotFailForNowData)).then(function (_this$_performCallAtt) {
|
|
4056
|
-
result = _this$_performCallAtt;
|
|
4057
|
-
});
|
|
4058
|
-
} else {
|
|
4059
|
-
var maxRps = Math.max.apply(Math, _this.providers.map(function (provider) {
|
|
4060
|
-
var _provider$getRps;
|
|
4061
|
-
return (_provider$getRps = provider.getRps()) != null ? _provider$getRps : 0;
|
|
4062
|
-
}));
|
|
4063
|
-
var waitingTimeMs = maxRps ? 1000 / (maxRps / rpsFactor) : 0;
|
|
4064
|
-
return Promise.resolve(new Promise(function (resolve, reject) {
|
|
4065
|
-
setTimeout(function () {
|
|
4066
|
-
try {
|
|
4067
|
-
var _temp6 = _catch$4(function () {
|
|
4068
|
-
return Promise.resolve(_this._performCallAttempt(parametersValues, timeoutMS, cancelToken, rpsFactor, doNotFailForNowData)).then(function (_this$_performCallAtt2) {
|
|
4069
|
-
resolve(_this$_performCallAtt2);
|
|
4070
|
-
});
|
|
4071
|
-
}, function (e) {
|
|
4072
|
-
reject(e);
|
|
4073
|
-
});
|
|
4074
|
-
return Promise.resolve(_temp6 && _temp6.then ? _temp6.then(function () {}) : void 0);
|
|
4075
|
-
} catch (e) {
|
|
4076
|
-
return Promise.reject(e);
|
|
4077
|
-
}
|
|
4078
|
-
}, waitingTimeMs);
|
|
4079
|
-
})).then(function (_Promise) {
|
|
4080
|
-
result = _Promise;
|
|
4081
|
-
});
|
|
4082
|
-
}
|
|
4083
|
-
}();
|
|
4084
|
-
return _temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp);
|
|
4085
|
-
}, function (e) {
|
|
4086
|
-
_this._logger(e, _this.bio + ".callExternalAPI", "Failed to perform external providers calling");
|
|
4087
|
-
});
|
|
4088
|
-
if (_temp3 && _temp3.then) return _temp3.then(function () {});
|
|
4089
|
-
});
|
|
4090
|
-
return _temp4 && _temp4.then ? _temp4.then(_temp5) : _temp5(_temp4);
|
|
4091
|
-
}, function (e) {
|
|
4092
|
-
improveAndRethrow(e, _this.bio + ".callExternalAPI");
|
|
4093
|
-
});
|
|
4094
|
-
}, function (_wasThrown, _result) {
|
|
4095
|
-
concurrentCalculationsMetadataHolder.endCalculation(_this.bio, calculationUuid);
|
|
4096
|
-
if (_wasThrown) throw _result;
|
|
4097
|
-
return _result;
|
|
4098
|
-
}));
|
|
4449
|
+
return this._activeCalculationsIds.get(requestHash) === lockId;
|
|
4099
4450
|
} catch (e) {
|
|
4100
|
-
|
|
4451
|
+
improveAndRethrow(e, "isTheLockActiveOne");
|
|
4452
|
+
}
|
|
4453
|
+
}
|
|
4454
|
+
|
|
4455
|
+
/**
|
|
4456
|
+
* @param requestHash {string}
|
|
4457
|
+
* @param activeCalculationId {string|null}
|
|
4458
|
+
* @param [attemptIndex=0] {number}
|
|
4459
|
+
* @param waitForCalculationId {string|null} if you want to wait for an exact id to appear as active then pass this parameter
|
|
4460
|
+
* @return {Promise<boolean>} true
|
|
4461
|
+
* - if the given calculation id is no more an active one
|
|
4462
|
+
* - or it is equal to waitForCalculationId
|
|
4463
|
+
* false
|
|
4464
|
+
* - if waiting period exceeds the max allowed waiting time or unexpected error occurs
|
|
4465
|
+
* @private
|
|
4466
|
+
*/;
|
|
4467
|
+
_proto2._waitForCalculationIdToFinish = function _waitForCalculationIdToFinish(requestHash, activeCalculationId, attemptIndex, waitForCalculationId) {
|
|
4468
|
+
if (attemptIndex === void 0) {
|
|
4469
|
+
attemptIndex = 0;
|
|
4470
|
+
}
|
|
4471
|
+
if (waitForCalculationId === void 0) {
|
|
4472
|
+
waitForCalculationId = null;
|
|
4101
4473
|
}
|
|
4102
|
-
};
|
|
4103
|
-
_proto._performCallAttempt = function _performCallAttempt(parametersValues, timeoutMS, cancelToken, rpsFactor, doNotFailForNowData) {
|
|
4104
4474
|
try {
|
|
4105
|
-
var
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
return {
|
|
4111
|
-
data: (_data = data) != null ? _data : null,
|
|
4112
|
-
shouldBeForceRetried: shouldBeForceRetried,
|
|
4113
|
-
rpsFactor: rpsFactor * rpsMultiplier,
|
|
4114
|
-
errors: errors
|
|
4115
|
-
};
|
|
4116
|
-
};
|
|
4117
|
-
var _this2 = this;
|
|
4118
|
-
var providers = _this2._reorderProvidersByNiceFactor();
|
|
4119
|
-
var data = undefined,
|
|
4120
|
-
providerIndex = 0,
|
|
4121
|
-
countOfRequestsDeclinedByRps = 0,
|
|
4122
|
-
errors = [];
|
|
4123
|
-
var _temp14 = _for(function () {
|
|
4124
|
-
return !data && providerIndex < providers.length;
|
|
4125
|
-
}, void 0, function () {
|
|
4126
|
-
var provider = providers[providerIndex];
|
|
4127
|
-
if (provider.isRpsExceeded()) {
|
|
4128
|
-
/**
|
|
4129
|
-
* Current provider's RPS is exceeded, so we try next provider. Also, we count such cases to make
|
|
4130
|
-
* a decision about the force-retry need.
|
|
4131
|
-
*/
|
|
4132
|
-
++providerIndex;
|
|
4133
|
-
++countOfRequestsDeclinedByRps;
|
|
4134
|
-
return;
|
|
4475
|
+
var _this6 = this;
|
|
4476
|
+
try {
|
|
4477
|
+
if (attemptIndex + 1 > _this6.maxPollsCount) {
|
|
4478
|
+
// Max number of polls for active calculation id change is achieved. So we return false.
|
|
4479
|
+
return Promise.resolve(false);
|
|
4135
4480
|
}
|
|
4136
|
-
var
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
var responsesDataForPages = responsesForPages.map(function (response) {
|
|
4162
|
-
return provider.getDataByResponse(response, parametersValues, subRequestIndex, iterationsData);
|
|
4163
|
-
});
|
|
4164
|
-
var allData = responsesDataForPages;
|
|
4165
|
-
if (Array.isArray(responsesDataForPages[0])) {
|
|
4166
|
-
allData = responsesDataForPages.flat();
|
|
4167
|
-
} else if (responsesDataForPages.length === 1) {
|
|
4168
|
-
allData = responsesDataForPages[0];
|
|
4169
|
-
}
|
|
4170
|
-
iterationsData.push(allData);
|
|
4171
|
-
}
|
|
4172
|
-
var query = provider.composeQueryString(parametersValues, subRequestIndex);
|
|
4173
|
-
var endpoint = "" + provider.endpoint + query;
|
|
4174
|
-
var axiosParams = [endpoint, axiosConfig];
|
|
4175
|
-
if (["post", "put", "patch"].find(function (method) {
|
|
4176
|
-
return method === httpMethods[subRequestIndex];
|
|
4177
|
-
})) {
|
|
4178
|
-
var _provider$composeBody;
|
|
4179
|
-
var body = (_provider$composeBody = provider.composeBody(parametersValues, subRequestIndex)) != null ? _provider$composeBody : null;
|
|
4180
|
-
axiosParams.splice(1, 0, body);
|
|
4481
|
+
var currentId = _this6._activeCalculationsIds.get(requestHash);
|
|
4482
|
+
if (waitForCalculationId == null ? currentId !== activeCalculationId : currentId === waitForCalculationId) {
|
|
4483
|
+
/* We return true depending on the usage of this function:
|
|
4484
|
+
* 1. if there is calculation id that we should wait for to become an active then we return true only
|
|
4485
|
+
* if this id becomes the active one.
|
|
4486
|
+
*
|
|
4487
|
+
* Theoretically we can fail to wait for the desired calculation id. This can be caused by wrong use of
|
|
4488
|
+
* this service or by any other mistakes/errors. But this waiting function will return false anyway if
|
|
4489
|
+
* the number of polls done exceeds the max allowed.
|
|
4490
|
+
*
|
|
4491
|
+
* 2. if we just wait for the currently active calculation id to be finished then we return true
|
|
4492
|
+
* when we notice that the current active id differs from the original passed into this function.
|
|
4493
|
+
*/
|
|
4494
|
+
return Promise.resolve(true);
|
|
4495
|
+
} else {
|
|
4496
|
+
/* The original calculation id is still the active one, so we are scheduling a new attempt to check
|
|
4497
|
+
* whether the active calculation id changed or not in timeoutDuration milliseconds.
|
|
4498
|
+
*/
|
|
4499
|
+
var it = _this6;
|
|
4500
|
+
return Promise.resolve(new Promise(function (resolve, reject) {
|
|
4501
|
+
setTimeout(function () {
|
|
4502
|
+
try {
|
|
4503
|
+
resolve(it._waitForCalculationIdToFinish(requestHash, activeCalculationId, attemptIndex + 1));
|
|
4504
|
+
} catch (e) {
|
|
4505
|
+
reject(e);
|
|
4181
4506
|
}
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
}
|
|
4190
|
-
pageNumber++;
|
|
4191
|
-
}
|
|
4192
|
-
var _temp7 = function () {
|
|
4193
|
-
if (subRequestIndex === 0 && pageNumber === 0) {
|
|
4194
|
-
provider.actualizeLastCalledTimestamp();
|
|
4195
|
-
return Promise.resolve(AxiosAdapter.call.apply(AxiosAdapter, [httpMethods[subRequestIndex]].concat(axiosParams))).then(function (_AxiosAdapter$call) {
|
|
4196
|
-
responsesForPages[pageNumber] = _AxiosAdapter$call;
|
|
4197
|
-
RobustExternalAPICallerService.statsCollector.externalServiceCalledWithoutError(provider.getApiGroupId());
|
|
4198
|
-
});
|
|
4199
|
-
} else {
|
|
4200
|
-
if (pageNumber > 0) {
|
|
4201
|
-
var actualizedParams = provider.changeQueryParametersForPageNumber(parametersValues, responsesForPages[pageNumber - 1], pageNumber, subRequestIndex);
|
|
4202
|
-
var _query = provider.composeQueryString(actualizedParams, subRequestIndex);
|
|
4203
|
-
axiosParams[0] = "" + provider.endpoint + _query;
|
|
4204
|
-
}
|
|
4205
|
-
/**
|
|
4206
|
-
* For second and more request we postpone each request to not exceed RPS
|
|
4207
|
-
* of current provider. We use rpsFactor to dynamically increase the rps to avoid
|
|
4208
|
-
* too frequent calls if we continue failing to retrieve the data due to RPS exceeding.
|
|
4209
|
-
* TODO: [dev] test RPS factor logic (units or integration)
|
|
4210
|
-
*/
|
|
4211
|
-
|
|
4212
|
-
var waitingTimeMS = provider.getRps() ? 1000 / (provider.getRps() / rpsFactor) : 0;
|
|
4213
|
-
var postponeUntilRpsExceeded = function postponeUntilRpsExceeded(recursionLevel) {
|
|
4214
|
-
if (recursionLevel === void 0) {
|
|
4215
|
-
recursionLevel = 0;
|
|
4216
|
-
}
|
|
4217
|
-
try {
|
|
4218
|
-
return Promise.resolve(postponeExecution(function () {
|
|
4219
|
-
try {
|
|
4220
|
-
var _temp17 = function _temp17(_result8) {
|
|
4221
|
-
if (_exit) return _result8;
|
|
4222
|
-
provider.actualizeLastCalledTimestamp();
|
|
4223
|
-
return Promise.resolve(AxiosAdapter.call.apply(AxiosAdapter, [httpMethods[subRequestIndex]].concat(axiosParams)));
|
|
4224
|
-
};
|
|
4225
|
-
var _exit;
|
|
4226
|
-
var maxCountOfPostponingAttempts = 2;
|
|
4227
|
-
var _temp16 = function () {
|
|
4228
|
-
if (provider.isRpsExceeded() && recursionLevel < maxCountOfPostponingAttempts) {
|
|
4229
|
-
return Promise.resolve(postponeUntilRpsExceeded(recursionLevel + 1)).then(function (_await$postponeUntilR) {
|
|
4230
|
-
_exit = 1;
|
|
4231
|
-
return _await$postponeUntilR;
|
|
4232
|
-
});
|
|
4233
|
-
}
|
|
4234
|
-
}();
|
|
4235
|
-
return Promise.resolve(_temp16 && _temp16.then ? _temp16.then(_temp17) : _temp17(_temp16));
|
|
4236
|
-
} catch (e) {
|
|
4237
|
-
return Promise.reject(e);
|
|
4238
|
-
}
|
|
4239
|
-
}, waitingTimeMS));
|
|
4240
|
-
} catch (e) {
|
|
4241
|
-
return Promise.reject(e);
|
|
4242
|
-
}
|
|
4243
|
-
};
|
|
4244
|
-
return Promise.resolve(postponeUntilRpsExceeded()).then(function (_postponeUntilRpsExce) {
|
|
4245
|
-
responsesForPages[pageNumber] = _postponeUntilRpsExce;
|
|
4246
|
-
});
|
|
4247
|
-
}
|
|
4248
|
-
}();
|
|
4249
|
-
return _temp7 && _temp7.then ? _temp7.then(_temp8) : _temp8(_temp7);
|
|
4250
|
-
}, function () {
|
|
4251
|
-
return !!hasNextPage;
|
|
4252
|
-
});
|
|
4253
|
-
return _temp9 && _temp9.then ? _temp9.then(_temp10) : _temp10(_temp9);
|
|
4254
|
-
});
|
|
4255
|
-
return _temp11 && _temp11.then ? _temp11.then(_temp12) : _temp12(_temp11);
|
|
4256
|
-
}, function (e) {
|
|
4257
|
-
punishProvider(provider);
|
|
4258
|
-
RobustExternalAPICallerService.statsCollector.externalServiceFailed(provider.getApiGroupId(), e == null ? void 0 : e.message);
|
|
4259
|
-
errors.push(e);
|
|
4260
|
-
});
|
|
4261
|
-
}, function (_wasThrown2, _result7) {
|
|
4262
|
-
providerIndex++;
|
|
4263
|
-
if (_wasThrown2) throw _result7;
|
|
4264
|
-
return _result7;
|
|
4265
|
-
});
|
|
4266
|
-
if (_temp13 && _temp13.then) return _temp13.then(function () {});
|
|
4267
|
-
});
|
|
4268
|
-
return Promise.resolve(_temp14 && _temp14.then ? _temp14.then(_temp15) : _temp15(_temp14));
|
|
4507
|
+
}, _this6.timeoutDuration);
|
|
4508
|
+
}));
|
|
4509
|
+
}
|
|
4510
|
+
} catch (e) {
|
|
4511
|
+
Logger.logError(e, "_waitForCalculationIdToFinish", "Failed to wait for active calculation id change.");
|
|
4512
|
+
return Promise.resolve(false);
|
|
4513
|
+
}
|
|
4269
4514
|
} catch (e) {
|
|
4270
4515
|
return Promise.reject(e);
|
|
4271
4516
|
}
|
|
4272
4517
|
};
|
|
4273
|
-
|
|
4274
|
-
var providersCopy = [].concat(this.providers);
|
|
4275
|
-
return providersCopy.sort(function (p1, p2) {
|
|
4276
|
-
return p2.niceFactor - p1.niceFactor;
|
|
4277
|
-
});
|
|
4278
|
-
};
|
|
4279
|
-
return RobustExternalAPICallerService;
|
|
4518
|
+
return ManagerOfRequestsToTheSameResource;
|
|
4280
4519
|
}();
|
|
4281
|
-
RobustExternalAPICallerService.statsCollector = new ExternalServicesStatsCollector();
|
|
4282
|
-
RobustExternalAPICallerService.defaultRPSFactor = 1;
|
|
4283
|
-
RobustExternalAPICallerService.rpsMultiplier = 1.05;
|
|
4284
|
-
function punishProvider(provider) {
|
|
4285
|
-
provider.niceFactor = provider.niceFactor - 1;
|
|
4286
|
-
}
|
|
4287
4520
|
|
|
4288
4521
|
/**
|
|
4289
4522
|
* Extended edit of RobustExternalApiCallerService supporting cache and management of concurrent requests
|
|
@@ -4291,7 +4524,7 @@ function punishProvider(provider) {
|
|
|
4291
4524
|
* TODO: [tests, critical] Massively used logic
|
|
4292
4525
|
*/
|
|
4293
4526
|
|
|
4294
|
-
function _catch$
|
|
4527
|
+
function _catch$4(body, recover) {
|
|
4295
4528
|
try {
|
|
4296
4529
|
var result = body();
|
|
4297
4530
|
} catch (e) {
|
|
@@ -4388,7 +4621,7 @@ var CachedRobustExternalApiCallerService = /*#__PURE__*/function () {
|
|
|
4388
4621
|
var cacheId;
|
|
4389
4622
|
var result;
|
|
4390
4623
|
return Promise.resolve(_finallyRethrows(function () {
|
|
4391
|
-
return _catch$
|
|
4624
|
+
return _catch$4(function () {
|
|
4392
4625
|
cacheId = _this._calculateCacheId(parametersValues, customHashFunctionForParams);
|
|
4393
4626
|
return Promise.resolve(_this._cahceAndRequestsResolver.getCachedOrWaitForCachedOrAcquireLock(cacheId)).then(function (_this$_cahceAndReques) {
|
|
4394
4627
|
var _result2, _result4;
|
|
@@ -4436,26 +4669,123 @@ var CachedRobustExternalApiCallerService = /*#__PURE__*/function () {
|
|
|
4436
4669
|
var cacheId = this._calculateCacheId(params, customHashFunctionForParams);
|
|
4437
4670
|
this._cahceAndRequestsResolver.actualizeCachedData(cacheId, synchronousCurrentCacheProcessor, sessionDependent);
|
|
4438
4671
|
};
|
|
4439
|
-
_proto.markCacheAsExpiredButDontRemove = function markCacheAsExpiredButDontRemove(parametersValues, customHashFunctionForParams) {
|
|
4440
|
-
try {
|
|
4441
|
-
this._cahceAndRequestsResolver.markAsExpiredButDontRemove(this._calculateCacheId(parametersValues, customHashFunctionForParams));
|
|
4442
|
-
} catch (e) {
|
|
4443
|
-
improveAndRethrow(e, "markCacheAsExpiredButDontRemove");
|
|
4444
|
-
}
|
|
4672
|
+
_proto.markCacheAsExpiredButDontRemove = function markCacheAsExpiredButDontRemove(parametersValues, customHashFunctionForParams) {
|
|
4673
|
+
try {
|
|
4674
|
+
this._cahceAndRequestsResolver.markAsExpiredButDontRemove(this._calculateCacheId(parametersValues, customHashFunctionForParams));
|
|
4675
|
+
} catch (e) {
|
|
4676
|
+
improveAndRethrow(e, "markCacheAsExpiredButDontRemove");
|
|
4677
|
+
}
|
|
4678
|
+
};
|
|
4679
|
+
_proto._calculateCacheId = function _calculateCacheId(parametersValues, customHashFunctionForParams) {
|
|
4680
|
+
if (customHashFunctionForParams === void 0) {
|
|
4681
|
+
customHashFunctionForParams = null;
|
|
4682
|
+
}
|
|
4683
|
+
try {
|
|
4684
|
+
var hash = typeof customHashFunctionForParams === "function" ? customHashFunctionForParams(parametersValues) : !parametersValues ? "" : new Hashes__default["default"].SHA512().hex(safeStringify(parametersValues));
|
|
4685
|
+
return this._provider.bio + "-" + hash;
|
|
4686
|
+
} catch (e) {
|
|
4687
|
+
improveAndRethrow(e, this._provider.bio + "_calculateCacheId");
|
|
4688
|
+
}
|
|
4689
|
+
};
|
|
4690
|
+
return CachedRobustExternalApiCallerService;
|
|
4691
|
+
}();
|
|
4692
|
+
|
|
4693
|
+
function _catch$3(body, recover) {
|
|
4694
|
+
try {
|
|
4695
|
+
var result = body();
|
|
4696
|
+
} catch (e) {
|
|
4697
|
+
return recover(e);
|
|
4698
|
+
}
|
|
4699
|
+
if (result && result.then) {
|
|
4700
|
+
return result.then(void 0, recover);
|
|
4701
|
+
}
|
|
4702
|
+
return result;
|
|
4703
|
+
}
|
|
4704
|
+
var BigdatacloudIpAddressProvider = /*#__PURE__*/function (_ExternalApiProvider) {
|
|
4705
|
+
_inheritsLoose(BigdatacloudIpAddressProvider, _ExternalApiProvider);
|
|
4706
|
+
function BigdatacloudIpAddressProvider() {
|
|
4707
|
+
return _ExternalApiProvider.call(this, "https://api.bigdatacloud.net/data/client-ip", "get", 15000, ApiGroups.BIGDATACLOUD) || this;
|
|
4708
|
+
}
|
|
4709
|
+
var _proto = BigdatacloudIpAddressProvider.prototype;
|
|
4710
|
+
_proto.getDataByResponse = function getDataByResponse(response, params, subRequestIndex, iterationsData) {
|
|
4711
|
+
var _response$data;
|
|
4712
|
+
return (response == null ? void 0 : response.data) && ((_response$data = response.data) == null ? void 0 : _response$data.ipString);
|
|
4713
|
+
};
|
|
4714
|
+
return BigdatacloudIpAddressProvider;
|
|
4715
|
+
}(ExternalApiProvider);
|
|
4716
|
+
var TrackipIpAddressProvider = /*#__PURE__*/function (_ExternalApiProvider2) {
|
|
4717
|
+
_inheritsLoose(TrackipIpAddressProvider, _ExternalApiProvider2);
|
|
4718
|
+
function TrackipIpAddressProvider() {
|
|
4719
|
+
return _ExternalApiProvider2.call(this, "https://www.trackip.net/ip", "get", 15000, ApiGroups.TRACKIP) || this;
|
|
4720
|
+
}
|
|
4721
|
+
var _proto2 = TrackipIpAddressProvider.prototype;
|
|
4722
|
+
_proto2.getDataByResponse = function getDataByResponse(response, params, subRequestIndex, iterationsData) {
|
|
4723
|
+
return response == null ? void 0 : response.data;
|
|
4724
|
+
};
|
|
4725
|
+
return TrackipIpAddressProvider;
|
|
4726
|
+
}(ExternalApiProvider);
|
|
4727
|
+
var IpifyV6IpAddressProvider = /*#__PURE__*/function (_ExternalApiProvider3) {
|
|
4728
|
+
_inheritsLoose(IpifyV6IpAddressProvider, _ExternalApiProvider3);
|
|
4729
|
+
function IpifyV6IpAddressProvider() {
|
|
4730
|
+
return _ExternalApiProvider3.call(this, "https://api6.ipify.org/?format=json", "get", 15000, ApiGroups.IPIFY) || this;
|
|
4731
|
+
}
|
|
4732
|
+
var _proto3 = IpifyV6IpAddressProvider.prototype;
|
|
4733
|
+
_proto3.getDataByResponse = function getDataByResponse(response, params, subRequestIndex, iterationsData) {
|
|
4734
|
+
var _response$data2;
|
|
4735
|
+
return (response == null ? void 0 : response.data) && ((_response$data2 = response.data) == null ? void 0 : _response$data2.ip);
|
|
4736
|
+
};
|
|
4737
|
+
return IpifyV6IpAddressProvider;
|
|
4738
|
+
}(ExternalApiProvider);
|
|
4739
|
+
var IpifyIpAddressProvider = /*#__PURE__*/function (_ExternalApiProvider4) {
|
|
4740
|
+
_inheritsLoose(IpifyIpAddressProvider, _ExternalApiProvider4);
|
|
4741
|
+
function IpifyIpAddressProvider() {
|
|
4742
|
+
return _ExternalApiProvider4.call(this, "https://api.ipify.org/?format=json", "get", 15000, ApiGroups.IPIFY) || this;
|
|
4743
|
+
}
|
|
4744
|
+
var _proto4 = IpifyIpAddressProvider.prototype;
|
|
4745
|
+
_proto4.getDataByResponse = function getDataByResponse(response, params, subRequestIndex, iterationsData) {
|
|
4746
|
+
var _response$data3;
|
|
4747
|
+
return (response == null ? void 0 : response.data) && ((_response$data3 = response.data) == null ? void 0 : _response$data3.ip);
|
|
4445
4748
|
};
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4749
|
+
return IpifyIpAddressProvider;
|
|
4750
|
+
}(ExternalApiProvider);
|
|
4751
|
+
var WhatismyipaddressIpAddressProvider = /*#__PURE__*/function (_ExternalApiProvider5) {
|
|
4752
|
+
_inheritsLoose(WhatismyipaddressIpAddressProvider, _ExternalApiProvider5);
|
|
4753
|
+
function WhatismyipaddressIpAddressProvider() {
|
|
4754
|
+
return _ExternalApiProvider5.call(this, "http://bot.whatismyipaddress.com/", "get", 15000, ApiGroups.WHATISMYIPADDRESS) || this;
|
|
4755
|
+
}
|
|
4756
|
+
var _proto5 = WhatismyipaddressIpAddressProvider.prototype;
|
|
4757
|
+
_proto5.getDataByResponse = function getDataByResponse(response, params, subRequestIndex, iterationsData) {
|
|
4758
|
+
return response == null ? void 0 : response.data;
|
|
4759
|
+
};
|
|
4760
|
+
return WhatismyipaddressIpAddressProvider;
|
|
4761
|
+
}(ExternalApiProvider);
|
|
4762
|
+
var IpAddressProvider = /*#__PURE__*/function () {
|
|
4763
|
+
function IpAddressProvider() {}
|
|
4764
|
+
/**
|
|
4765
|
+
* Returns current public IP address identified by one of external services.
|
|
4766
|
+
*
|
|
4767
|
+
* It is easier than manual identification and also (as ip needed for server side to check it) it saves us from
|
|
4768
|
+
* issues related to changes of infrastructure configurations (like adding proxies etc.) so we should not configure
|
|
4769
|
+
* anything on server side to get correct client's IP.
|
|
4770
|
+
*
|
|
4771
|
+
* @returns {Promise<String>} IP address
|
|
4772
|
+
* @throws {Error} if fails to retrieve IP address from all the services
|
|
4773
|
+
*/
|
|
4774
|
+
IpAddressProvider.getClientIpAddress = function getClientIpAddress() {
|
|
4450
4775
|
try {
|
|
4451
|
-
var
|
|
4452
|
-
return
|
|
4776
|
+
var _this = this;
|
|
4777
|
+
return Promise.resolve(_catch$3(function () {
|
|
4778
|
+
return Promise.resolve(_this.externalIPAddressAPICaller.callExternalAPICached([], 7000));
|
|
4779
|
+
}, function (e) {
|
|
4780
|
+
improveAndRethrow(e, "getClientIpAddress");
|
|
4781
|
+
}));
|
|
4453
4782
|
} catch (e) {
|
|
4454
|
-
|
|
4783
|
+
return Promise.reject(e);
|
|
4455
4784
|
}
|
|
4456
4785
|
};
|
|
4457
|
-
return
|
|
4786
|
+
return IpAddressProvider;
|
|
4458
4787
|
}();
|
|
4788
|
+
IpAddressProvider.externalIPAddressAPICaller = new CachedRobustExternalApiCallerService("externalIPAddressAPICaller", new Cache(EventBusInstance__default["default"]), [new BigdatacloudIpAddressProvider(), new TrackipIpAddressProvider(), new IpifyV6IpAddressProvider(), new IpifyIpAddressProvider(), new WhatismyipaddressIpAddressProvider()], 300000);
|
|
4459
4789
|
|
|
4460
4790
|
/**
|
|
4461
4791
|
* Utils class needed to perform cancelling of axios request inside some process.
|
|
@@ -4483,239 +4813,6 @@ var CancelProcessing = /*#__PURE__*/function () {
|
|
|
4483
4813
|
return CancelProcessing;
|
|
4484
4814
|
}();
|
|
4485
4815
|
|
|
4486
|
-
var ExternalApiProvider = /*#__PURE__*/function () {
|
|
4487
|
-
/**
|
|
4488
|
-
* Creates an instance of external api provider.
|
|
4489
|
-
*
|
|
4490
|
-
* If you need sub-request then use 'subRequestIndex' to check current request index in functions below.
|
|
4491
|
-
* Also use array for 'httpMethod'.
|
|
4492
|
-
*
|
|
4493
|
-
* If the endpoint of dedicated provider has pagination then you should customize the behavior using
|
|
4494
|
-
* "changeQueryParametersForPageNumber", "checkWhetherResponseIsForLastPage".
|
|
4495
|
-
*
|
|
4496
|
-
* We perform RPS counting all over the App to avoid blocking our clients due to abuses of the providers.
|
|
4497
|
-
*
|
|
4498
|
-
* @param endpoint {string} URL to the provider's endpoint. Note: you can customize it using composeQueryString
|
|
4499
|
-
* @param [httpMethod] {string|string[]} one of "get", "post", "put", "patch", "delete" or an array of these values
|
|
4500
|
-
* for request having sub-requests
|
|
4501
|
-
* @param [timeout] {number} number of milliseconds to wait for the response
|
|
4502
|
-
* @param [apiGroup] {ApiGroup} singleton object containing parameters of API group. Helpful when you use the same
|
|
4503
|
-
* api for different providers to avoid hardcoding RPS inside each provider what can cause mistakes
|
|
4504
|
-
* @param [specificHeaders] {Object} contains specific keys (headers) and values (their content) if needed for this provider
|
|
4505
|
-
* @param [maxPageLength] {number} optional number of items per page if the request supports pagination
|
|
4506
|
-
*/
|
|
4507
|
-
function ExternalApiProvider(endpoint, httpMethod, timeout, apiGroup, specificHeaders, maxPageLength) {
|
|
4508
|
-
var _maxPageLength, _specificHeaders;
|
|
4509
|
-
if (specificHeaders === void 0) {
|
|
4510
|
-
specificHeaders = {};
|
|
4511
|
-
}
|
|
4512
|
-
if (maxPageLength === void 0) {
|
|
4513
|
-
maxPageLength = Number.MAX_SAFE_INTEGER;
|
|
4514
|
-
}
|
|
4515
|
-
this.endpoint = endpoint;
|
|
4516
|
-
this.httpMethod = httpMethod != null ? httpMethod : "get";
|
|
4517
|
-
// TODO: [refactoring, critical] We have two timeouts for robust data retrieval - here and inside the service method call, need to remain the only
|
|
4518
|
-
this.timeout = timeout != null ? timeout : 10000;
|
|
4519
|
-
// TODO: [refactoring, critical] We need single place for all RPSes as we use them as hardcoded constants now inside different services
|
|
4520
|
-
this.apiGroup = apiGroup;
|
|
4521
|
-
this.maxPageLength = (_maxPageLength = maxPageLength) != null ? _maxPageLength : Number.MAX_SAFE_INTEGER;
|
|
4522
|
-
this.niceFactor = 1;
|
|
4523
|
-
this.specificHeaders = (_specificHeaders = specificHeaders) != null ? _specificHeaders : {};
|
|
4524
|
-
}
|
|
4525
|
-
var _proto = ExternalApiProvider.prototype;
|
|
4526
|
-
_proto.getRps = function getRps() {
|
|
4527
|
-
var _this$apiGroup$rps;
|
|
4528
|
-
return (_this$apiGroup$rps = this.apiGroup.rps) != null ? _this$apiGroup$rps : 2;
|
|
4529
|
-
};
|
|
4530
|
-
_proto.isRpsExceeded = function isRpsExceeded() {
|
|
4531
|
-
return this.apiGroup.isRpsExceeded();
|
|
4532
|
-
};
|
|
4533
|
-
_proto.actualizeLastCalledTimestamp = function actualizeLastCalledTimestamp() {
|
|
4534
|
-
this.apiGroup.actualizeLastCalledTimestamp();
|
|
4535
|
-
};
|
|
4536
|
-
_proto.getApiGroupId = function getApiGroupId() {
|
|
4537
|
-
return this.apiGroup.id;
|
|
4538
|
-
}
|
|
4539
|
-
|
|
4540
|
-
/**
|
|
4541
|
-
* Some endpoint can require several sub requests. Example is one request to get confirmed transactions
|
|
4542
|
-
* and another request for unconfirmed transactions. You should override this method to return true for such requests.
|
|
4543
|
-
*
|
|
4544
|
-
* @return {boolean} true if this provider requires several requests to retrieve the data
|
|
4545
|
-
*/;
|
|
4546
|
-
_proto.doesRequireSubRequests = function doesRequireSubRequests() {
|
|
4547
|
-
return false;
|
|
4548
|
-
}
|
|
4549
|
-
|
|
4550
|
-
/**
|
|
4551
|
-
* Some endpoint support pagination. Override this method if so and implement corresponding methods.
|
|
4552
|
-
*
|
|
4553
|
-
* @return {boolean} true if this provider requires several requests to retrieve the data
|
|
4554
|
-
*/;
|
|
4555
|
-
_proto.doesSupportPagination = function doesSupportPagination() {
|
|
4556
|
-
return false;
|
|
4557
|
-
}
|
|
4558
|
-
|
|
4559
|
-
/**
|
|
4560
|
-
* Composes a query string to be added to the endpoint of this provider.
|
|
4561
|
-
*
|
|
4562
|
-
* @param params {any[]} params array passed to the RobustExternalAPICallerService
|
|
4563
|
-
* @param [subRequestIndex] {number} optional number of the sub-request the call is performed for
|
|
4564
|
-
* @returns {string} query string to be concatenated with endpoint
|
|
4565
|
-
*/;
|
|
4566
|
-
_proto.composeQueryString = function composeQueryString(params, subRequestIndex) {
|
|
4567
|
-
return "";
|
|
4568
|
-
}
|
|
4569
|
-
|
|
4570
|
-
/**
|
|
4571
|
-
* Composes a body to be added to the request
|
|
4572
|
-
*
|
|
4573
|
-
* @param params {any[]} params array passed to the RobustExternalAPICallerService
|
|
4574
|
-
* @param [subRequestIndex] {number} optional number of the sub-request the call is performed for
|
|
4575
|
-
* @returns {string}
|
|
4576
|
-
*/;
|
|
4577
|
-
_proto.composeBody = function composeBody(params, subRequestIndex) {
|
|
4578
|
-
return "";
|
|
4579
|
-
}
|
|
4580
|
-
|
|
4581
|
-
/**
|
|
4582
|
-
* Extracts data from the response and returns it
|
|
4583
|
-
*
|
|
4584
|
-
* @param response {Object} HTTP response returned by provider
|
|
4585
|
-
* @param [params] {any[]} params array passed to the RobustExternalAPICallerService
|
|
4586
|
-
* @param [subRequestIndex] {number} optional number of the sub-request the call is performed for
|
|
4587
|
-
* @param iterationsData {any[]} array of data retrieved from previous sub-requests
|
|
4588
|
-
* @returns {any}
|
|
4589
|
-
*/;
|
|
4590
|
-
_proto.getDataByResponse = function getDataByResponse(response, params, subRequestIndex, iterationsData) {
|
|
4591
|
-
return [];
|
|
4592
|
-
}
|
|
4593
|
-
|
|
4594
|
-
/**
|
|
4595
|
-
* Function changing the query string according to page number and previous response
|
|
4596
|
-
* Only for endpoints supporting pagination
|
|
4597
|
-
*
|
|
4598
|
-
* @param params {any[]} params array passed to the RobustExternalAPICallerService
|
|
4599
|
-
* @param previousResponse {Object} HTTP response returned by provider for previous call (previous page)
|
|
4600
|
-
* @param pageNumber {number} new page number. We count from 0. You need to manually increment with 1 if your
|
|
4601
|
-
* provider counts pages starting with 1
|
|
4602
|
-
* @param [subRequestIndex] {number} optional number of the sub-request the call is performed for
|
|
4603
|
-
* @returns {any[]}
|
|
4604
|
-
*/;
|
|
4605
|
-
_proto.changeQueryParametersForPageNumber = function changeQueryParametersForPageNumber(params, previousResponse, pageNumber, subRequestIndex) {
|
|
4606
|
-
return params;
|
|
4607
|
-
}
|
|
4608
|
-
|
|
4609
|
-
/**
|
|
4610
|
-
* Function checking whether the response is for the last page to stop requesting for a next page.
|
|
4611
|
-
* Only for endpoints supporting pagination.
|
|
4612
|
-
*
|
|
4613
|
-
* @param previousResponse {Object} HTTP response returned by provider for previous call (previous page)
|
|
4614
|
-
* @param currentResponse {Object} HTTP response returned by provider for current call (current page, next after the previous)
|
|
4615
|
-
* @param currentPageNumber {number} current page number (for current response)
|
|
4616
|
-
* @param [subRequestIndex] {number} optional number of the sub-request the call is performed for
|
|
4617
|
-
* @returns {boolean}
|
|
4618
|
-
*/;
|
|
4619
|
-
_proto.checkWhetherResponseIsForLastPage = function checkWhetherResponseIsForLastPage(previousResponse, currentResponse, currentPageNumber, subRequestIndex) {
|
|
4620
|
-
return true;
|
|
4621
|
-
}
|
|
4622
|
-
|
|
4623
|
-
/**
|
|
4624
|
-
* Resets the nice factor to default value
|
|
4625
|
-
*/;
|
|
4626
|
-
_proto.resetNiceFactor = function resetNiceFactor() {
|
|
4627
|
-
this.niceFactor = 1;
|
|
4628
|
-
}
|
|
4629
|
-
|
|
4630
|
-
/**
|
|
4631
|
-
* Internal method used for requests requiring sub-requests.
|
|
4632
|
-
*
|
|
4633
|
-
* @param iterationsData {any[]} iterations data retrieved from getDataByResponse called per sub-request.
|
|
4634
|
-
* @return {any} by default flatten the passed iterations data array. Should be redefined if you need another logic.
|
|
4635
|
-
*/;
|
|
4636
|
-
_proto.incorporateIterationsData = function incorporateIterationsData(iterationsData) {
|
|
4637
|
-
return iterationsData.flat();
|
|
4638
|
-
};
|
|
4639
|
-
return ExternalApiProvider;
|
|
4640
|
-
}();
|
|
4641
|
-
|
|
4642
|
-
/**
|
|
4643
|
-
* Models a group of APIs provided by the same owner and used for different services in our app.
|
|
4644
|
-
* It means we need to mention RPS several times for each usage and also have some holder of last call timestamp per
|
|
4645
|
-
* api group. So this concept allows to use it for exact ExternalApiProvider and make sure that you use the same
|
|
4646
|
-
* RPS value and make decisions on base of the same timestamp of last call to the API group owner.
|
|
4647
|
-
*/
|
|
4648
|
-
var ApiGroup = /*#__PURE__*/function () {
|
|
4649
|
-
function ApiGroup(id, rps, backendProxyIdGenerator) {
|
|
4650
|
-
if (backendProxyIdGenerator === void 0) {
|
|
4651
|
-
backendProxyIdGenerator = null;
|
|
4652
|
-
}
|
|
4653
|
-
this.id = id;
|
|
4654
|
-
this.rps = rps;
|
|
4655
|
-
this.lastCalledTimestamp = null;
|
|
4656
|
-
this.backendProxyIdGenerator = backendProxyIdGenerator;
|
|
4657
|
-
}
|
|
4658
|
-
var _proto = ApiGroup.prototype;
|
|
4659
|
-
_proto.isRpsExceeded = function isRpsExceeded() {
|
|
4660
|
-
var _this$lastCalledTimes;
|
|
4661
|
-
return ((_this$lastCalledTimes = this.lastCalledTimestamp) != null ? _this$lastCalledTimes : 0) + Math.floor(1000 / this.rps) > Date.now();
|
|
4662
|
-
};
|
|
4663
|
-
_proto.actualizeLastCalledTimestamp = function actualizeLastCalledTimestamp() {
|
|
4664
|
-
this.lastCalledTimestamp = Date.now();
|
|
4665
|
-
};
|
|
4666
|
-
return ApiGroup;
|
|
4667
|
-
}();
|
|
4668
|
-
var ApiGroups = {
|
|
4669
|
-
/**
|
|
4670
|
-
* Currently we use free version of etherscan provider with 0.2 RPS. But we have API key with 100k requests free
|
|
4671
|
-
* per month. So we can add it if not enough current RPS.
|
|
4672
|
-
*/
|
|
4673
|
-
ETHERSCAN: new ApiGroup("etherscan", 0.17),
|
|
4674
|
-
// Actually 0.2 but fails sometime, so we use smaller
|
|
4675
|
-
ALCHEMY: new ApiGroup("alchemy", 0.3, function (networkKey) {
|
|
4676
|
-
return "alchemy-" + networkKey;
|
|
4677
|
-
}),
|
|
4678
|
-
BLOCKSTREAM: new ApiGroup("blockstream", 0.2),
|
|
4679
|
-
BLOCKCHAIN_INFO: new ApiGroup("blockchain.info", 1),
|
|
4680
|
-
BLOCKNATIVE: new ApiGroup("blocknative", 0.5),
|
|
4681
|
-
ETHGASSTATION: new ApiGroup("ethgasstation", 0.5),
|
|
4682
|
-
TRONGRID: new ApiGroup("trongrid", 0.3, function (networkKey) {
|
|
4683
|
-
return "trongrid-" + networkKey;
|
|
4684
|
-
}),
|
|
4685
|
-
TRONSCAN: new ApiGroup("tronscan", 0.3),
|
|
4686
|
-
GETBLOCK: new ApiGroup("getblock", 0.3),
|
|
4687
|
-
COINCAP: new ApiGroup("coincap", 0.5),
|
|
4688
|
-
// 200 per minute without API key
|
|
4689
|
-
COINGECKO: new ApiGroup("coingecko", 0.9),
|
|
4690
|
-
// actually 0.13-0.5 according to the docs but we use smaller due to expirienced frequent abuses
|
|
4691
|
-
MESSARI: new ApiGroup("messari", 0.2),
|
|
4692
|
-
BTCCOM: new ApiGroup("btccom", 0.2),
|
|
4693
|
-
BITAPS: new ApiGroup("bitaps", 0.25),
|
|
4694
|
-
// Docs say that RPS is 3 but using it causes frequent 429 HTTP errors
|
|
4695
|
-
CEX: new ApiGroup("cex", 0.5),
|
|
4696
|
-
// Just assumption for RPS
|
|
4697
|
-
BIGDATACLOUD: new ApiGroup("bigdatacloud", 1),
|
|
4698
|
-
// Just assumption for RPS
|
|
4699
|
-
TRACKIP: new ApiGroup("trackip", 1),
|
|
4700
|
-
// Just assumption for RPS
|
|
4701
|
-
IPIFY: new ApiGroup("ipify", 1),
|
|
4702
|
-
// Just assumption for RPS
|
|
4703
|
-
WHATISMYIPADDRESS: new ApiGroup("whatismyipaddress", 1),
|
|
4704
|
-
// Just assumption for RPS
|
|
4705
|
-
EXCHANGERATE: new ApiGroup("exchangerate", 1),
|
|
4706
|
-
// Just assumption for RPS
|
|
4707
|
-
FRANKFURTER: new ApiGroup("frankfurter", 1),
|
|
4708
|
-
// Just assumption for RPS
|
|
4709
|
-
BITGO: new ApiGroup("bitgo", 1),
|
|
4710
|
-
// Just assumption for RPS
|
|
4711
|
-
BITCOINER: new ApiGroup("bitcoiner", 1),
|
|
4712
|
-
// Just assumption for RPS
|
|
4713
|
-
BITCORE: new ApiGroup("bitcore", 1),
|
|
4714
|
-
// Just assumption for RPS
|
|
4715
|
-
// BLOCKCHAIR: new ApiGroup("blockchair", 0.04), // this provider require API key for commercial use (10usd 10000 reqs), we will add it later
|
|
4716
|
-
MEMPOOL: new ApiGroup("mempool", 0.2) // Just assumption for RPS
|
|
4717
|
-
};
|
|
4718
|
-
|
|
4719
4816
|
var ExistingSwap =
|
|
4720
4817
|
/**
|
|
4721
4818
|
* @param swapId {string}
|
|
@@ -6707,6 +6804,7 @@ exports.ExistingSwap = ExistingSwap;
|
|
|
6707
6804
|
exports.ExistingSwapWithFiatData = ExistingSwapWithFiatData;
|
|
6708
6805
|
exports.ExternalApiProvider = ExternalApiProvider;
|
|
6709
6806
|
exports.FiatCurrenciesService = FiatCurrenciesService;
|
|
6807
|
+
exports.IpAddressProvider = IpAddressProvider;
|
|
6710
6808
|
exports.LoadingDots = LoadingDots;
|
|
6711
6809
|
exports.Logger = Logger;
|
|
6712
6810
|
exports.LogsStorage = LogsStorage;
|