teraslice 0.87.1 → 0.88.0

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 (69) hide show
  1. package/cluster-service.js +24 -18
  2. package/dist/src/index.js +42 -0
  3. package/package.json +11 -15
  4. package/service.js +4 -6
  5. package/worker-service.js +6 -6
  6. package/index.js +0 -21
  7. package/lib/cluster/cluster_master.js +0 -164
  8. package/lib/cluster/node_master.js +0 -393
  9. package/lib/cluster/services/api.js +0 -581
  10. package/lib/cluster/services/assets.js +0 -211
  11. package/lib/cluster/services/cluster/backends/kubernetes/deployments/worker.hbs +0 -86
  12. package/lib/cluster/services/cluster/backends/kubernetes/index.js +0 -225
  13. package/lib/cluster/services/cluster/backends/kubernetes/jobs/execution_controller.hbs +0 -69
  14. package/lib/cluster/services/cluster/backends/kubernetes/k8s.js +0 -450
  15. package/lib/cluster/services/cluster/backends/kubernetes/k8sResource.js +0 -443
  16. package/lib/cluster/services/cluster/backends/kubernetes/k8sState.js +0 -67
  17. package/lib/cluster/services/cluster/backends/kubernetes/utils.js +0 -58
  18. package/lib/cluster/services/cluster/backends/native/index.js +0 -611
  19. package/lib/cluster/services/cluster/backends/native/messaging.js +0 -563
  20. package/lib/cluster/services/cluster/backends/state-utils.js +0 -49
  21. package/lib/cluster/services/cluster/index.js +0 -15
  22. package/lib/cluster/services/execution.js +0 -459
  23. package/lib/cluster/services/jobs.js +0 -303
  24. package/lib/config/default-sysconfig.js +0 -47
  25. package/lib/config/index.js +0 -32
  26. package/lib/config/schemas/system.js +0 -333
  27. package/lib/processors/save_file/index.js +0 -9
  28. package/lib/processors/save_file/processor.js +0 -17
  29. package/lib/processors/save_file/schema.js +0 -17
  30. package/lib/processors/script.js +0 -130
  31. package/lib/processors/stdout/index.js +0 -9
  32. package/lib/processors/stdout/processor.js +0 -19
  33. package/lib/processors/stdout/schema.js +0 -18
  34. package/lib/storage/analytics.js +0 -106
  35. package/lib/storage/assets.js +0 -275
  36. package/lib/storage/backends/elasticsearch_store.js +0 -567
  37. package/lib/storage/backends/mappings/analytics.json +0 -49
  38. package/lib/storage/backends/mappings/asset.json +0 -40
  39. package/lib/storage/backends/mappings/ex.json +0 -55
  40. package/lib/storage/backends/mappings/job.json +0 -31
  41. package/lib/storage/backends/mappings/state.json +0 -37
  42. package/lib/storage/execution.js +0 -331
  43. package/lib/storage/index.js +0 -16
  44. package/lib/storage/jobs.js +0 -97
  45. package/lib/storage/state.js +0 -302
  46. package/lib/utils/api_utils.js +0 -173
  47. package/lib/utils/asset_utils.js +0 -117
  48. package/lib/utils/date_utils.js +0 -58
  49. package/lib/utils/encoding_utils.js +0 -29
  50. package/lib/utils/events.js +0 -7
  51. package/lib/utils/file_utils.js +0 -118
  52. package/lib/utils/id_utils.js +0 -19
  53. package/lib/utils/port_utils.js +0 -83
  54. package/lib/workers/assets/loader.js +0 -109
  55. package/lib/workers/assets/spawn.js +0 -78
  56. package/lib/workers/context/execution-context.js +0 -16
  57. package/lib/workers/context/terafoundation-context.js +0 -10
  58. package/lib/workers/execution-controller/execution-analytics.js +0 -211
  59. package/lib/workers/execution-controller/index.js +0 -1033
  60. package/lib/workers/execution-controller/recovery.js +0 -188
  61. package/lib/workers/execution-controller/scheduler.js +0 -461
  62. package/lib/workers/execution-controller/slice-analytics.js +0 -115
  63. package/lib/workers/helpers/job.js +0 -93
  64. package/lib/workers/helpers/op-analytics.js +0 -22
  65. package/lib/workers/helpers/terafoundation.js +0 -43
  66. package/lib/workers/helpers/worker-shutdown.js +0 -187
  67. package/lib/workers/metrics/index.js +0 -139
  68. package/lib/workers/worker/index.js +0 -344
  69. package/lib/workers/worker/slice.js +0 -143
