teraslice-client-js 2.16.2 → 2.17.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 (53) hide show
  1. package/dist/src/executions.d.ts +1 -1
  2. package/dist/src/executions.d.ts.map +1 -1
  3. package/package.json +7 -4
  4. package/dist/test/assets-spec.d.ts +0 -2
  5. package/dist/test/assets-spec.d.ts.map +0 -1
  6. package/dist/test/assets-spec.js +0 -322
  7. package/dist/test/assets-spec.js.map +0 -1
  8. package/dist/test/client-spec.d.ts +0 -2
  9. package/dist/test/client-spec.d.ts.map +0 -1
  10. package/dist/test/client-spec.js +0 -374
  11. package/dist/test/client-spec.js.map +0 -1
  12. package/dist/test/cluster-spec.d.ts +0 -2
  13. package/dist/test/cluster-spec.d.ts.map +0 -1
  14. package/dist/test/cluster-spec.js +0 -143
  15. package/dist/test/cluster-spec.js.map +0 -1
  16. package/dist/test/ex-spec.d.ts +0 -2
  17. package/dist/test/ex-spec.d.ts.map +0 -1
  18. package/dist/test/ex-spec.js +0 -550
  19. package/dist/test/ex-spec.js.map +0 -1
  20. package/dist/test/executions-spec.d.ts +0 -2
  21. package/dist/test/executions-spec.d.ts.map +0 -1
  22. package/dist/test/executions-spec.js +0 -233
  23. package/dist/test/executions-spec.js.map +0 -1
  24. package/dist/test/job-spec.d.ts +0 -2
  25. package/dist/test/job-spec.d.ts.map +0 -1
  26. package/dist/test/job-spec.js +0 -837
  27. package/dist/test/job-spec.js.map +0 -1
  28. package/dist/test/jobs-spec.d.ts +0 -2
  29. package/dist/test/jobs-spec.d.ts.map +0 -1
  30. package/dist/test/jobs-spec.js +0 -241
  31. package/dist/test/jobs-spec.js.map +0 -1
  32. package/dist/tsconfig.tsbuildinfo +0 -1
  33. package/examples/cluster.js +0 -13
  34. package/examples/list.js +0 -16
  35. package/examples/submit.js +0 -48
  36. package/src/assets.ts +0 -99
  37. package/src/client.ts +0 -197
  38. package/src/cluster.ts +0 -48
  39. package/src/ex.ts +0 -223
  40. package/src/executions.ts +0 -82
  41. package/src/index.ts +0 -39
  42. package/src/interfaces.ts +0 -12
  43. package/src/job.ts +0 -260
  44. package/src/jobs.ts +0 -66
  45. package/test/assets-spec.ts +0 -376
  46. package/test/client-spec.ts +0 -416
  47. package/test/cluster-spec.ts +0 -167
  48. package/test/ex-spec.ts +0 -628
  49. package/test/executions-spec.ts +0 -260
  50. package/test/fixtures/test.txt +0 -1
  51. package/test/job-spec.ts +0 -947
  52. package/test/jobs-spec.ts +0 -272
  53. package/tsconfig.json +0 -12
