teraslice 3.3.0 → 3.3.2

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.
Files changed (108) hide show
  1. package/LICENSE +202 -0
  2. package/package.json +25 -28
  3. package/dist/src/interfaces.js +0 -12
  4. package/dist/src/lib/cluster/cluster_master.js +0 -246
  5. package/dist/src/lib/cluster/node_master.js +0 -355
  6. package/dist/src/lib/cluster/services/api.js +0 -663
  7. package/dist/src/lib/cluster/services/assets.js +0 -224
  8. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/index.js +0 -192
  9. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/interfaces.js +0 -2
  10. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8s.js +0 -419
  11. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sDeploymentResource.js +0 -60
  12. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sJobResource.js +0 -55
  13. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sResource.js +0 -357
  14. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sServiceResource.js +0 -37
  15. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sState.js +0 -60
  16. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/utils.js +0 -170
  17. package/dist/src/lib/cluster/services/cluster/backends/native/dispatch.js +0 -13
  18. package/dist/src/lib/cluster/services/cluster/backends/native/index.js +0 -526
  19. package/dist/src/lib/cluster/services/cluster/backends/native/messaging.js +0 -548
  20. package/dist/src/lib/cluster/services/cluster/backends/state-utils.js +0 -26
  21. package/dist/src/lib/cluster/services/cluster/index.js +0 -13
  22. package/dist/src/lib/cluster/services/execution.js +0 -435
  23. package/dist/src/lib/cluster/services/index.js +0 -6
  24. package/dist/src/lib/cluster/services/interfaces.js +0 -2
  25. package/dist/src/lib/cluster/services/jobs.js +0 -458
  26. package/dist/src/lib/config/default-sysconfig.js +0 -25
  27. package/dist/src/lib/config/index.js +0 -20
  28. package/dist/src/lib/config/schemas/system.js +0 -360
  29. package/dist/src/lib/storage/analytics.js +0 -86
  30. package/dist/src/lib/storage/assets.js +0 -401
  31. package/dist/src/lib/storage/backends/elasticsearch_store.js +0 -496
  32. package/dist/src/lib/storage/backends/mappings/analytics.js +0 -20
  33. package/dist/src/lib/storage/backends/mappings/asset.js +0 -32
  34. package/dist/src/lib/storage/backends/mappings/ex.js +0 -53
  35. package/dist/src/lib/storage/backends/mappings/job.js +0 -42
  36. package/dist/src/lib/storage/backends/mappings/state.js +0 -16
  37. package/dist/src/lib/storage/backends/s3_store.js +0 -237
  38. package/dist/src/lib/storage/execution.js +0 -302
  39. package/dist/src/lib/storage/index.js +0 -7
  40. package/dist/src/lib/storage/jobs.js +0 -81
  41. package/dist/src/lib/storage/state.js +0 -254
  42. package/dist/src/lib/utils/api_utils.js +0 -128
  43. package/dist/src/lib/utils/asset_utils.js +0 -94
  44. package/dist/src/lib/utils/date_utils.js +0 -52
  45. package/dist/src/lib/utils/encoding_utils.js +0 -27
  46. package/dist/src/lib/utils/events.js +0 -4
  47. package/dist/src/lib/utils/file_utils.js +0 -124
  48. package/dist/src/lib/utils/id_utils.js +0 -15
  49. package/dist/src/lib/utils/port_utils.js +0 -32
  50. package/dist/src/lib/workers/assets/index.js +0 -3
  51. package/dist/src/lib/workers/assets/loader-executable.js +0 -40
  52. package/dist/src/lib/workers/assets/loader.js +0 -73
  53. package/dist/src/lib/workers/assets/spawn.js +0 -55
  54. package/dist/src/lib/workers/context/execution-context.js +0 -12
  55. package/dist/src/lib/workers/context/terafoundation-context.js +0 -8
  56. package/dist/src/lib/workers/execution-controller/execution-analytics.js +0 -188
  57. package/dist/src/lib/workers/execution-controller/index.js +0 -1024
  58. package/dist/src/lib/workers/execution-controller/recovery.js +0 -151
  59. package/dist/src/lib/workers/execution-controller/scheduler.js +0 -390
  60. package/dist/src/lib/workers/execution-controller/slice-analytics.js +0 -96
  61. package/dist/src/lib/workers/helpers/job.js +0 -80
  62. package/dist/src/lib/workers/helpers/op-analytics.js +0 -22
  63. package/dist/src/lib/workers/helpers/terafoundation.js +0 -34
  64. package/dist/src/lib/workers/helpers/worker-shutdown.js +0 -147
  65. package/dist/src/lib/workers/metrics/index.js +0 -108
  66. package/dist/src/lib/workers/worker/index.js +0 -378
  67. package/dist/src/lib/workers/worker/slice.js +0 -122
  68. package/dist/test/config/schemas/system_schema-spec.js +0 -26
  69. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8s-v2-spec.js +0 -458
  70. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sResource-v2-spec.js +0 -818
  71. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-multicluster-v2-spec.js +0 -67
  72. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-v2-spec.js +0 -84
  73. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/utils-v2-spec.js +0 -320
  74. package/dist/test/lib/cluster/services/cluster/backends/state-utils-spec.js +0 -37
  75. package/dist/test/node_master-spec.js +0 -194
  76. package/dist/test/services/api-spec.js +0 -79
  77. package/dist/test/services/assets-spec.js +0 -158
  78. package/dist/test/services/messaging-spec.js +0 -440
  79. package/dist/test/storage/assets_storage-spec.js +0 -95
  80. package/dist/test/storage/s3_store-spec.js +0 -149
  81. package/dist/test/test.config.js +0 -23
  82. package/dist/test/test.setup.js +0 -6
  83. package/dist/test/utils/api_utils-spec.js +0 -25
  84. package/dist/test/utils/asset_utils-spec.js +0 -141
  85. package/dist/test/utils/elastic_utils-spec.js +0 -25
  86. package/dist/test/workers/execution-controller/execution-controller-spec.js +0 -371
  87. package/dist/test/workers/execution-controller/execution-special-test-cases-spec.js +0 -519
  88. package/dist/test/workers/execution-controller/execution-test-cases-spec.js +0 -343
  89. package/dist/test/workers/execution-controller/recovery-spec.js +0 -160
  90. package/dist/test/workers/execution-controller/scheduler-spec.js +0 -249
  91. package/dist/test/workers/execution-controller/slice-analytics-spec.js +0 -121
  92. package/dist/test/workers/fixtures/ops/example-op/processor.js +0 -20
  93. package/dist/test/workers/fixtures/ops/example-op/schema.js +0 -19
  94. package/dist/test/workers/fixtures/ops/example-reader/fetcher.js +0 -20
  95. package/dist/test/workers/fixtures/ops/example-reader/schema.js +0 -41
  96. package/dist/test/workers/fixtures/ops/example-reader/slicer.js +0 -37
  97. package/dist/test/workers/fixtures/ops/new-op/processor.js +0 -29
  98. package/dist/test/workers/fixtures/ops/new-op/schema.js +0 -18
  99. package/dist/test/workers/fixtures/ops/new-reader/fetcher.js +0 -19
  100. package/dist/test/workers/fixtures/ops/new-reader/schema.js +0 -23
  101. package/dist/test/workers/fixtures/ops/new-reader/slicer.js +0 -13
  102. package/dist/test/workers/helpers/configs.js +0 -128
  103. package/dist/test/workers/helpers/execution-controller-helper.js +0 -49
  104. package/dist/test/workers/helpers/index.js +0 -5
  105. package/dist/test/workers/helpers/test-context.js +0 -210
  106. package/dist/test/workers/helpers/zip-directory.js +0 -25
  107. package/dist/test/workers/worker/slice-spec.js +0 -333
  108. package/dist/test/workers/worker/worker-spec.js +0 -356
