@shopgate/pwa-core 7.30.0-alpha.7 → 7.30.0-alpha.8
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/classes/AppCommand/index.js +115 -11
- package/classes/AppCommand/spec.js +260 -6
- package/classes/AppCommandRequest/index.js +129 -20
- package/classes/AppPermissionsRequest/AppPermissionsRequest.js +45 -7
- package/classes/AppPermissionsRequest/GetAppPermissionsRequest.js +48 -9
- package/classes/AppPermissionsRequest/RequestAppPermissionsRequest.js +54 -9
- package/classes/Bridge/index.js +34 -4
- package/classes/Bridge/spec.js +24 -1
- package/classes/BrightnessRequest/index.js +59 -10
- package/classes/BrightnessRequest/spec.js +111 -6
- package/classes/BrowserConnector/index.js +180 -26
- package/classes/Conditioner/index.js +74 -8
- package/classes/Conditioner/spec.js +75 -1
- package/classes/DataRequest/index.js +116 -13
- package/classes/DevServerBridge/index.js +86 -9
- package/classes/DevServerBridge/spec.js +231 -14
- package/classes/ErrorManager/index.js +144 -20
- package/classes/ErrorManager/spec.js +244 -2
- package/classes/Event/index.js +101 -15
- package/classes/HttpRequest/index.js +182 -21
- package/classes/PipelineDependencies/index.js +42 -6
- package/classes/PipelineDependencies/spec.js +46 -3
- package/classes/PipelineManager/index.js +517 -71
- package/classes/PipelineManager/spec.js +733 -15
- package/classes/PipelineRequest/index.js +167 -19
- package/classes/PipelineRequest/mock.js +118 -21
- package/classes/PipelineRequest/spec.js +333 -2
- package/classes/PipelineSequence/index.js +34 -6
- package/classes/Request/index.js +61 -13
- package/classes/RequestBuffer/index.js +43 -6
- package/classes/RequestManager/index.js +216 -33
- package/classes/RequestManager/spec.js +188 -1
- package/classes/Scanner/index.js +246 -67
- package/classes/ScannerEvent/index.js +23 -9
- package/classes/ScannerEventHandler/index.js +39 -16
- package/classes/ScannerEventListener/index.js +84 -24
- package/classes/ScannerManager/ScanProcessingError.js +11 -3
- package/classes/ScannerManager/index.js +133 -21
- package/classes/WebStorageRequest/index.js +76 -9
- package/commands/analyticsSetCustomValues.js +8 -2
- package/commands/appPermissions.js +10 -3
- package/commands/brightness.js +33 -5
- package/commands/broadcastEvent.js +8 -2
- package/commands/cleanTab.js +11 -3
- package/commands/closeInAppBrowser.js +22 -2
- package/commands/flushTab.js +8 -2
- package/commands/getWebStorageEntry.js +11 -2
- package/commands/hideMenuBar.js +8 -2
- package/commands/hideNavigationBar.js +8 -2
- package/commands/hideSplashScreen.js +8 -2
- package/commands/onload.js +13 -3
- package/commands/openAppSettings.js +8 -2
- package/commands/openPage.js +8 -2
- package/commands/openPageExtern.js +8 -2
- package/commands/performCommandsAfterDelay.js +11 -3
- package/commands/plotProjects.js +65 -7
- package/commands/popTabToRoot.js +11 -3
- package/commands/registerEvents.js +10 -2
- package/commands/scanner.js +76 -7
- package/commands/setCookie.js +8 -2
- package/commands/setDebugLoggingEnabled.js +8 -2
- package/commands/setScrollingEnabled.js +7 -2
- package/commands/setWebStorageEntry.js +8 -2
- package/commands/shareItem.js +18 -2
- package/commands/showNavigationBar.js +8 -2
- package/commands/showTab.js +13 -2
- package/commands/unifiedTracking.js +128 -30
- package/constants/AppCommands.js +6 -1
- package/constants/AppEvents.js +9 -1
- package/constants/AppPermissions.js +57 -13
- package/constants/Command.js +1 -1
- package/constants/ErrorHandleTypes.js +2 -1
- package/constants/ErrorManager.js +15 -1
- package/constants/Pipeline.js +52 -17
- package/constants/ProcessTypes.js +3 -1
- package/constants/RequestManagerModes.js +19 -7
- package/constants/RequestTypes.js +2 -1
- package/constants/Scanner.js +39 -10
- package/constants/Trilean.js +6 -1
- package/emitters/ui.js +2 -1
- package/helpers/index.js +66 -8
- package/helpers/logGroup.js +56 -8
- package/helpers/version.js +216 -22
- package/index.js +60 -5
- package/package.json +1 -1
|
@@ -1,126 +1,572 @@
|
|
|
1
|
-
|
|
1
|
+
import AppCommand from "../AppCommand";
|
|
2
|
+
import event from "../Event";
|
|
3
|
+
import errorManager from "../ErrorManager";
|
|
4
|
+
import pipelineDependencies from "../PipelineDependencies";
|
|
5
|
+
import pipelineSequence from "../PipelineSequence";
|
|
6
|
+
import * as errorSources from "../../constants/ErrorManager";
|
|
7
|
+
import * as errorHandleTypes from "../../constants/ErrorHandleTypes";
|
|
8
|
+
import * as processTypes from "../../constants/ProcessTypes";
|
|
9
|
+
import { ETIMEOUT, ENETUNREACH } from "../../constants/Pipeline";
|
|
10
|
+
import logGroup from "../../helpers/logGroup";
|
|
11
|
+
|
|
12
|
+
/**
|
|
2
13
|
* The PipelineManager class.
|
|
3
14
|
* Manages requests, retries responses and timeouts of PipelineRequest instances.
|
|
4
|
-
*/
|
|
15
|
+
*/
|
|
16
|
+
class PipelineManager {
|
|
17
|
+
/**
|
|
5
18
|
* Constructor.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
*/
|
|
20
|
+
constructor() {
|
|
21
|
+
/**
|
|
22
|
+
* Sanitizes error objects.
|
|
23
|
+
* @param {Object} error An error object.
|
|
24
|
+
* @return {Object}
|
|
25
|
+
*/
|
|
26
|
+
this.sanitizeError = (error = {}) => {
|
|
27
|
+
let sanitizedCode = error.code;
|
|
28
|
+
if (sanitizedCode) {
|
|
29
|
+
sanitizedCode = sanitizedCode.toString();
|
|
30
|
+
}
|
|
31
|
+
if (sanitizedCode === '-999') {
|
|
32
|
+
// Pipeline / socket timeout code from the OS.
|
|
33
|
+
sanitizedCode = ETIMEOUT;
|
|
34
|
+
} else if (sanitizedCode === '-1000') {
|
|
35
|
+
// Network IO exception
|
|
36
|
+
sanitizedCode = ENETUNREACH;
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
...error,
|
|
40
|
+
code: sanitizedCode
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
// The open requests at any given time.
|
|
44
|
+
this.requests = new Map();
|
|
45
|
+
|
|
46
|
+
// The pipelines which have currently running requests.
|
|
47
|
+
this.pipelines = new Map();
|
|
48
|
+
|
|
49
|
+
// The error codes that should be suppressed.
|
|
50
|
+
this.suppressedErrors = [];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
16
54
|
* Adds error code(s) to the suppressed collection.
|
|
17
55
|
* @param {Array|string} code The code(s) of the errors to suppress.
|
|
18
|
-
*/
|
|
56
|
+
*/
|
|
57
|
+
addSuppressedErrors(code) {
|
|
58
|
+
const codes = [].concat(code);
|
|
59
|
+
this.suppressedErrors = [...this.suppressedErrors, ...codes];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
19
63
|
* Adds a new PipelineRequest instance.
|
|
20
64
|
* @param {PipelineRequest} request The pipeline request instance.
|
|
21
65
|
* @return {Promise}
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
|
|
66
|
+
*/
|
|
67
|
+
add(request) {
|
|
68
|
+
request.createSerial(`${request.name}.v${request.version}`);
|
|
69
|
+
request.createEventCallbackName('pipelineResponse');
|
|
70
|
+
|
|
71
|
+
// Store the request by serial to be accessible later.
|
|
72
|
+
this.requests.set(request.serial, {
|
|
73
|
+
request,
|
|
74
|
+
retries: request.retries,
|
|
75
|
+
finished: false,
|
|
76
|
+
deferred: false,
|
|
77
|
+
bypass: false,
|
|
78
|
+
timer: null
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Try to dispatch immediately (can be blocked by dependency)
|
|
82
|
+
return this.dispatch(request.serial);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
25
86
|
* Dispatches a PipelineRequest instance.
|
|
26
87
|
* @param {string} serial The pipeline request serial.
|
|
27
88
|
* @return {Promise}
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
entry.
|
|
32
|
-
|
|
89
|
+
*/
|
|
90
|
+
dispatch(serial) {
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
const entry = this.requests.get(serial);
|
|
93
|
+
const {
|
|
94
|
+
name
|
|
95
|
+
} = entry.request;
|
|
96
|
+
|
|
97
|
+
// Create and subscribe a pipeline response handler (+ store in the request for later access)
|
|
98
|
+
this.createRequestCallback(serial, resolve, reject);
|
|
99
|
+
|
|
100
|
+
// Pipeline execution can be moved to later, based on the "pipeline dependency" setup.
|
|
101
|
+
if (this.hasRunningDependencies(name)) {
|
|
102
|
+
// Requests with running dependencies will be sent after the dependencies are finished.
|
|
103
|
+
entry.deferred = true;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Trigger the PipelineRequest AppCommand
|
|
108
|
+
this.sendRequest(serial);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
33
113
|
* Creates the request callback.
|
|
34
114
|
* @param {string} serial The pipeline request serial.
|
|
35
115
|
* @param {Function} resolve Resolves the promise.
|
|
36
116
|
* @param {Function} reject Rejects the promise.
|
|
37
|
-
*/
|
|
38
|
-
|
|
117
|
+
*/
|
|
118
|
+
createRequestCallback(serial, resolve, reject) {
|
|
119
|
+
const entry = this.requests.get(serial);
|
|
120
|
+
const {
|
|
121
|
+
request
|
|
122
|
+
} = entry;
|
|
123
|
+
|
|
124
|
+
// Add the executor functions to the request object.
|
|
125
|
+
request.resolve = resolve;
|
|
126
|
+
request.reject = reject;
|
|
127
|
+
|
|
128
|
+
/**
|
|
39
129
|
* A callback that is invoked when a pipeline response comes in.
|
|
40
130
|
* @param {Object} error A pipeline error object.
|
|
41
131
|
* @param {string} serialResult A pipeline serial.
|
|
42
132
|
* @param {Object} output The pipeline response payload.
|
|
43
|
-
*/
|
|
44
|
-
request.
|
|
45
|
-
|
|
133
|
+
*/
|
|
134
|
+
request.callback = (error, serialResult, output = undefined) => {
|
|
135
|
+
// Add the relevant response properties to the request object.
|
|
136
|
+
request.error = error;
|
|
137
|
+
request.output = output;
|
|
138
|
+
entry.finished = true;
|
|
139
|
+
switch (request.process) {
|
|
140
|
+
case processTypes.PROCESS_SEQUENTIAL:
|
|
141
|
+
this.handleResultSequence();
|
|
142
|
+
break;
|
|
143
|
+
case processTypes.PROCESS_LAST:
|
|
144
|
+
this.handleResultLast(serialResult);
|
|
145
|
+
break;
|
|
146
|
+
default:
|
|
147
|
+
this.handleResult(serialResult);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// Register a response listener for the request.
|
|
152
|
+
event.addCallback(request.getEventCallbackName(), request.callback);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
46
156
|
* Checks whether a pipeline request has running dependencies.
|
|
47
157
|
* @param {string} pipelineName The name of the pipeline.
|
|
48
158
|
* @return {boolean}
|
|
49
|
-
*/
|
|
50
|
-
|
|
159
|
+
*/
|
|
160
|
+
hasRunningDependencies(pipelineName) {
|
|
161
|
+
const dependencies = pipelineDependencies.get(pipelineName);
|
|
162
|
+
let found = 0;
|
|
163
|
+
dependencies.forEach(dependency => {
|
|
164
|
+
// Check if the dependency exists and is ongoing.
|
|
165
|
+
if (this.pipelines.has(dependency) && this.pipelines.get(dependency) > 0) {
|
|
166
|
+
found += 1;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
return found > 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
51
173
|
* Sends deferred requests when they don't have running dependencies anymore.
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
|
|
174
|
+
*/
|
|
175
|
+
handleDeferredRequests() {
|
|
176
|
+
this.requests.forEach(entry => {
|
|
177
|
+
const {
|
|
178
|
+
deferred,
|
|
179
|
+
request: {
|
|
180
|
+
name,
|
|
181
|
+
serial
|
|
182
|
+
}
|
|
183
|
+
} = entry;
|
|
184
|
+
// Stop processing When the current request isn't deferred, or still has running dependencies.
|
|
185
|
+
if (!deferred || this.hasRunningDependencies(name)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// eslint-disable-next-line no-param-reassign
|
|
190
|
+
entry.deferred = false;
|
|
191
|
+
this.sendRequest(serial);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
55
196
|
* Handles the request timeout.
|
|
56
197
|
* @param {string} serial The pipeline request serial.
|
|
57
|
-
*/
|
|
58
|
-
|
|
198
|
+
*/
|
|
199
|
+
handleTimeout(serial) {
|
|
200
|
+
const entry = this.requests.get(serial);
|
|
201
|
+
const {
|
|
202
|
+
request,
|
|
203
|
+
retries
|
|
204
|
+
} = entry;
|
|
205
|
+
entry.timer = setTimeout(() => {
|
|
206
|
+
if (!retries) {
|
|
207
|
+
const error = {
|
|
208
|
+
message: `Pipeline '${request.name}.v${request.version}' timed out after ${request.timeout}ms`,
|
|
209
|
+
code: ETIMEOUT
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
// Invoke the request callback with the timeout error.
|
|
213
|
+
request.callback(error, serial);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
this.decrementRetries(serial);
|
|
217
|
+
this.sendRequest(serial);
|
|
218
|
+
}, request.timeout);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
59
221
|
* Handles a pipeline error.
|
|
60
222
|
* @param {string} serial The pipeline request serial.
|
|
61
|
-
*/
|
|
62
|
-
|
|
223
|
+
*/
|
|
224
|
+
handleError(serial) {
|
|
225
|
+
const {
|
|
226
|
+
request
|
|
227
|
+
} = this.requests.get(serial);
|
|
228
|
+
const pipelineName = this.getPipelineNameBySerial(serial);
|
|
229
|
+
request.error = this.sanitizeError(request.error);
|
|
230
|
+
const {
|
|
231
|
+
code,
|
|
232
|
+
message,
|
|
233
|
+
validationErrors,
|
|
234
|
+
errors,
|
|
235
|
+
additionalParams,
|
|
236
|
+
translated
|
|
237
|
+
} = request.error || {};
|
|
238
|
+
const err = new Error(message);
|
|
239
|
+
err.code = code;
|
|
240
|
+
err.message = message;
|
|
241
|
+
if (validationErrors !== undefined) {
|
|
242
|
+
err.validationErrors = validationErrors;
|
|
243
|
+
}
|
|
244
|
+
if (errors !== undefined) {
|
|
245
|
+
err.errors = errors;
|
|
246
|
+
}
|
|
247
|
+
let handleError = request.handleErrors === errorHandleTypes.ERROR_HANDLE_DEFAULT;
|
|
248
|
+
|
|
249
|
+
// Don't handle generally suppressed or via pipeline request blacklisted errors
|
|
250
|
+
if (this.suppressedErrors.includes(code) || request.errorBlacklist.includes(code)) {
|
|
251
|
+
handleError = false;
|
|
252
|
+
}
|
|
253
|
+
if (handleError) {
|
|
254
|
+
errorManager.queue({
|
|
255
|
+
source: errorSources.SOURCE_PIPELINE,
|
|
256
|
+
context: pipelineName,
|
|
257
|
+
meta: {
|
|
258
|
+
input: request.input,
|
|
259
|
+
behavior: request.getErrorResponseBehavior(),
|
|
260
|
+
additionalParams,
|
|
261
|
+
translated
|
|
262
|
+
},
|
|
263
|
+
code,
|
|
264
|
+
message
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
err.handled = handleError;
|
|
268
|
+
if (!Array.isArray(request.reject)) {
|
|
269
|
+
request.reject(err);
|
|
270
|
+
} else {
|
|
271
|
+
request.reject.forEach(reject => {
|
|
272
|
+
reject(err);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
63
278
|
* Handles the result of a dispatched PipelineRequest.
|
|
64
279
|
* @param {string} serial The pipeline request serial.
|
|
65
|
-
*/
|
|
66
|
-
|
|
67
|
-
this.
|
|
280
|
+
*/
|
|
281
|
+
handleResult(serial) {
|
|
282
|
+
const entry = this.requests.get(serial);
|
|
283
|
+
const {
|
|
284
|
+
request
|
|
285
|
+
} = entry;
|
|
286
|
+
const {
|
|
287
|
+
input,
|
|
288
|
+
error,
|
|
289
|
+
output
|
|
290
|
+
} = request;
|
|
291
|
+
const pipelineName = this.getPipelineNameBySerial(serial);
|
|
292
|
+
const callbackName = request.getEventCallbackName();
|
|
293
|
+
this.decrementPipelineOngoing(serial);
|
|
294
|
+
let logColor = '#307bc2';
|
|
295
|
+
if (request.error) {
|
|
296
|
+
logColor = '#ff0000';
|
|
297
|
+
this.handleError(serial);
|
|
298
|
+
} else if (!Array.isArray(request.resolve)) {
|
|
299
|
+
request.resolve(request.output);
|
|
300
|
+
} else {
|
|
301
|
+
request.resolve.forEach(resolve => {
|
|
302
|
+
resolve(request.output);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
logGroup(`PipelineResponse %c${pipelineName}`, {
|
|
306
|
+
input,
|
|
307
|
+
error,
|
|
308
|
+
output,
|
|
309
|
+
serial
|
|
310
|
+
}, logColor);
|
|
311
|
+
|
|
312
|
+
// Cleanup.
|
|
313
|
+
event.removeCallback(callbackName, request.callback);
|
|
314
|
+
if (entry.timer) {
|
|
315
|
+
clearTimeout(entry.timer);
|
|
316
|
+
}
|
|
317
|
+
this.removeRequestFromPipelineSequence(serial);
|
|
318
|
+
this.requests.delete(serial);
|
|
319
|
+
|
|
320
|
+
// Take care about requests that were deferred because of running dependencies.
|
|
321
|
+
this.handleDeferredRequests();
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
68
325
|
* Handles the results sequentially.
|
|
69
|
-
*/
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
326
|
+
*/
|
|
327
|
+
handleResultSequence() {
|
|
328
|
+
// Create a copy of the sequence, to avoid side effects when entries are removed.
|
|
329
|
+
const [...sequence] = pipelineSequence.get();
|
|
330
|
+
for (let i = 0; i < sequence.length; i += 1) {
|
|
331
|
+
const serial = sequence[i];
|
|
332
|
+
const entry = this.requests.get(serial);
|
|
333
|
+
if (!entry) {
|
|
334
|
+
// Remove sequence entries without request.
|
|
335
|
+
this.removeRequestFromPipelineSequence(serial);
|
|
336
|
+
} else if (!entry.finished) {
|
|
337
|
+
// Stop sequence procession at the first not finished request.
|
|
338
|
+
break;
|
|
339
|
+
} else {
|
|
340
|
+
this.handleResult(serial);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
73
346
|
* Handles only the last result of a list of calls to the same pipeline.
|
|
74
347
|
* @param {string} serial The serial of the incoming response
|
|
75
|
-
*/
|
|
76
|
-
|
|
77
|
-
this.
|
|
348
|
+
*/
|
|
349
|
+
handleResultLast(serial) {
|
|
350
|
+
const entry = this.requests.get(serial);
|
|
351
|
+
|
|
352
|
+
// Requests which are queried later mark all previous ones to be bypassed ...
|
|
353
|
+
if (entry.bypass) {
|
|
354
|
+
// ... like this one - just clean up
|
|
355
|
+
this.decrementPipelineOngoing(serial);
|
|
356
|
+
this.requests.delete(serial);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
this.handleResult(serial);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
78
363
|
* Sends the actual request command.
|
|
79
364
|
* @param {string} serial The pipeline request serial.
|
|
80
|
-
*/
|
|
81
|
-
|
|
365
|
+
*/
|
|
366
|
+
sendRequest(serial) {
|
|
367
|
+
const entry = this.requests.get(serial);
|
|
368
|
+
if (!entry) {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
this.incrementPipelineOngoing(serial);
|
|
372
|
+
this.handleTimeout(serial);
|
|
373
|
+
this.addRequestToPipelineSequence(serial);
|
|
374
|
+
this.bypassOutdatedRequests(serial);
|
|
375
|
+
const prefix = this.getRetriesPrefix(serial);
|
|
376
|
+
const pipelineName = this.getPipelineNameBySerial(serial);
|
|
377
|
+
logGroup(`${prefix}PipelineRequest %c${pipelineName}`, {
|
|
378
|
+
input: entry.request.input,
|
|
379
|
+
serial: entry.request.serial
|
|
380
|
+
}, '#32ac5c');
|
|
381
|
+
|
|
382
|
+
// Send the pipeline request.
|
|
383
|
+
const command = new AppCommand();
|
|
384
|
+
command.setCommandName('sendPipelineRequest').setLibVersion('12.0').dispatch({
|
|
385
|
+
name: pipelineName,
|
|
386
|
+
serial: entry.request.serial,
|
|
387
|
+
input: entry.request.input,
|
|
388
|
+
...(entry.request.trusted && {
|
|
389
|
+
type: 'trusted'
|
|
390
|
+
})
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
82
395
|
* Adds sequentially processed requests to the pipeline sequence.
|
|
83
396
|
* @param {string} serial The pipeline request serial.
|
|
84
|
-
*/
|
|
397
|
+
*/
|
|
398
|
+
addRequestToPipelineSequence(serial) {
|
|
399
|
+
const {
|
|
400
|
+
request
|
|
401
|
+
} = this.requests.get(serial);
|
|
402
|
+
if (request.process === processTypes.PROCESS_SEQUENTIAL) {
|
|
403
|
+
pipelineSequence.set(serial);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
85
408
|
* When a new request is added with the "PROCESS_LAST" type it causes previous requests with the
|
|
86
409
|
* same pipeline name (with the flag being set as well) to be marked as bypassed.
|
|
87
410
|
* When a response of a bypassed request comes in, it will be ignored.
|
|
88
411
|
* @param {string} serial The pipeline request serial.
|
|
89
|
-
*/
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
412
|
+
*/
|
|
413
|
+
bypassOutdatedRequests(serial) {
|
|
414
|
+
const {
|
|
415
|
+
request
|
|
416
|
+
} = this.requests.get(serial);
|
|
417
|
+
if (request.process !== processTypes.PROCESS_LAST) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Get only those pipelines with the same name
|
|
422
|
+
const groupedRequests = Array.from(this.requests.values()).filter(entry => entry.request.name === request.name)
|
|
423
|
+
// Single requests in the group can still be interested in the result, so don't bypass the
|
|
424
|
+
// ones without the "PROCESS_LAST" flag
|
|
425
|
+
.filter(entry => entry.request.process === processTypes.PROCESS_LAST);
|
|
426
|
+
|
|
427
|
+
// Nothing to do, if there is only one request, because it is logically the last one
|
|
428
|
+
if (groupedRequests.length <= 1) {
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Convert to a list of resolvers and rejectors, because it will need to resolve all previous
|
|
433
|
+
// promises, because they will be bypassed, as they don't have any valid data to resolve with.
|
|
434
|
+
if (!Array.isArray(request.resolve)) {
|
|
435
|
+
request.resolve = [request.resolve];
|
|
436
|
+
}
|
|
437
|
+
if (!Array.isArray(request.reject)) {
|
|
438
|
+
request.reject = [request.reject];
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Bypass only the requests up to, but excluding the current one
|
|
442
|
+
const currentIndex = groupedRequests.length - 1; // The current one is the last in the group
|
|
443
|
+
groupedRequests.forEach((entry, i) => {
|
|
444
|
+
// Keep the last one
|
|
445
|
+
if (i >= currentIndex || entry.bypass === true) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Collect and move over all resolvers of the previous requests to the current one
|
|
450
|
+
const previousResolvers = Array.isArray(entry.request.resolve) ? entry.request.resolve : [entry.request.resolve];
|
|
451
|
+
|
|
452
|
+
// Attach to current
|
|
453
|
+
request.resolve = [...request.resolve, ...previousResolvers];
|
|
454
|
+
|
|
455
|
+
// Collect and move over all rejectors of the previous requests to the current one
|
|
456
|
+
const previousRejectors = Array.isArray(entry.request.reject) ? entry.request.reject : [entry.request.reject];
|
|
457
|
+
|
|
458
|
+
// Attach to current
|
|
459
|
+
request.reject = [...request.reject, ...previousRejectors];
|
|
460
|
+
|
|
461
|
+
// Clear out retry mechanism on bypassed requests
|
|
462
|
+
clearTimeout(entry.timer);
|
|
463
|
+
this.requests.set(entry.request.serial, {
|
|
464
|
+
...entry,
|
|
465
|
+
request: {
|
|
466
|
+
...entry.request,
|
|
467
|
+
resolve: () => {},
|
|
468
|
+
// moved over to the current request
|
|
469
|
+
reject: () => {} // moved over to the current request
|
|
470
|
+
},
|
|
471
|
+
bypass: true,
|
|
472
|
+
timer: null
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
106
478
|
* Removes sequentially processed requests from the pipeline sequence.
|
|
107
479
|
* @param {string} serial The pipeline request serial.
|
|
108
|
-
*/
|
|
480
|
+
*/
|
|
481
|
+
removeRequestFromPipelineSequence(serial) {
|
|
482
|
+
const {
|
|
483
|
+
request
|
|
484
|
+
} = this.requests.get(serial) || {};
|
|
485
|
+
if (request && request.process === processTypes.PROCESS_SEQUENTIAL) {
|
|
486
|
+
pipelineSequence.remove(request.serial);
|
|
487
|
+
} else if (!request) {
|
|
488
|
+
pipelineSequence.remove(serial);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
109
493
|
* Increments the ongoing count for the pipeline of a request.
|
|
110
494
|
* @param {string} serial The pipeline request serial.
|
|
111
|
-
*/
|
|
495
|
+
*/
|
|
496
|
+
incrementPipelineOngoing(serial) {
|
|
497
|
+
const pipelineName = this.getPipelineNameBySerial(serial, false);
|
|
498
|
+
if (!pipelineName) {
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
if (!this.pipelines.has(pipelineName)) {
|
|
502
|
+
this.pipelines.set(pipelineName, 1);
|
|
503
|
+
} else {
|
|
504
|
+
this.pipelines.set(pipelineName, this.pipelines.get(pipelineName) + 1);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
112
509
|
* Decrements the ongoing count for the pipeline of a request.
|
|
113
510
|
* @param {string} serial The pipeline request serial.
|
|
114
|
-
*/
|
|
511
|
+
*/
|
|
512
|
+
decrementPipelineOngoing(serial) {
|
|
513
|
+
const pipelineName = this.getPipelineNameBySerial(serial, false);
|
|
514
|
+
if (!pipelineName) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
if (this.pipelines.has(pipelineName)) {
|
|
518
|
+
const ongoing = this.pipelines.get(pipelineName);
|
|
519
|
+
if (ongoing > 1) {
|
|
520
|
+
this.pipelines.set(pipelineName, ongoing - 1);
|
|
521
|
+
} else {
|
|
522
|
+
this.pipelines.delete(pipelineName);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
115
528
|
* Decrements the retries count.
|
|
116
529
|
* @param {string} serial The pipeline request serial.
|
|
117
|
-
*/
|
|
530
|
+
*/
|
|
531
|
+
decrementRetries(serial) {
|
|
532
|
+
const entry = this.requests.get(serial);
|
|
533
|
+
if (!entry) {
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
if (entry.retries) {
|
|
537
|
+
entry.retries -= 1;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
118
542
|
* Returns the PipelineRequest name.
|
|
119
543
|
* @param {string} serial The pipeline request serial.
|
|
120
544
|
* @param {boolean} [addVersion=true] Should the pipeline version be added.
|
|
121
545
|
* @return {string}
|
|
122
|
-
*/
|
|
546
|
+
*/
|
|
547
|
+
getPipelineNameBySerial(serial, addVersion = true) {
|
|
548
|
+
const entry = this.requests.get(serial);
|
|
549
|
+
if (!entry) {
|
|
550
|
+
return '';
|
|
551
|
+
}
|
|
552
|
+
if (addVersion) {
|
|
553
|
+
return `${entry.request.name}.v${entry.request.version}`;
|
|
554
|
+
}
|
|
555
|
+
return entry.request.name;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
123
559
|
* Returns the retries prefix for logs.
|
|
124
560
|
* @param {string} serial The pipeline request serial.
|
|
125
561
|
* @return {string}
|
|
126
|
-
*/
|
|
562
|
+
*/
|
|
563
|
+
getRetriesPrefix(serial) {
|
|
564
|
+
const {
|
|
565
|
+
request,
|
|
566
|
+
retries
|
|
567
|
+
} = this.requests.get(serial);
|
|
568
|
+
const numRetries = request.retries - retries;
|
|
569
|
+
return numRetries ? `Retry ${numRetries}: ` : '';
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
export default new PipelineManager();
|