package/src/executions.ts DELETED
@@ -1,82 +0,0 @@
1
- import {
2
- isString, isPlainObject, TSError, unset
3
- } from '@terascope/core-utils';
4
- import { Teraslice } from '@terascope/types';
5
- import autoBind from 'auto-bind';
6
- import Client from './client.js';
7
- import Ex from './ex.js';
8
- import { ClientConfig, RequestOptions } from './interfaces';
9
-
10
- type ListOptions = undefined | string | Teraslice.SearchQuery;
11
-
12
- export default class Executions extends Client {
13
- constructor(config: ClientConfig) {
14
- super(config);
15
- autoBind(this);
16
- }
17
-
18
- /**
19
- * Similar to jobs.submit but returns an instance of Ex not a Job
20
- */
21
- async submit(jobSpec: Teraslice.JobConfigParams, shouldNotStart?: boolean): Promise<Ex> {
22
- if (!jobSpec) {
23
- throw new TSError('Submit requires a jobSpec', {
24
- statusCode: 400
25
- });
26
- }
27
- const job: Teraslice.ApiJobCreateResponse = await this.post('/jobs', jobSpec, {
28
- searchParams: { start: !shouldNotStart }
29
- });
30
- // support older version of teraslice
31
- if (!job.ex_id) {
32
- const { ex_id: exId } = await this.get(`/jobs/${job.job_id}/ex`);
33
- return this.wrap(exId);
34
- }
35
-
36
- return this.wrap(job.ex_id);
37
- }
38
-
39
- async list(options?: ListOptions): Promise<Teraslice.ExecutionConfig[]> {
40
- const query = _parseListOptions(options);
41
- return this.get('/ex', { searchParams: query } as RequestOptions);
42
- }
43
-
44
- async errors(
45
- exId?: string | Teraslice.SearchQuery,
46
- opts?: Teraslice.SearchQuery
47
- ): Promise<Teraslice.ErrorRecord[]> {
48
- const options: Teraslice.SearchQuery = {};
49
- if (isString(exId)) {
50
- if (isPlainObject(opts)) {
51
- options.searchParams = opts;
52
- }
53
-
54
- return this.get(`/ex/${exId}/errors`, options as RequestOptions);
55
- }
56
-
57
- if (isPlainObject(exId)) {
58
- options.searchParams = exId;
59
- }
60
-
61
- return this.get('/ex/errors', options as RequestOptions);
62
- }
63
-
64
- /**
65
- * Wraps the execution id with convenience functions for accessing
66
- * the state on the server.
67
- */
68
- wrap(exId: string): Ex {
69
- return new Ex(this._config, exId);
70
- }
71
- }
72
-
73
- function _parseListOptions(options: ListOptions): Teraslice.SearchQuery {
74
- // support legacy
75
- if (!options) return {};
76
- if (isString(options)) {
77
- if (options === '*') return {};
78
- return { status: options };
79
- }
80
- if (options.status === '*') unset(options, 'status');
81
- return options;
82
- }
package/src/index.ts DELETED
@@ -1,39 +0,0 @@
1
- import Assets from './assets.js';
2
- import Cluster from './cluster.js';
3
- import Ex from './ex.js';
4
- import Executions from './executions.js';
5
- import Job from './job.js';
6
- import Jobs from './jobs.js';
7
- import * as i from './interfaces.js';
8
-
9
- class TerasliceClient {
10
- config?: i.ClientConfig;
11
- assets: Assets;
12
- cluster: Cluster;
13
- jobs: Jobs;
14
- executions: Executions;
15
-
16
- constructor(config: i.ClientConfig = {}) {
17
- this.config = config;
18
- this.assets = new Assets(config);
19
- this.cluster = new Cluster(config);
20
- this.jobs = new Jobs(config);
21
- this.executions = new Executions(config);
22
- }
23
-
24
- protected get ex(): never {
25
- throw new Error('TerasliceClient->ex is now removed in favor of executions and ex (wrapper) like a jobs/job');
26
- }
27
- }
28
-
29
- export * from './interfaces.js';
30
- export {
31
- TerasliceClient,
32
- Assets,
33
- Cluster,
34
- Executions,
35
- Ex,
36
- Jobs,
37
- Job
38
- };
39
- export default TerasliceClient;
package/src/interfaces.ts DELETED
@@ -1,12 +0,0 @@
1
- import { Options } from 'got';
2
-
3
- export interface ClientConfig {
4
- host?: string;
5
- baseUrl?: string;
6
- apiVersion?: string;
7
- timeout?: number;
8
- }
9
-
10
- export type RequestOptions = Partial<Options>;
11
-
12
- export type PostData = string | NodeJS.ReadableStream | Buffer;
package/src/job.ts DELETED
@@ -1,260 +0,0 @@
1
- import util from 'node:util';
2
- import autoBind from 'auto-bind';
3
- import {
4
- pDelay, isString, toString,
5
- TSError, toHumanTime
6
- } from '@terascope/core-utils';
7
- import { Teraslice } from '@terascope/types';
8
- import { ClientConfig, RequestOptions } from './interfaces.js';
9
- import Client from './client.js';
10
-
11
- /*
12
- * This is basically a wrapper around the job_id that acts as a proxy
13
- * to the server. It looks like an object but does not store the job
14
- * state internally. Any access to the state currently goes to the server.
15
- * Depending on how usage of this API develops we may want to reconsider this.
16
- */
17
-
18
- function _deprecateSlicerName(fn: () => Promise<Teraslice.ExecutionList>) {
19
- const msg = 'api endpoints with /slicers are being deprecated in favor of the semantically correct term of /controllers';
20
- return util.deprecate(fn, msg);
21
- }
22
-
23
- export default class Job extends Client {
24
- private readonly _jobId: string;
25
-
26
- constructor(config: ClientConfig, jobId: string) {
27
- super(config);
28
- if (!jobId || !isString(jobId)) {
29
- throw new TSError('Job requires jobId to be a string', {
30
- statusCode: 400
31
- });
32
- }
33
- this._jobId = jobId;
34
- this.slicer = _deprecateSlicerName(this.slicer);
35
- autoBind(this);
36
- }
37
-
38
- id(): string {
39
- return this._jobId;
40
- }
41
-
42
- async slicer(requestOptions: RequestOptions = {}): Promise<Teraslice.ExecutionList> {
43
- return this.get(`/jobs/${this._jobId}/slicer`, requestOptions);
44
- }
45
-
46
- async controller(requestOptions: RequestOptions = {}): Promise<Teraslice.ExecutionList> {
47
- return this.get(`/jobs/${this._jobId}/controller`, requestOptions);
48
- }
49
-
50
- async start(
51
- query?: Teraslice.SearchQuery,
52
- searchOptions: RequestOptions = {}
53
- ): Promise<Teraslice.ApiJobCreateResponse> {
54
- const options = this.makeOptions(query, searchOptions);
55
- return this.post(`/jobs/${this._jobId}/_start`, null, options);
56
- }
57
-
58
- async stop(
59
- query?: Teraslice.StopQuery,
60
- searchOptions: RequestOptions = {}
61
- ): Promise<Teraslice.ApiStoppedResponse> {
62
- const options = this.makeOptions(query, searchOptions);
63
- return this.post(`/jobs/${this._jobId}/_stop`, null, options);
64
- }
65
-
66
- async pause(
67
- query?: Teraslice.SearchQuery,
68
- searchOptions: RequestOptions = {}
69
- ): Promise<Teraslice.ApiPausedResponse> {
70
- const options = this.makeOptions(query, searchOptions);
71
- return this.post(`/jobs/${this._jobId}/_pause`, null, options);
72
- }
73
-
74
- async resume(
75
- query?: Teraslice.SearchQuery,
76
- searchOptions: RequestOptions = {}
77
- ): Promise<Teraslice.ApiResumeResponse> {
78
- const options = this.makeOptions(query, searchOptions);
79
- return this.post(`/jobs/${this._jobId}/_resume`, null, options);
80
- }
81
-
82
- async recover(
83
- query: Teraslice.RecoverQuery = {},
84
- searchOptions: RequestOptions = {}
85
- ): Promise<Teraslice.ApiJobCreateResponse> {
86
- const options = this.makeOptions(query, searchOptions);
87
- return this.post(`/jobs/${this._jobId}/_recover`, null, options);
88
- }
89
-
90
- async update(jobSpec: Teraslice.JobConfig): Promise<Teraslice.ApiJobUpdateResponse> {
91
- return this.put(`/jobs/${this._jobId}`, jobSpec);
92
- }
93
-
94
- async updatePartial(
95
- jobSpec: Partial<Teraslice.JobConfig>
96
- ): Promise<Teraslice.ApiJobUpdateResponse> {
97
- const current = await this.config();
98
- const body: Teraslice.JobConfig = Object.assign({}, current, jobSpec);
99
- return this.update(body);
100
- }
101
-
102
- async deleteJob(): Promise<Teraslice.JobConfig> {
103
- return this.delete(`/jobs/${this._jobId}`);
104
- }
105
-
106
- async execution(requestOptions: RequestOptions = {}): Promise<Teraslice.ExecutionConfig> {
107
- return this.get(`/jobs/${this._jobId}/ex`, requestOptions);
108
- }
109
-
110
- async exId(requestOptions: RequestOptions = {}): Promise<Teraslice.ExecutionIDResponse> {
111
- const { ex_id: exId } = await this.get(`/jobs/${this._jobId}/ex`, requestOptions);
112
- return exId;
113
- }
114
-
115
- async status(requestOptions: RequestOptions = {}): Promise<Teraslice.ExecutionStatus> {
116
- const { _status: status } = await this.get(`/jobs/${this._jobId}/ex`, requestOptions);
117
- return status;
118
- }
119
-
120
- async waitForStatus(
121
- target: Teraslice.ExecutionStatus[] | Teraslice.ExecutionStatus,
122
- intervalMs = 1000,
123
- timeoutMs = 0,
124
- requestOptions: RequestOptions = {}
125
- ): Promise<Teraslice.ExecutionStatus> {
126
- const terminal = {
127
- [Teraslice.ExecutionStatusEnum.terminated]: true,
128
- [Teraslice.ExecutionStatusEnum.failed]: true,
129
- [Teraslice.ExecutionStatusEnum.rejected]: true,
130
- [Teraslice.ExecutionStatusEnum.completed]: true,
131
- [Teraslice.ExecutionStatusEnum.stopped]: true,
132
- };
133
-
134
- const startTime = Date.now();
135
- const options = Object.assign({}, {
136
- responseType: 'json',
137
- timeout: {
138
- request: intervalMs < 1000 ? 1000 : intervalMs
139
- },
140
- }, requestOptions);
141
- let exId: string;
142
-
143
- const checkStatus = async (): Promise<Teraslice.ExecutionStatus> => {
144
- let result;
145
- try {
146
- const ex = await this.get<Teraslice.ExecutionConfig>(`/jobs/${this._jobId}/ex`, options);
147
- if (exId && ex.ex_id !== exId) {
148
- console.warn(`[WARNING] the execution ${ex.ex_id} has changed from ${exId}`);
149
- }
150
- exId = ex.ex_id;
151
- result = ex._status;
152
- } catch (err) {
153
- if (/(timeout|timedout)/i.test(toString(err))) {
154
- await pDelay(intervalMs);
155
- return checkStatus();
156
- }
157
- throw err;
158
- }
159
-
160
- if (result === target || (Array.isArray(target) && target.includes(result))) {
161
- return result;
162
- }
163
-
164
- // These are terminal states for a job so if we're not explicitly
165
- // watching for these then we need to stop waiting as the job
166
- // status won't change further.
167
- if (result in terminal) {
168
- throw new TSError(
169
- `Job cannot reach the target status, "${target}", because it is in the terminal state, "${result}"`,
170
- { context: { lastStatus: result } }
171
- );
172
- }
173
-
174
- const elapsed = Date.now() - startTime;
175
- if (timeoutMs > 0 && elapsed >= timeoutMs) {
176
- throw new TSError(
177
- `Job status failed to change from status "${result}" to "${target}" within ${toHumanTime(timeoutMs)}`,
178
- { context: { lastStatus: result } }
179
- );
180
- }
181
-
182
- await pDelay(intervalMs);
183
- return checkStatus();
184
- };
185
-
186
- return checkStatus();
187
- }
188
-
189
- async config(requestOptions: RequestOptions = {}): Promise<Teraslice.JobConfig> {
190
- return this.get(`/jobs/${this._jobId}`, requestOptions);
191
- }
192
-
193
- async errors(
194
- query: Teraslice.SearchQuery = {},
195
- searchOptions: RequestOptions = {}
196
- ): Promise<Teraslice.ErrorRecord[]> {
197
- return this.get(`/jobs/${this._jobId}/errors`, this.makeOptions(query, searchOptions));
198
- }
199
-
200
- async workers(requestOptions: RequestOptions = {}): Promise<Teraslice.WorkerNode[]> {
201
- const state: Teraslice.ClusterState = await this.get('/cluster/state', requestOptions);
202
- return filterProcesses<Teraslice.WorkerNode>(state, this._jobId, 'worker');
203
- }
204
-
205
- async changeWorkers(
206
- action: Teraslice.ChangeWorkerQueryParams,
207
- workerNum: number,
208
- requestOptions: RequestOptions = {}
209
- ): Promise<Teraslice.ChangeWorkerResponse | string> {
210
- if (action == null || workerNum == null) {
211
- throw new TSError('Change workers requires action and count', {
212
- statusCode: 400
213
- });
214
- }
215
- if (!['add', 'remove', 'total'].includes(action)) {
216
- throw new TSError('Change workers requires action to be one of add, remove, or total', {
217
- statusCode: 400
218
- });
219
- }
220
-
221
- const query = { [action]: workerNum };
222
- requestOptions.responseType = 'text';
223
- const options = this.makeOptions(query, requestOptions);
224
-
225
- const response = await this.post(`/jobs/${this._jobId}/_workers`, null, options);
226
- // for backwards compatability
227
- if (typeof response === 'string') {
228
- try {
229
- return this.parse(response);
230
- } catch (err) {
231
- // do nothing
232
- }
233
- }
234
-
235
- return response;
236
- }
237
- }
238
-
239
- function filterProcesses<T>(
240
- state: Teraslice.ClusterState,
241
- jobId: string,
242
- type: Teraslice.Assignment
243
- ) {
244
- const results: T[] = [];
245
-
246
- for (const [, node] of Object.entries(state)) {
247
- // TODO: fix this
248
- node.active.forEach((child: any) => {
249
- if (child.job_id) {
250
- const { assignment, job_id: procJobId } = child;
251
- if ((assignment && assignment === type) && (procJobId && procJobId === jobId)) {
252
- const jobProcess = Object.assign({}, child, { node_id: node.node_id });
253
- results.push(jobProcess);
254
- }
255
- }
256
- });
257
- }
258
-
259
- return results;
260
- }
package/src/jobs.ts DELETED
@@ -1,66 +0,0 @@
1
- import { TSError } from '@terascope/core-utils';
2
- import { Teraslice } from '@terascope/types';
3
- import autoBind from 'auto-bind';
4
- import Client from './client.js';
5
- import Job from './job.js';
6
- import { RequestOptions, ClientConfig } from './interfaces.js';
7
-
8
- export default class Jobs extends Client {
9
- constructor(config: ClientConfig) {
10
- super(config);
11
- autoBind(this);
12
- }
13
-
14
- async submit(jobSpec: Teraslice.JobConfigParams, shouldNotStart?: boolean): Promise<Job> {
15
- if (!jobSpec) {
16
- throw new TSError('Submit requires a jobSpec', {
17
- statusCode: 400
18
- });
19
- }
20
-
21
- const job: Teraslice.ApiJobCreateResponse = await this.post('/jobs', jobSpec, {
22
- searchParams: { start: !shouldNotStart }
23
- });
24
-
25
- return this.wrap(job.job_id);
26
- }
27
-
28
- // TODO: Teraslice v4 this exists to avoid a breaking change to submit() which returns just
29
- // the Job. This is only used by teraslice-cli. In Teraslice v4, submit() should
30
- // be updated to return warnings and this method removed.
31
- // See https://github.com/terascope/teraslice/issues/4501
32
- async submitWithWarnings(
33
- jobSpec: Teraslice.JobConfigParams,
34
- shouldNotStart?: boolean
35
- ): Promise<{ job: Job; warnings: Teraslice.JobWarning[] }> {
36
- if (!jobSpec) {
37
- throw new TSError('Submit requires a jobSpec', {
38
- statusCode: 400
39
- });
40
- }
41
-
42
- const response: Teraslice.ApiJobCreateResponse = await this.post('/jobs', jobSpec, {
43
- searchParams: { start: !shouldNotStart }
44
- });
45
-
46
- return {
47
- job: this.wrap(response.job_id),
48
- warnings: response.warnings ?? []
49
- };
50
- }
51
-
52
- async list(
53
- query?: Teraslice.JobSearchParams,
54
- searchOptions: RequestOptions = {}
55
- ): Promise<Teraslice.JobConfig[]> {
56
- return this.get('/jobs', this.makeOptions(query, searchOptions));
57
- }
58
-
59
- /**
60
- * Wraps the job_id with convenience functions for accessing
61
- * the state on the server.
62
- */
63
- wrap(jobId: string): Job {
64
- return new Job(this._config, jobId);
65
- }
66
- }