@@ -1,443 +0,0 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
-
6
- const barbe = require('barbe');
7
- const _ = require('lodash');
8
-
9
- const { isNumber } = require('@terascope/utils');
10
-
11
- const { safeEncode } = require('../../../../../utils/encoding_utils');
12
- const { setMaxOldSpaceViaEnv } = require('./utils');
13
-
14
- class K8sResource {
15
- /**
16
- * K8sResource allows the generation of k8s resources based on templates.
17
- * After creating the object, the k8s resource is accessible on the objects
18
- * .resource property.
19
- *
20
- * @param {String} resourceType - jobs/services/deployments
21
- * @param {String} resourceName - worker/execution_controller
22
- * @param {Object} terasliceConfig - teraslice cluster config from context
23
- * @param {Object} execution - teraslice execution
24
- */
25
- constructor(resourceType, resourceName, terasliceConfig, execution, logger) {
26
- this.execution = execution;
27
- this.jobLabelPrefix = 'job.teraslice.terascope.io';
28
- this.jobPropertyLabelPrefix = 'job-property.teraslice.terascope.io';
29
- this.logger = logger;
30
- this.nodeType = resourceName;
31
- this.terasliceConfig = terasliceConfig;
32
-
33
- if (resourceName === 'worker') {
34
- this.nameInfix = 'wkr';
35
- } else if (resourceName === 'execution_controller') {
36
- this.nameInfix = 'exc';
37
- } else {
38
- throw new Error(`Unsupported resourceName: ${resourceName}`);
39
- }
40
-
41
- this.templateGenerator = this._makeTemplate(resourceType, resourceName);
42
- this.templateConfig = this._makeConfig();
43
- this.resource = this.templateGenerator(this.templateConfig);
44
-
45
- this._setJobLabels();
46
-
47
- // Apply job `targets` setting as k8s nodeAffinity
48
- // We assume that multiple targets require both to match ...
49
- // NOTE: If you specify multiple `matchExpressions` associated with
50
- // `nodeSelectorTerms`, then the pod can be scheduled onto a node
51
- // only if *all* `matchExpressions` can be satisfied.
52
- this._setTargets();
53
- this._setResources();
54
- this._setVolumes();
55
- this._setAssetsVolume();
56
- this._setImagePullSecret();
57
- this._setEphemeralStorage();
58
- this._setExternalPorts();
59
- this._setPriorityClassName();
60
-
61
- if (resourceName === 'worker') {
62
- this._setWorkerAntiAffinity();
63
- }
64
-
65
- // Execution controller targets are required nodeAffinities, if
66
- // required job targets are also supplied, then *all* of the matches
67
- // will have to be satisfied for the job to be scheduled. This also
68
- // adds tolerations for any specified targets
69
- if (resourceName === 'execution_controller') {
70
- this._setExecutionControllerTargets();
71
- }
72
-
73
- if (this.terasliceConfig.kubernetes_overrides_enabled) {
74
- this._mergePodSpecOverlay();
75
- }
76
- }
77
-
78
- _makeConfig() {
79
- const clusterName = _.get(this.terasliceConfig, 'name');
80
- const clusterNameLabel = clusterName.replace(/[^a-zA-Z0-9_\-.]/g, '_').substring(0, 63);
81
- const configMapName = _.get(
82
- this.terasliceConfig,
83
- 'kubernetes_config_map_name',
84
- `${this.terasliceConfig.name}-worker`
85
- );
86
- const dockerImage = this.execution.kubernetes_image
87
- || this.terasliceConfig.kubernetes_image;
88
- // name needs to be a valid DNS name since it is used in the svc name,
89
- // so we can only permit alphanumeric and - characters. _ is forbidden.
90
- // -> regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?'
91
- const jobNameLabel = this.execution.name
92
- .toLowerCase()
93
- .replace(/[^a-zA-Z0-9\-.]/g, '-')
94
- .replace(/^[^a-z]/, 'a')
95
- .replace(/[^a-z0-9]$/, '0')
96
- .substring(0, 63);
97
- const name = `ts-${this.nameInfix}-${jobNameLabel.substring(0, 35)}-${this.execution.job_id.substring(0, 13)}`;
98
- const shutdownTimeoutMs = _.get(this.terasliceConfig, 'shutdown_timeout', 60000);
99
- const shutdownTimeoutSeconds = Math.round(shutdownTimeoutMs / 1000);
100
-
101
- const config = {
102
- // assetsDirectory: _.get(this.terasliceConfig, 'assets_directory', ''),
103
- // assetsVolume: _.get(this.terasliceConfig, 'assets_volume', ''),
104
- clusterName,
105
- clusterNameLabel,
106
- configMapName,
107
- dockerImage,
108
- execution: safeEncode(this.execution),
109
- exId: this.execution.ex_id,
110
- exName: this.execution.k8sName,
111
- exUid: this.execution.k8sUid,
112
- jobId: this.execution.job_id,
113
- jobNameLabel,
114
- name,
115
- namespace: _.get(this.terasliceConfig, 'kubernetes_namespace', 'default'),
116
- nodeType: this.nodeType,
117
- replicas: this.execution.workers,
118
- shutdownTimeout: shutdownTimeoutSeconds
119
- };
120
- return config;
121
- }
122
-
123
- _makeTemplate(folder, fileName) {
124
- const filePath = path.join(__dirname, folder, `${fileName}.hbs`);
125
- const templateData = fs.readFileSync(filePath, 'utf-8');
126
- const templateKeys = ['{{', '}}'];
127
-
128
- return (config) => {
129
- const templated = barbe(templateData, templateKeys, config);
130
- return JSON.parse(templated);
131
- };
132
- }
133
-
134
- _setWorkerAntiAffinity() {
135
- if (this.terasliceConfig.kubernetes_worker_antiaffinity) {
136
- const targetKey = 'spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution';
137
- if (!_.has(this.resource, targetKey)) {
138
- _.set(this.resource, targetKey, []);
139
- }
140
-
141
- // eslint-disable-next-line max-len
142
- this.resource.spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution.push(
143
- {
144
- weight: 1,
145
- podAffinityTerm: {
146
- labelSelector: {
147
- matchExpressions: [
148
- {
149
- key: 'app.kubernetes.io/name',
150
- operator: 'In',
151
- values: [
152
- 'teraslice'
153
- ]
154
- },
155
- {
156
- key: 'app.kubernetes.io/instance',
157
- operator: 'In',
158
- values: [
159
- this.templateConfig.clusterNameLabel
160
- ]
161
- }
162
- ]
163
- },
164
- topologyKey: 'kubernetes.io/hostname'
165
- }
166
- }
167
- );
168
- }
169
- }
170
-
171
- /**
172
- * Execution Controllers get tolerations and required affinities
173
- *
174
- * NOTE: We considered changing `execution_controller_targets` to be an
175
- * object but the inconsistency with `targets` made this awkward. See the
176
- * `teraslice config with execution_controller_targets and job targets set`
177
- * test for an example. If the syntax for this were to change, we should
178
- * also consider changing `execution.targets`, which is a change on the job.
179
- */
180
- _setExecutionControllerTargets() {
181
- if (this.terasliceConfig.execution_controller_targets) {
182
- _.forEach(this.terasliceConfig.execution_controller_targets, (target) => {
183
- this._setTargetRequired(target);
184
- this._setTargetAccepted(target);
185
- });
186
- }
187
- }
188
-
189
- _setEphemeralStorage() {
190
- if (this.execution.ephemeral_storage) {
191
- this.resource.spec.template.spec.containers[0].volumeMounts.push({
192
- name: 'ephemeral-volume',
193
- mountPath: '/ephemeral0'
194
- });
195
- this.resource.spec.template.spec.volumes.push({
196
- name: 'ephemeral-volume',
197
- emptyDir: {}
198
- });
199
- }
200
- }
201
-
202
- _setExternalPorts() {
203
- if (this.execution.external_ports) {
204
- _.forEach(this.execution.external_ports, (portValue) => {
205
- if (isNumber(portValue)) {
206
- this.resource.spec.template.spec.containers[0].ports
207
- .push({ containerPort: portValue });
208
- } else {
209
- this.resource.spec.template.spec.containers[0].ports
210
- .push(
211
- {
212
- name: portValue.name,
213
- containerPort: portValue.port
214
- }
215
- );
216
- }
217
- });
218
- }
219
- }
220
-
221
- _setImagePullSecret() {
222
- if (this.terasliceConfig.kubernetes_image_pull_secret) {
223
- this.resource.spec.template.spec.imagePullSecrets = [
224
- { name: this.terasliceConfig.kubernetes_image_pull_secret }
225
- ];
226
- }
227
- }
228
-
229
- _setPriorityClassName() {
230
- if (this.terasliceConfig.kubernetes_priority_class_name) {
231
- if (this.nodeType === 'execution_controller') {
232
- // eslint-disable-next-line max-len
233
- this.resource.spec.template.spec.priorityClassName = this.terasliceConfig.kubernetes_priority_class_name;
234
- if (this.execution.stateful) {
235
- // eslint-disable-next-line max-len
236
- this.resource.spec.template.metadata.labels[`${this.jobPropertyLabelPrefix}/stateful`] = 'true';
237
- }
238
- }
239
- if (this.nodeType === 'worker' && this.execution.stateful) {
240
- // eslint-disable-next-line max-len
241
- this.resource.spec.template.spec.priorityClassName = this.terasliceConfig.kubernetes_priority_class_name;
242
- // eslint-disable-next-line max-len
243
- this.resource.spec.template.metadata.labels[`${this.jobPropertyLabelPrefix}/stateful`] = 'true';
244
- }
245
- }
246
- }
247
-
248
- _setAssetsVolume() {
249
- if (this.terasliceConfig.assets_directory && this.terasliceConfig.assets_volume) {
250
- this.resource.spec.template.spec.volumes.push({
251
- name: this.terasliceConfig.assets_volume,
252
- persistentVolumeClaim: { claimName: this.terasliceConfig.assets_volume }
253
- });
254
- this.resource.spec.template.spec.containers[0].volumeMounts.push({
255
- name: this.terasliceConfig.assets_volume,
256
- mountPath: this.terasliceConfig.assets_directory
257
- });
258
- }
259
- }
260
-
261
- _setJobLabels() {
262
- if (this.execution.labels != null) {
263
- Object.entries(this.execution.labels).forEach(([k, v]) => {
264
- const key = `${this.jobLabelPrefix}/${_.replace(k, /[^a-zA-Z0-9\-._]/g, '-').substring(0, 63)}`;
265
- const value = _.replace(v, /[^a-zA-Z0-9\-._]/g, '-').substring(0, 63);
266
- this.resource.metadata.labels[key] = value;
267
-
268
- if (this.resource.kind !== 'Service') {
269
- // Services don't have templates, so if it's a service,
270
- // don't add this
271
- this.resource.spec.template.metadata.labels[key] = value;
272
- }
273
- });
274
- }
275
- }
276
-
277
- _setVolumes() {
278
- if (this.execution.volumes != null) {
279
- _.forEach(this.execution.volumes, (volume) => {
280
- this.resource.spec.template.spec.volumes.push({
281
- name: volume.name,
282
- persistentVolumeClaim: { claimName: volume.name }
283
- });
284
- this.resource.spec.template.spec.containers[0].volumeMounts.push({
285
- name: volume.name,
286
- mountPath: volume.path
287
- });
288
- });
289
- }
290
- }
291
-
292
- _setResources() {
293
- let cpu;
294
- let memory;
295
- let maxMemory;
296
-
297
- const container = this.resource.spec.template.spec.containers[0];
298
-
299
- // use teraslice config as defaults and execution config will override it
300
- const envVars = Object.assign({}, this.terasliceConfig.env_vars, this.execution.env_vars);
301
-
302
- if (this.nodeType === 'worker') {
303
- if (this.execution.resources_requests_cpu
304
- || this.execution.resources_limits_cpu) {
305
- if (this.execution.resources_requests_cpu) {
306
- _.set(container, 'resources.requests.cpu', this.execution.resources_requests_cpu);
307
- }
308
- if (this.execution.resources_limits_cpu) {
309
- _.set(container, 'resources.limits.cpu', this.execution.resources_limits_cpu);
310
- }
311
- } else if (this.execution.cpu || this.terasliceConfig.cpu) {
312
- // The settings on the executions override the cluster configs
313
- cpu = this.execution.cpu || this.terasliceConfig.cpu || -1;
314
- _.set(container, 'resources.requests.cpu', cpu);
315
- _.set(container, 'resources.limits.cpu', cpu);
316
- }
317
- if (this.execution.resources_requests_memory
318
- || this.execution.resources_limits_memory) {
319
- _.set(container, 'resources.requests.memory', this.execution.resources_requests_memory);
320
- _.set(container, 'resources.limits.memory', this.execution.resources_limits_memory);
321
- maxMemory = this.execution.resources_limits_memory;
322
- } else if (this.execution.memory || this.terasliceConfig.memory) {
323
- // The settings on the executions override the cluster configs
324
- memory = this.execution.memory || this.terasliceConfig.memory || -1;
325
- _.set(container, 'resources.requests.memory', memory);
326
- _.set(container, 'resources.limits.memory', memory);
327
- maxMemory = memory;
328
- }
329
- }
330
-
331
- if (this.nodeType === 'execution_controller') {
332
- // The settings on the executions override the cluster configs
333
- cpu = this.execution.cpu_execution_controller
334
- || this.terasliceConfig.cpu_execution_controller || -1;
335
- memory = this.execution.memory_execution_controller
336
- || this.terasliceConfig.memory_execution_controller || -1;
337
- _.set(container, 'resources.requests.cpu', cpu);
338
- _.set(container, 'resources.limits.cpu', cpu);
339
- _.set(container, 'resources.requests.memory', memory);
340
- _.set(container, 'resources.limits.memory', memory);
341
- maxMemory = memory;
342
- }
343
-
344
- // NOTE: This sucks, this manages the memory env var but it ALSO is
345
- // responsible for doing the config and execution env var merge, which
346
- // should NOT be in this function
347
- setMaxOldSpaceViaEnv(container.env, envVars, maxMemory);
348
- }
349
-
350
- _setTargets() {
351
- if (_.has(this.execution, 'targets') && (!_.isEmpty(this.execution.targets))) {
352
- _.forEach(this.execution.targets, (target) => {
353
- // `required` is the default if no `constraint` is provided for
354
- // backwards compatibility and as the most likely case
355
- if (target.constraint === 'required' || !_.has(target, 'constraint')) {
356
- this._setTargetRequired(target);
357
- }
358
-
359
- if (target.constraint === 'preferred') {
360
- this._setTargetPreferred(target);
361
- }
362
-
363
- if (target.constraint === 'accepted') {
364
- this._setTargetAccepted(target);
365
- }
366
- });
367
- }
368
- }
369
-
370
- _setTargetRequired(target) {
371
- const targetKey = 'spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution';
372
- if (!_.has(this.resource, targetKey)) {
373
- const nodeSelectorObj = {
374
- nodeSelectorTerms: [{ matchExpressions: [] }]
375
- };
376
- _.set(this.resource, targetKey, nodeSelectorObj);
377
- }
378
-
379
- this.resource.spec.template.spec.affinity.nodeAffinity
380
- .requiredDuringSchedulingIgnoredDuringExecution
381
- .nodeSelectorTerms[0].matchExpressions.push({
382
- key: target.key,
383
- operator: 'In',
384
- values: [target.value]
385
- });
386
- }
387
-
388
- _setTargetPreferred(target) {
389
- const targetKey = 'spec.template.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution';
390
- if (!_.has(this.resource, targetKey)) {
391
- _.set(this.resource, targetKey, []);
392
- }
393
-
394
- this.resource.spec.template.spec.affinity.nodeAffinity
395
- .preferredDuringSchedulingIgnoredDuringExecution.push({
396
- weight: 1,
397
- preference: {
398
- matchExpressions: [{
399
- key: target.key,
400
- operator: 'In',
401
- values: [target.value]
402
- }]
403
- }
404
- });
405
- }
406
-
407
- _setTargetAccepted(target) {
408
- const targetKey = 'spec.template.spec.tolerations';
409
- if (!_.has(this.resource, targetKey)) {
410
- _.set(this.resource, targetKey, []);
411
- }
412
-
413
- this.resource.spec.template.spec.tolerations.push({
414
- key: target.key,
415
- operator: 'Equal',
416
- value: target.value,
417
- effect: 'NoSchedule'
418
- });
419
- }
420
-
421
- /**
422
- * _mergePodSpecOverlay - allows the author of the job to override anything
423
- * in the pod .spec for both the execution controller and the worker pods
424
- * created in Kubernetes. This can be useful in many ways including these:
425
- *
426
- * * add `initContainers` to the pods
427
- * * add `hostAliases` to the pods
428
- *
429
- * Note that this happens at the end of the process, so anything added by
430
- * this overlay will overwrite any other setting set on the job or by the
431
- * config.
432
- *
433
- * Job setting: `pod_spec_override`
434
- */
435
- _mergePodSpecOverlay() {
436
- this.resource.spec.template.spec = _.merge(
437
- this.resource.spec.template.spec,
438
- this.execution.pod_spec_override
439
- );
440
- }
441
- }
442
-
443
- module.exports = K8sResource;
@@ -1,67 +0,0 @@
1
- 'use strict';
2
-
3
- const _ = require('lodash');
4
-
5
- /**
6
- * Given the k8s Pods API output generates the appropriate Teraslice cluster
7
- * state. NOTE: This assumes the pods have already been filtered to ensure they
8
- * are teraslice pods and match the cluster in question.
9
- * @param {Object} k8sPods k8s pods API object (k8s v1.10+)
10
- * @param {Object} clusterState Teraslice Cluster State
11
- * @param {String} clusterNameLabel k8s label containing clusterName
12
- */
13
- function gen(k8sPods, clusterState) {
14
- // Make sure we clean up the old
15
- const hostIPs = _.uniq(_.map(k8sPods.items, 'status.hostIP'));
16
- const oldHostIps = _.difference(_.keys(clusterState), hostIPs);
17
- _.forEach(oldHostIps, (ip) => {
18
- delete clusterState[ip];
19
- });
20
-
21
- // Loop over the nodes in clusterState and set active = [] so we can append
22
- // later
23
- Object.keys(clusterState).forEach((nodeId) => {
24
- clusterState[nodeId].active = [];
25
- });
26
-
27
- // add a worker for each pod
28
- k8sPods.items.forEach((pod) => {
29
- if (!_.has(clusterState, pod.status.hostIP)) {
30
- // If the node isn't in clusterState, add it
31
- clusterState[pod.status.hostIP] = {
32
- node_id: pod.status.hostIP,
33
- hostname: pod.status.hostIP,
34
- pid: 'N/A',
35
- node_version: 'N/A',
36
- teraslice_version: 'N/A',
37
- total: 'N/A',
38
- state: 'connected',
39
- available: 'N/A',
40
- active: []
41
- };
42
- }
43
-
44
- const worker = {
45
- assets: [],
46
- assignment: pod.metadata.labels['app.kubernetes.io/component'],
47
- ex_id: pod.metadata.labels['teraslice.terascope.io/exId'],
48
- // WARNING: This makes the assumption that the first container
49
- // in the pod is the teraslice container. Currently it is the
50
- // only container, so this assumption is safe for now.
51
- image: pod.spec.containers[0].image,
52
- job_id: pod.metadata.labels['teraslice.terascope.io/jobId'],
53
- pod_name: pod.metadata.name,
54
- pod_ip: pod.status.podIP,
55
- worker_id: pod.metadata.name,
56
- };
57
-
58
- // k8s pods can have status.phase = `Pending`, `Running`, `Succeeded`,
59
- // `Failed`, `Unknown`. We will only add `Running` pods to the
60
- // Teraslice cluster state.
61
- if (pod.status.phase === 'Running') {
62
- clusterState[pod.status.hostIP].active.push(worker);
63
- }
64
- });
65
- }
66
-
67
- exports.gen = gen;
@@ -1,58 +0,0 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const barbe = require('barbe');
6
-
7
- const { isTest } = require('@terascope/utils');
8
-
9
- function makeTemplate(folder, fileName) {
10
- const filePath = path.join(__dirname, folder, `${fileName}.hbs`);
11
- const templateData = fs.readFileSync(filePath, 'utf-8');
12
- const templateKeys = ['{{', '}}'];
13
-
14
- return (config) => {
15
- const templated = barbe(templateData, templateKeys, config);
16
- return JSON.parse(templated);
17
- };
18
- }
19
-
20
- // Convert bytes to MB and reduce by 10%
21
- function getMaxOldSpace(memory) {
22
- return Math.round(0.9 * (memory / 1024 / 1024));
23
- }
24
-
25
- function setMaxOldSpaceViaEnv(envArr, jobEnv, memory) {
26
- const envObj = {};
27
- if (memory && memory > -1) {
28
- // Set NODE_OPTIONS to override max-old-space-size
29
- const maxOldSpace = getMaxOldSpace(memory);
30
- envObj.NODE_OPTIONS = `--max-old-space-size=${maxOldSpace}`;
31
- }
32
-
33
- Object.assign(envObj, jobEnv);
34
-
35
- Object.entries(envObj).forEach(([name, value]) => {
36
- envArr.push({
37
- name,
38
- value
39
- });
40
- });
41
- }
42
-
43
- const MAX_RETRIES = isTest ? 2 : 3;
44
- const RETRY_DELAY = isTest ? 50 : 1000; // time in ms
45
-
46
- function getRetryConfig() {
47
- return {
48
- retries: MAX_RETRIES,
49
- delay: RETRY_DELAY
50
- };
51
- }
52
-
53
- module.exports = {
54
- getMaxOldSpace,
55
- getRetryConfig,
56
- makeTemplate,
57
- setMaxOldSpaceViaEnv
58
- };