teraslice 0.87.0 → 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,303 +0,0 @@
1
- 'use strict';
2
-
3
- const defaultsDeep = require('lodash/defaultsDeep');
4
- const {
5
- TSError,
6
- uniq,
7
- get,
8
- cloneDeep,
9
- isEmpty,
10
- getTypeOf,
11
- isString,
12
- } = require('@terascope/utils');
13
- const { JobValidator } = require('@terascope/job-components');
14
- const { makeLogger } = require('../../workers/helpers/terafoundation');
15
- const spawnAssetsLoader = require('../../workers/assets/spawn');
16
- const { terasliceOpPath } = require('../../config');
17
-
18
- /**
19
- * New execution result
20
- * @typedef NewExecutionResult
21
- * @property {string} job_id
22
- * @property {string} ex_id
23
- */
24
-
25
- module.exports = function jobsService(context) {
26
- let executionService;
27
- let exStore;
28
- let jobStore;
29
-
30
- const logger = makeLogger(context, 'jobs_service');
31
-
32
- const jobValidator = new JobValidator(context, {
33
- terasliceOpPath,
34
- assetPath: get(context, 'sysconfig.teraslice.assets_directory'),
35
- });
36
-
37
- /**
38
- * Validate the job spec
39
- *
40
- * @returns {Promise<import('@terascope/job-components').ValidatedJobConfig>}
41
- */
42
- async function _validateJobSpec(jobSpec) {
43
- const parsedAssetJob = await _ensureAssets(cloneDeep(jobSpec));
44
- const validJob = await jobValidator.validateConfig(parsedAssetJob);
45
- return validJob;
46
- }
47
-
48
- async function submitJob(jobSpec, shouldRun) {
49
- if (jobSpec.job_id) {
50
- throw new TSError('Job cannot include a job_id on submit', {
51
- statusCode: 422,
52
- });
53
- }
54
-
55
- const validJob = await _validateJobSpec(jobSpec);
56
- const job = await jobStore.create(jobSpec);
57
- if (!shouldRun) {
58
- return { job_id: job.job_id };
59
- }
60
-
61
- const exConfig = Object.assign({}, jobSpec, validJob, {
62
- job_id: job.job_id
63
- });
64
- return executionService.createExecutionContext(exConfig);
65
- }
66
-
67
- /**
68
- * Sets the `active` property on the job to `true` or `false`.
69
- * @param {string} jobId
70
- * @param {boolean} activeState
71
- */
72
- async function setActiveState(jobId, activeState) {
73
- const job = await jobStore.get(jobId);
74
- if (activeState === true) {
75
- job.active = true;
76
- } else {
77
- job.active = false;
78
- }
79
- logger.info(`Setting jobId: ${jobId} to active: ${activeState}`);
80
- return updateJob(jobId, job);
81
- }
82
-
83
- async function updateJob(jobId, jobSpec) {
84
- await _validateJobSpec(jobSpec);
85
- const originalJob = await jobStore.get(jobId);
86
- return jobStore.update(jobId, Object.assign({}, jobSpec, {
87
- _created: originalJob._created
88
- }));
89
- }
90
-
91
- /**
92
- * Start a Job
93
- *
94
- * @param {string} jobId
95
- * @returns {Promise<NewExecutionResult>}
96
- */
97
- async function startJob(jobId) {
98
- const activeExecution = await _getActiveExecution(jobId, true);
99
-
100
- // searching for an active execution, if there is then we reject
101
- if (activeExecution) {
102
- throw new TSError(`Job ${jobId} is currently running, cannot have the same job concurrently running`, {
103
- statusCode: 409
104
- });
105
- }
106
-
107
- const jobSpec = await jobStore.get(jobId);
108
- const validJob = await _validateJobSpec(jobSpec);
109
-
110
- if (validJob.autorecover) {
111
- return _recoverValidJob(validJob);
112
- }
113
-
114
- return executionService.createExecutionContext(validJob);
115
- }
116
-
117
- /**
118
- * Recover a job using the valid configuration
119
- *
120
- * @private
121
- * @param {import('@terascope/job-components').ValidatedJobConfig} validJob
122
- * @param {import('@terascope/job-components').RecoveryCleanupType} [cleanupType]
123
- * @returns {Promise<NewExecutionResult>}
124
- */
125
- async function _recoverValidJob(validJob, cleanupType) {
126
- const recoverFrom = await getLatestExecution(validJob.job_id, undefined, true);
127
-
128
- // if there isn't an execution and autorecover is true
129
- // create a new execution else throw
130
- if (!recoverFrom) {
131
- if (validJob.autorecover) {
132
- return executionService.createExecutionContext(validJob);
133
- }
134
-
135
- throw new TSError(`Job ${validJob.job_id} is missing an execution to recover from`, {
136
- statusCode: 404
137
- });
138
- }
139
-
140
- if (validJob.slicers !== recoverFrom.slicers) {
141
- const changedFrom = `from ${recoverFrom.slicers} to ${validJob.slicers}`;
142
- logger.warn(`recovery for job ${recoverFrom.job_id} changed slicers ${changedFrom}`);
143
- }
144
-
145
- return executionService.recoverExecution(
146
- // apply the latest job config changes
147
- defaultsDeep({}, validJob, recoverFrom),
148
- cleanupType
149
- );
150
- }
151
-
152
- /**
153
- * Recover a job, applied the last changes to the prev execution
154
- *
155
- * @param {string} jobId
156
- * @param {import('@terascope/job-components').RecoveryCleanupType} [cleanupType]
157
- * @returns {Promise<NewExecutionResult>}
158
- */
159
- async function recoverJob(jobId, cleanupType) {
160
- // we need to do validations since the job config could change between recovery
161
- const jobSpec = await jobStore.get(jobId);
162
- const validJob = await _validateJobSpec(jobSpec);
163
- return _recoverValidJob(validJob, cleanupType);
164
- }
165
-
166
- async function pauseJob(jobId) {
167
- return getLatestExecutionId(jobId).then((exId) => executionService.pauseExecution(exId));
168
- }
169
-
170
- async function resumeJob(jobId) {
171
- return getLatestExecutionId(jobId).then((exId) => executionService.resumeExecution(exId));
172
- }
173
-
174
- /**
175
- * Get the latest execution
176
- *
177
- * @param {string} jobId
178
- * @param {string} [query]
179
- * @param {boolean=false} [allowZeroResults]
180
- * @returns {Promise<import('@terascope/job-components').ExecutionConfig>}
181
- */
182
- async function getLatestExecution(jobId, query, allowZeroResults = false) {
183
- if (!jobId || !isString(jobId)) {
184
- throw new TSError(`Invalid job id, got ${getTypeOf(jobId)}`);
185
- }
186
-
187
- const ex = await exStore.search(
188
- query || `job_id: "${jobId}"`, null, 1, '_created:desc'
189
- );
190
-
191
- if (!allowZeroResults && !ex.length) {
192
- throw new TSError(`No execution was found for job ${jobId}`, {
193
- statusCode: 404
194
- });
195
- }
196
- return ex[0];
197
- }
198
-
199
- /**
200
- * Get the active execution
201
- *
202
- * @param {string} jobId
203
- * @param {boolean} [allowZeroResults]
204
- * @returns {Promise<import('@terascope/job-components').ExecutionConfig>}
205
- */
206
- async function _getActiveExecution(jobId, allowZeroResults) {
207
- const str = exStore
208
- .getTerminalStatuses()
209
- .map((state) => ` _status:"${state}"`)
210
- .join(' OR ');
211
- const query = `job_id:"${jobId}" AND _context:ex NOT (${str.trim()})`;
212
- return getLatestExecution(jobId, query, allowZeroResults);
213
- }
214
-
215
- /**
216
- * Get the active execution
217
- *
218
- * @param {string} jobId
219
- * @param {boolean} [allowZeroResults]
220
- * @returns {Promise<import('@terascope/job-components').ExecutionConfig>}
221
- */
222
- async function _getActiveExecutionId(jobId) {
223
- return _getActiveExecution(jobId).then((ex) => ex.ex_id);
224
- }
225
-
226
- async function getLatestExecutionId(jobId) {
227
- return getLatestExecution(jobId).then((ex) => ex.ex_id);
228
- }
229
-
230
- async function shutdown() {
231
-
232
- }
233
-
234
- async function addWorkers(jobId, workerCount) {
235
- const exId = await _getActiveExecutionId(jobId);
236
- return executionService.addWorkers(exId, workerCount);
237
- }
238
-
239
- async function removeWorkers(jobId, workerCount) {
240
- const exId = await _getActiveExecutionId(jobId);
241
- return executionService.removeWorkers(exId, workerCount);
242
- }
243
-
244
- async function setWorkers(jobId, workerCount) {
245
- const exId = await _getActiveExecutionId(jobId);
246
- return executionService.setWorkers(exId, workerCount);
247
- }
248
-
249
- async function _ensureAssets(jobConfig) {
250
- const jobAssets = uniq(jobConfig.assets || []);
251
- if (isEmpty(jobAssets)) {
252
- return cloneDeep(jobConfig);
253
- }
254
- // convert asset references to their id's
255
- const assetIds = await spawnAssetsLoader(jobAssets);
256
- if (!assetIds.length) {
257
- throw new Error(`no asset id's were found for assets: ${JSON.stringify(jobAssets)}`);
258
- }
259
-
260
- if (jobAssets.length !== assetIds.length) {
261
- throw new Error(`job specified ${jobAssets.length} assets: ${jobAssets.assets} but only ${assetIds.length} where found, assets: ${assetIds}`);
262
- }
263
-
264
- // need to normalize asset identifiers to their id form
265
- // but not mutate original job_spec
266
- const parsedAssetJob = cloneDeep(jobConfig);
267
- parsedAssetJob.assets = assetIds;
268
- return parsedAssetJob;
269
- }
270
-
271
- async function initialize() {
272
- logger.info('job service is initializing...');
273
-
274
- exStore = context.stores.execution;
275
- jobStore = context.stores.jobs;
276
-
277
- if (jobStore == null || exStore == null) {
278
- throw new Error('Missing required stores');
279
- }
280
-
281
- executionService = context.services.execution;
282
- if (executionService == null) {
283
- throw new Error('Missing required services');
284
- }
285
- }
286
-
287
- return {
288
- submitJob,
289
- updateJob,
290
- startJob,
291
- pauseJob,
292
- resumeJob,
293
- recoverJob,
294
- setActiveState,
295
- addWorkers,
296
- removeWorkers,
297
- setWorkers,
298
- getLatestExecutionId,
299
- getLatestExecution,
300
- initialize,
301
- shutdown,
302
- }; // Load the initial pendingJobs state.
303
- };
@@ -1,47 +0,0 @@
1
- 'use strict';
2
-
3
- function hasKafkaConnector() {
4
- try {
5
- // eslint-disable-next-line
6
- require('terafoundation_kafka_connector');
7
- return true;
8
- } catch (err) {
9
- return false;
10
- }
11
- }
12
-
13
- function getConnectors() {
14
- const connectors = {
15
- elasticsearch: {
16
- default: {
17
- host: ['localhost:9200']
18
- }
19
- },
20
- 'elasticsearch-next': {
21
- default: {
22
- node: ['localhost:9200']
23
- }
24
- }
25
- };
26
-
27
- if (hasKafkaConnector()) {
28
- connectors.kafka = {
29
- default: {
30
- brokers: ['localhost:9092']
31
- }
32
- };
33
- }
34
-
35
- return connectors;
36
- }
37
-
38
- module.exports = {
39
- terafoundation: {
40
- environment: 'development',
41
- connectors: getConnectors()
42
- },
43
- teraslice: {
44
- master: true,
45
- name: 'teracluster'
46
- }
47
- };
@@ -1,32 +0,0 @@
1
- 'use strict';
2
-
3
- const path = require('path');
4
- const { get } = require('@terascope/utils');
5
- const { formats } = require('@terascope/job-components');
6
- const { configSchema } = require('./schemas/system');
7
-
8
- const terasliceOpPath = path.join(__dirname, '..');
9
-
10
- function clusterName(configFile) {
11
- return get(configFile, 'teraslice.name', null);
12
- }
13
-
14
- function getTerasliceConfig(sysconfig) {
15
- return Object.assign({
16
- name: 'teraslice',
17
- default_config_file: path.join(__dirname, 'default-sysconfig.js'),
18
- config_schema: configSchema,
19
- schema_formats: formats,
20
- cluster_name: clusterName,
21
- shutdownMessaging: false,
22
- start_workers: false,
23
- }, sysconfig);
24
- }
25
-
26
- module.exports = {
27
- terasliceOpPath,
28
- formats,
29
- configSchema,
30
- getTerasliceConfig,
31
- clusterName,
32
- };