@@ -1,151 +0,0 @@
1
- import { pRaceWithTimeout, logError, Queue } from '@terascope/core-utils';
2
- import { makeLogger } from '../helpers/terafoundation.js';
3
- export class RecoveryModule {
4
- logger;
5
- events;
6
- slicersToRecover;
7
- recoveryQueue;
8
- recoverComplete = true;
9
- isShutdown = false;
10
- autorecover;
11
- cleanupType;
12
- slicerID = 0;
13
- retryState = new Map();
14
- recoverExecution;
15
- exId;
16
- stateStore;
17
- timeout;
18
- constructor(context, executionContext) {
19
- const { exId } = executionContext;
20
- this.events = context.apis.foundation.getSystemEvents();
21
- this.slicersToRecover = executionContext.config.slicers;
22
- this.recoveryQueue = new Queue();
23
- this.cleanupType = executionContext.config.recovered_slice_type;
24
- this.recoverExecution = executionContext.config.recovered_execution;
25
- this.autorecover = Boolean(executionContext.config.autorecover);
26
- this.exId = exId;
27
- this.logger = makeLogger(context, 'execution_recovery');
28
- this.timeout = context.sysconfig.teraslice.shutdown_timeout;
29
- }
30
- initialize(stateStore) {
31
- this.stateStore = stateStore;
32
- this.events.on('slice:success', this._sliceComplete.bind(this));
33
- this.recoverComplete = false;
34
- // once we have fully recovered, clean up event listeners
35
- this.events.once('execution:recovery:complete', () => {
36
- this.events.removeListener('slice:success', this._sliceComplete.bind(this));
37
- });
38
- }
39
- // TODO: this is wrong
40
- _sliceComplete(sliceData) {
41
- this.retryState.set(sliceData.slice.slice_id, false);
42
- }
43
- _setId(slice) {
44
- this.retryState.set(slice.slice_id, true);
45
- }
46
- async _processIncompleteSlices(slicerID) {
47
- const slices = await this.stateStore.recoverSlices(this.recoverExecution, slicerID, this.cleanupType);
48
- for (const slice of slices) {
49
- this._setId(slice);
50
- this.recoveryQueue.enqueue(slice);
51
- }
52
- return slices.length;
53
- }
54
- _recoveryBatchCompleted() {
55
- return [...this.retryState.values()].every((v) => v === false);
56
- }
57
- _retryState() {
58
- return Object.fromEntries(this.retryState);
59
- }
60
- // TODO: refactor to use pwhile
61
- async _waitForRecoveryBatchCompletion() {
62
- return new Promise((resolve) => {
63
- const checkingBatch = setInterval(() => {
64
- if (this._recoveryBatchCompleted()) {
65
- clearInterval(checkingBatch);
66
- this.events.emit('execution:recovery:complete');
67
- this.recoverComplete = true;
68
- resolve(true);
69
- return;
70
- }
71
- if (this.isShutdown) {
72
- clearInterval(checkingBatch);
73
- this.recoverComplete = false;
74
- resolve(true);
75
- }
76
- }, 100);
77
- });
78
- }
79
- async handle() {
80
- if (this.recoverComplete) {
81
- return true;
82
- }
83
- const recoveredSlicesCount = await this._processIncompleteSlices(this.slicerID);
84
- if (recoveredSlicesCount === 0) {
85
- this.slicerID++;
86
- // all slicers have been recovered
87
- if (this.slicerID > this.slicersToRecover) {
88
- this.logger.warn(`recovered data for execution: ${this.exId} has successfully been enqueued`);
89
- await this._waitForRecoveryBatchCompletion();
90
- return true;
91
- }
92
- }
93
- await this._waitForRecoveryBatchCompletion();
94
- return false;
95
- }
96
- getSlice() {
97
- if (this.recoveryQueue.size() > 0) {
98
- return this.recoveryQueue.dequeue();
99
- }
100
- return;
101
- }
102
- getSlices(max = 1) {
103
- const count = max > this.sliceCount() ? this.sliceCount() : max;
104
- const slices = [];
105
- for (let i = 0; i < count; i++) {
106
- const slice = this.recoveryQueue.dequeue();
107
- if (!slice)
108
- return slices;
109
- slices.push(slice);
110
- }
111
- return slices;
112
- }
113
- sliceCount() {
114
- return this.recoveryQueue.size();
115
- }
116
- async shutdown() {
117
- let checkInterval;
118
- try {
119
- await pRaceWithTimeout(new Promise((resolve) => {
120
- checkInterval = setInterval(() => {
121
- if (this.recoverComplete) {
122
- resolve(true);
123
- }
124
- }, 100);
125
- }), this.timeout, (err) => {
126
- logError(this.logger, err);
127
- });
128
- }
129
- finally {
130
- this.isShutdown = true;
131
- clearInterval(checkInterval);
132
- }
133
- }
134
- recoveryComplete() {
135
- return this.recoverComplete;
136
- }
137
- /**
138
- * Whether or not the execution will continue to process
139
- * slices after recovering.
140
- *
141
- * @returns {boolean}
142
- */
143
- exitAfterComplete() {
144
- if (this.autorecover)
145
- return false;
146
- if (!this.cleanupType)
147
- return false;
148
- return true;
149
- }
150
- }
151
- //# sourceMappingURL=recovery.js.map
@@ -1,390 +0,0 @@
1
- import { noop, pDelay, get, toString, logError, pWhile, Queue, makeISODate } from '@terascope/core-utils';
2
- import { RecoveryModule } from './recovery.js';
3
- import { makeLogger } from '../helpers/terafoundation.js';
4
- export class Scheduler {
5
- context;
6
- logger;
7
- events;
8
- executionContext;
9
- exId;
10
- recoverFromExId;
11
- recoverExecution;
12
- recovering;
13
- autorecover;
14
- _creating = 0;
15
- ready = false;
16
- paused = true;
17
- stopped = false;
18
- slicersDone = false;
19
- slicersFailed = false;
20
- queue = new Queue();
21
- recover;
22
- stateStorage;
23
- executionStorage;
24
- _resolveRun = noop;
25
- _processCleanup = noop;
26
- startingPoints = [];
27
- constructor(context, executionContext) {
28
- this.context = context;
29
- this.logger = makeLogger(context, 'execution_scheduler');
30
- this.events = context.apis.foundation.getSystemEvents();
31
- this.executionContext = executionContext;
32
- this.exId = executionContext.exId;
33
- this.recover = new RecoveryModule(context, executionContext);
34
- const recoverFromExId = get(executionContext.config, 'recovered_execution');
35
- const slicerCanRecover = executionContext.slicer().isRecoverable();
36
- if (recoverFromExId && !slicerCanRecover) {
37
- throw new Error('Slicer is not recoverable');
38
- }
39
- this.recoverFromExId = recoverFromExId;
40
- this.recoverExecution = Boolean(recoverFromExId && slicerCanRecover);
41
- this.recovering = Boolean(this.recoverExecution);
42
- this.autorecover = Boolean(executionContext.config.autorecover);
43
- this._processSlicers();
44
- }
45
- /**
46
- * Initialize the recovery instance or the execution context,
47
- * if recovery is initialized, the execution context will not be
48
- * initialized until the execution if finished and the cleanup
49
- * type is set.
50
- */
51
- async initialize(stateStorage, executionStorage) {
52
- this.stateStorage = stateStorage;
53
- this.executionStorage = executionStorage;
54
- if (this.recoverExecution) {
55
- await this._initializeRecovery();
56
- return;
57
- }
58
- await this._initializeExecution();
59
- }
60
- /**
61
- * Run the execution, this will block until complete (or failed)
62
- */
63
- async run() {
64
- if (this.recoverExecution) {
65
- await this.executionStorage.setStatus(this.exId, 'recovering');
66
- this.logger.info(`execution: ${this.exId} is starting in recovery mode`);
67
- this.ready = true;
68
- this.start();
69
- await this._waitForRecovery();
70
- await this._recoveryComplete();
71
- if (this.recover.exitAfterComplete()) {
72
- return;
73
- }
74
- await this._initializeExecution();
75
- }
76
- await this.executionStorage.setStatus(this.exId, 'running');
77
- this.ready = true;
78
- const promise = new Promise((resolve) => {
79
- const handler = (err) => {
80
- if (err) {
81
- this.slicersFailed = true;
82
- }
83
- else {
84
- this.slicersDone = true;
85
- }
86
- this._resolveRun();
87
- this._resolveRun = noop;
88
- };
89
- this._resolveRun = () => {
90
- this.events.removeListener('slicers:finished', handler);
91
- resolve(true);
92
- };
93
- this.events.once('slicers:finished', handler);
94
- });
95
- this.start();
96
- this.logger.trace('running the scheduler');
97
- await promise;
98
- const n = this.pendingSlices + this.pendingSlicerCount;
99
- this.logger.debug(`execution ${this.exId} is finished scheduling, ${n} remaining slices in the queue`);
100
- await pWhile(async () => {
101
- if (!this._creating) {
102
- this.logger.debug('done creating remaining slices');
103
- return true;
104
- }
105
- this.logger.debug(`waiting for ${this._creating} remaining slices to be created...`);
106
- await pDelay(100);
107
- return false;
108
- });
109
- }
110
- start() {
111
- this.paused = false;
112
- }
113
- async stop() {
114
- if (this.stopped)
115
- return;
116
- this.logger.debug('stopping scheduler...');
117
- this.stopped = true;
118
- const drain = this._drainPendingSlices(false);
119
- this._processCleanup();
120
- this._processCleanup = noop;
121
- this._resolveRun();
122
- this._resolveRun = noop;
123
- await drain;
124
- }
125
- pause() {
126
- this.paused = true;
127
- }
128
- get maxQueueLength() {
129
- return this.executionContext.slicer().maxQueueLength();
130
- }
131
- get queueLength() {
132
- return this.queue.size();
133
- }
134
- get isQueueFull() {
135
- const maxLength = this.maxQueueLength;
136
- return this.pendingSlices + this.pendingSlicerCount > maxLength;
137
- }
138
- get pendingSlicerCount() {
139
- if (!this.ready)
140
- return 0;
141
- if (this.recovering && this.recover) {
142
- return this.recover.sliceCount();
143
- }
144
- return this.executionContext.slicer().sliceCount();
145
- }
146
- get pendingSlices() {
147
- return this.queueLength + this._creating;
148
- }
149
- get queueRemainder() {
150
- const remainder = this.maxQueueLength - this.pendingSlices;
151
- return remainder > 0 ? remainder : 0;
152
- }
153
- get isFinished() {
154
- const isDone = this.slicersDone || this.slicersFailed || this.stopped;
155
- return isDone && !this.pendingSlices;
156
- }
157
- canAllocateSlice() {
158
- return this.ready && !this.paused && !this.isQueueFull;
159
- }
160
- canComplete() {
161
- const { lifecycle } = this.executionContext.config;
162
- return this.ready && lifecycle === 'once' && !this.recovering;
163
- }
164
- isRecovering() {
165
- return this.ready && this.recovering;
166
- }
167
- async shutdown() {
168
- await this.stop();
169
- if (this.recover) {
170
- try {
171
- await this.recover.shutdown();
172
- }
173
- catch (err) {
174
- logError(this.logger, err, 'failed to shutdown recovery');
175
- }
176
- }
177
- this.queue.each((slice) => {
178
- this.queue.remove(slice.slice_id, 'slice_id');
179
- });
180
- }
181
- getSlices(limit = 1) {
182
- if (this.queue.size() === 0)
183
- return [];
184
- if (limit < 1)
185
- return [];
186
- const slices = [];
187
- for (let i = 0; i < limit; i += 1) {
188
- const slice = this.queue.dequeue();
189
- if (slice == null)
190
- break;
191
- slices.push(slice);
192
- }
193
- if (slices.length > 0) {
194
- this.events.emit('slicers:queued', this.queueLength);
195
- }
196
- return slices;
197
- }
198
- enqueueSlice(slice, addToStart) {
199
- return this.enqueueSlices([slice], addToStart);
200
- }
201
- enqueueSlices(slices, addToStart = false) {
202
- if (this.stopped)
203
- return;
204
- slices.forEach((slice) => {
205
- if (this.queue.exists('slice_id', slice.slice_id)) {
206
- this.logger.warn(`slice ${slice.slice_id} has already been enqueued`);
207
- return;
208
- }
209
- this.logger.trace('enqueuing slice', slice);
210
- if (addToStart) {
211
- this.queue.unshift(slice);
212
- }
213
- else {
214
- this.queue.enqueue(slice);
215
- this.executionContext.onSliceEnqueued(slice);
216
- }
217
- });
218
- this.events.emit('slicers:queued', this.queueLength);
219
- }
220
- _processSlicers() {
221
- const { events, logger, exId } = this;
222
- let _handling = false;
223
- let _finished = false;
224
- let createInterval;
225
- let handleInterval;
226
- const resetCleanup = () => {
227
- this._processCleanup = noop;
228
- };
229
- const cleanup = () => {
230
- clearInterval(createInterval);
231
- createInterval = undefined;
232
- clearInterval(handleInterval);
233
- handleInterval = undefined;
234
- resetCleanup();
235
- };
236
- const drain = () => {
237
- const n = this.pendingSlicerCount;
238
- if (n) {
239
- logger.debug(`draining the remaining ${n} pending slices from the slicer`);
240
- }
241
- return this._drainPendingSlices(false);
242
- };
243
- const onSlicerFinished = async () => {
244
- cleanup();
245
- logger.info(`all slicers for execution: ${exId} have been completed`);
246
- await drain();
247
- events.emit('slicers:finished');
248
- };
249
- const onSlicerFailure = async (err) => {
250
- cleanup();
251
- logger.warn('slicer failed', toString(err));
252
- await drain();
253
- // before removing listeners make sure we've received all of the events
254
- await pDelay(100);
255
- events.emit('slicers:finished', err);
256
- };
257
- const makeSlices = async () => {
258
- try {
259
- if (this.recovering && this.recover) {
260
- _finished = await this.recover.handle();
261
- }
262
- else {
263
- _finished = await this.executionContext.slicer().handle();
264
- }
265
- }
266
- catch (err) {
267
- await onSlicerFailure(err);
268
- return;
269
- }
270
- if (!_finished) {
271
- return;
272
- }
273
- if (!this.recovering) {
274
- clearInterval(handleInterval);
275
- handleInterval = undefined;
276
- }
277
- if (this.canComplete()) {
278
- await onSlicerFinished();
279
- }
280
- };
281
- handleInterval = setInterval(() => {
282
- if (!this.canAllocateSlice())
283
- return;
284
- if (_handling)
285
- return;
286
- _handling = true;
287
- makeSlices()
288
- .then(() => {
289
- _handling = false;
290
- })
291
- .catch((err) => {
292
- _handling = false;
293
- logError(this.logger, err, 'failure to run slicers');
294
- });
295
- }, 3);
296
- createInterval = setInterval(() => {
297
- if (!this.pendingSlicerCount)
298
- return;
299
- this._drainPendingSlices().catch(onSlicerFailure);
300
- }, 5);
301
- this._processCleanup = cleanup;
302
- }
303
- async _drainPendingSlices(once = true) {
304
- const slices = this._getPendingSlices();
305
- if (!slices.length)
306
- return;
307
- await this._createSlices(slices);
308
- if (once)
309
- return;
310
- await this._drainPendingSlices();
311
- }
312
- _getPendingSlices() {
313
- if (!this.ready)
314
- return [];
315
- if (this.recovering && this.recover) {
316
- return this.recover.getSlices(this.queueRemainder);
317
- }
318
- return this.executionContext.slicer().getSlices(this.queueRemainder);
319
- }
320
- async _createSlices(allSlices) {
321
- // filter out anything that doesn't need to be created
322
- const slices = [];
323
- for (const slice of allSlices) {
324
- // In the case of recovery slices have already been
325
- // created, so its important to skip this step
326
- if (slice._created) {
327
- this.enqueueSlice(slice);
328
- }
329
- else {
330
- slice._created = makeISODate();
331
- slices.push(slice);
332
- }
333
- }
334
- if (!slices.length)
335
- return;
336
- this._creating += slices.length;
337
- try {
338
- const count = await this.stateStorage.createSlices(this.exId, slices);
339
- this.enqueueSlices(slices);
340
- this._creating -= count;
341
- }
342
- catch (err) {
343
- const { lifecycle } = this.executionContext.config;
344
- if (lifecycle === 'once') {
345
- throw err;
346
- }
347
- else {
348
- logError(this.logger, err, 'failure creating slices');
349
- }
350
- }
351
- }
352
- async _initializeRecovery() {
353
- await this.recover.initialize(this.stateStorage);
354
- const { slicers: prevSlicers } = await this.executionStorage.get(this.recoverFromExId);
355
- this.events.emit('slicers:registered', prevSlicers);
356
- }
357
- async _initializeExecution() {
358
- await this.executionContext.initialize(this.startingPoints);
359
- const slicers = this.executionContext.slicer().slicers();
360
- this.events.emit('slicers:registered', slicers);
361
- }
362
- async _waitForRecovery() {
363
- if (!this.recoverExecution)
364
- return;
365
- if (!this.recover.recoveryComplete()) {
366
- await new Promise((resolve) => {
367
- this.events.once('execution:recovery:complete', () => {
368
- resolve(true);
369
- });
370
- });
371
- }
372
- }
373
- async _recoveryComplete() {
374
- this.recovering = false;
375
- this.ready = false;
376
- if (this.recover.exitAfterComplete()) {
377
- this.logger.warn('execution recovery has been marked as completed');
378
- this.slicersDone = true;
379
- this._processCleanup();
380
- this._processCleanup = noop;
381
- this._resolveRun();
382
- this._resolveRun = noop;
383
- return;
384
- }
385
- const { slicers: prevSlicers } = await this.executionStorage.get(this.recoverFromExId);
386
- this.startingPoints = await this.stateStorage.getStartingPoints(this.recoverFromExId, prevSlicers);
387
- this.logger.info(`execution: ${this.exId} finished its recovery`);
388
- }
389
- }
390
- //# sourceMappingURL=scheduler.js.map
@@ -1,96 +0,0 @@
1
- import { has, isInteger, toNumber } from '@terascope/core-utils';
2
- import { makeLogger } from '../helpers/terafoundation.js';
3
- // TODO: more types
4
- export class SliceAnalytics {
5
- logger;
6
- events;
7
- sliceAnalytics;
8
- operations;
9
- constructor(context, executionContext) {
10
- this.logger = makeLogger(context, 'slice_analytics');
11
- this.events = context.apis.foundation.getSystemEvents();
12
- const { operations } = executionContext.config;
13
- this.operations = operations;
14
- // create a container to hold all the slice analytics for this execution
15
- this.sliceAnalytics = {
16
- time: [],
17
- size: [],
18
- memory: []
19
- };
20
- const opsLength = this.operations.length;
21
- for (let i = 0; i < opsLength; i += 1) {
22
- this.sliceAnalytics.time.push({
23
- min: 0,
24
- max: 0,
25
- sum: 0,
26
- total: 0,
27
- average: 0
28
- });
29
- this.sliceAnalytics.size.push({
30
- min: 0,
31
- max: 0,
32
- sum: 0,
33
- total: 0,
34
- average: 0
35
- });
36
- this.sliceAnalytics.memory.push({
37
- min: 0,
38
- max: 0,
39
- sum: 0,
40
- total: 0,
41
- average: 0
42
- });
43
- }
44
- this.events.on('slice:success', this.onSliceSuccess.bind(this));
45
- }
46
- addStat(input, stat) {
47
- if (!has(input, stat) || !has(this.sliceAnalytics, stat)) {
48
- this.logger.warn(`unsupported stat "${stat}"`);
49
- return;
50
- }
51
- for (let i = 0; i < this.operations.length; i += 1) {
52
- const val = input[stat][i];
53
- if (!isInteger(val)) {
54
- return;
55
- }
56
- this.sliceAnalytics[stat][i].sum += val;
57
- this.sliceAnalytics[stat][i].total += 1;
58
- const { min, max, total, sum } = this.sliceAnalytics[stat][i];
59
- this.sliceAnalytics[stat][i].min = min !== 0 ? Math.min(val, min) : val;
60
- this.sliceAnalytics[stat][i].max = max !== 0 ? Math.max(val, max) : val;
61
- this.sliceAnalytics[stat][i].average = toNumber((sum / total).toFixed(2));
62
- }
63
- }
64
- addStats(data) {
65
- this.addStat(data, 'time');
66
- this.addStat(data, 'memory');
67
- this.addStat(data, 'size');
68
- }
69
- analyzeStats() {
70
- this.logger.info('calculating statistics');
71
- for (let i = 0; i < this.operations.length; i += 1) {
72
- const name = this.operations[i]._op;
73
- const time = this.sliceAnalytics.time[i];
74
- const size = this.sliceAnalytics.size[i];
75
- const memory = this.sliceAnalytics.memory[i];
76
- this.logger.info(`
77
- operation ${name}
78
- average completion time of: ${time.average} ms, min: ${time.min} ms, and max: ${time.max} ms
79
- average size: ${size.average}, min: ${size.min}, and max: ${size.max}
80
- average memory: ${memory.average}, min: ${memory.min}, and max: ${memory.max}
81
- `);
82
- }
83
- }
84
- getStats() {
85
- return this.sliceAnalytics;
86
- }
87
- onSliceSuccess({ analytics }) {
88
- if (analytics) {
89
- this.addStats(analytics);
90
- }
91
- }
92
- async shutdown() {
93
- this.events.removeListener('slice:success', this.onSliceSuccess.bind(this));
94
- }
95
- }
96
- //# sourceMappingURL=slice-analytics.js.map