@hatchet-dev/typescript-sdk 0.15.1-alpha5 → 0.15.1
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/clients/dispatcher/dispatcher-client.d.ts +2 -1
- package/clients/dispatcher/dispatcher-client.js +10 -1
- package/clients/event/event-client.js +16 -14
- package/clients/listener/child-listener-client.js +10 -16
- package/examples/on-failure.js +15 -10
- package/package.json +5 -4
- package/protoc/dispatcher/dispatcher.d.ts +19 -0
- package/protoc/dispatcher/dispatcher.js +368 -92
- package/protoc/events/events.js +45 -23
- package/protoc/google/protobuf/timestamp.js +5 -3
- package/protoc/workflows/workflows.d.ts +9 -0
- package/protoc/workflows/workflows.js +275 -82
- package/util/retrier.js +1 -1
- package/version.d.ts +1 -0
- package/version.js +4 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Channel, ClientFactory } from 'nice-grpc';
|
|
2
|
-
import { DispatcherClient as PbDispatcherClient, StepActionEvent, GroupKeyActionEvent, OverridesData, DeepPartial } from '../../protoc/dispatcher';
|
|
2
|
+
import { DispatcherClient as PbDispatcherClient, StepActionEvent, GroupKeyActionEvent, OverridesData, DeepPartial, RuntimeInfo } from '../../protoc/dispatcher';
|
|
3
3
|
import { ClientConfig } from '../hatchet-client/client-config';
|
|
4
4
|
import { Logger } from '../../util/logger';
|
|
5
5
|
import { ActionListener } from './action-listener';
|
|
@@ -16,6 +16,7 @@ export declare class DispatcherClient {
|
|
|
16
16
|
client: PbDispatcherClient;
|
|
17
17
|
logger: Logger;
|
|
18
18
|
constructor(config: ClientConfig, channel: Channel, factory: ClientFactory);
|
|
19
|
+
getRuntimeInfo(): RuntimeInfo;
|
|
19
20
|
getActionListener(options: GetActionListenerOptions): Promise<ActionListener>;
|
|
20
21
|
sendStepActionEvent(in_: StepActionEvent): Promise<import("../../protoc/dispatcher").ActionEventResponse>;
|
|
21
22
|
sendGroupKeyActionEvent(in_: GroupKeyActionEvent): Promise<import("../../protoc/dispatcher").ActionEventResponse>;
|
|
@@ -17,6 +17,7 @@ const dispatcher_1 = require("../../protoc/dispatcher");
|
|
|
17
17
|
const hatchet_error_1 = __importDefault(require("../../util/errors/hatchet-error"));
|
|
18
18
|
const logger_1 = require("../../util/logger");
|
|
19
19
|
const retrier_1 = require("../../util/retrier");
|
|
20
|
+
const version_1 = require("../../version");
|
|
20
21
|
const action_listener_1 = require("./action-listener");
|
|
21
22
|
class DispatcherClient {
|
|
22
23
|
constructor(config, channel, factory) {
|
|
@@ -24,10 +25,18 @@ class DispatcherClient {
|
|
|
24
25
|
this.client = factory.create(dispatcher_1.DispatcherDefinition, channel);
|
|
25
26
|
this.logger = new logger_1.Logger(`Dispatcher`, config.log_level);
|
|
26
27
|
}
|
|
28
|
+
getRuntimeInfo() {
|
|
29
|
+
return {
|
|
30
|
+
sdkVersion: version_1.HATCHET_VERSION,
|
|
31
|
+
language: dispatcher_1.SDKS.TYPESCRIPT,
|
|
32
|
+
languageVersion: process.version,
|
|
33
|
+
os: process.platform,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
27
36
|
getActionListener(options) {
|
|
28
37
|
return __awaiter(this, void 0, void 0, function* () {
|
|
29
38
|
// Register the worker
|
|
30
|
-
const registration = yield this.client.register(Object.assign(Object.assign({}, options), { labels: options.labels ? mapLabels(options.labels) : undefined }));
|
|
39
|
+
const registration = yield this.client.register(Object.assign(Object.assign({}, options), { labels: options.labels ? mapLabels(options.labels) : undefined, runtimeInfo: this.getRuntimeInfo() }));
|
|
31
40
|
return new action_listener_1.ActionListener(this, registration.workerId);
|
|
32
41
|
});
|
|
33
42
|
}
|
|
@@ -84,20 +84,22 @@ class EventClient {
|
|
|
84
84
|
}
|
|
85
85
|
putLog(stepRunId, log, level) {
|
|
86
86
|
const createdAt = new Date();
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
87
|
+
if (log.length > 1000) {
|
|
88
|
+
this.logger.warn(`log is too long, skipping: ${log.length} characters`);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// fire and forget the log
|
|
92
|
+
this.client
|
|
93
|
+
.putLog({
|
|
94
|
+
stepRunId,
|
|
95
|
+
createdAt,
|
|
96
|
+
message: log,
|
|
97
|
+
level: level || LogLevel.INFO,
|
|
98
|
+
})
|
|
99
|
+
.catch((e) => {
|
|
100
|
+
// log a warning, but this is not a fatal error
|
|
101
|
+
this.logger.warn(`Could not put log: ${e.message}`);
|
|
102
|
+
});
|
|
101
103
|
}
|
|
102
104
|
putStream(stepRunId, data) {
|
|
103
105
|
const createdAt = new Date();
|
|
@@ -38,8 +38,6 @@ const events_1 = require("events");
|
|
|
38
38
|
const dispatcher_1 = require("../../protoc/dispatcher");
|
|
39
39
|
const abort_controller_x_1 = require("abort-controller-x");
|
|
40
40
|
const sleep_1 = __importDefault(require("../../util/sleep"));
|
|
41
|
-
const DEFAULT_EVENT_LISTENER_RETRY_INTERVAL = 5; // seconds
|
|
42
|
-
const DEFAULT_EVENT_LISTENER_RETRY_COUNT = 20;
|
|
43
41
|
class Streamable {
|
|
44
42
|
constructor(listener, id) {
|
|
45
43
|
this.responseEmitter = new events_1.EventEmitter();
|
|
@@ -71,11 +69,13 @@ class GrpcPooledListener {
|
|
|
71
69
|
init() {
|
|
72
70
|
return __awaiter(this, arguments, void 0, function* (retries = 0) {
|
|
73
71
|
var _a, e_1, _b, _c;
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
let retryCount = retries;
|
|
73
|
+
const MAX_RETRY_INTERVAL = 5000; // 5 seconds in milliseconds
|
|
74
|
+
const BASE_RETRY_INTERVAL = 100; // 0.1 seconds in milliseconds
|
|
76
75
|
if (retries > 0) {
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
const backoffTime = Math.min(BASE_RETRY_INTERVAL * 2 ** (retries - 1), MAX_RETRY_INTERVAL);
|
|
77
|
+
this.client.logger.info(`Retrying in ... ${backoffTime / 1000} seconds`);
|
|
78
|
+
yield (0, sleep_1.default)(backoffTime);
|
|
79
79
|
}
|
|
80
80
|
try {
|
|
81
81
|
this.client.logger.debug('Initializing child-listener');
|
|
@@ -90,17 +90,12 @@ class GrpcPooledListener {
|
|
|
90
90
|
_c = _f.value;
|
|
91
91
|
_d = false;
|
|
92
92
|
const event = _c;
|
|
93
|
+
retryCount = 0;
|
|
93
94
|
const emitter = this.subscribers[event.workflowRunId];
|
|
94
95
|
if (emitter) {
|
|
95
96
|
emitter.responseEmitter.emit('response', event);
|
|
96
97
|
if (event.eventType === dispatcher_1.WorkflowRunEventType.WORKFLOW_RUN_EVENT_TYPE_FINISHED) {
|
|
97
98
|
delete this.subscribers[event.workflowRunId];
|
|
98
|
-
if (Object.keys(this.subscribers).length === 0) {
|
|
99
|
-
// FIXME it would be better to cleanup on parent complete
|
|
100
|
-
this.client.logger.debug('All subscriptions finished, cleaning up listener');
|
|
101
|
-
this.signal.abort();
|
|
102
|
-
this.onFinish();
|
|
103
|
-
}
|
|
104
99
|
}
|
|
105
100
|
}
|
|
106
101
|
}
|
|
@@ -124,10 +119,9 @@ class GrpcPooledListener {
|
|
|
124
119
|
finally {
|
|
125
120
|
// it is possible the server hangs up early,
|
|
126
121
|
// restart the listener if we still have subscribers
|
|
127
|
-
this.client.logger.debug(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
122
|
+
this.client.logger.debug(`Child listener loop exited with ${Object.keys(this.subscribers).length} subscribers`);
|
|
123
|
+
this.client.logger.debug(`Restarting child listener retry ${retryCount + 1}`);
|
|
124
|
+
this.init(retryCount + 1);
|
|
131
125
|
}
|
|
132
126
|
});
|
|
133
127
|
}
|
package/examples/on-failure.js
CHANGED
|
@@ -13,36 +13,41 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const sdk_1 = __importDefault(require("../sdk"));
|
|
16
|
-
const hatchet = sdk_1.default.init(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
setTimeout(resolve, ms);
|
|
21
|
-
});
|
|
16
|
+
const hatchet = sdk_1.default.init();
|
|
17
|
+
// ❓ OnFailure Step
|
|
18
|
+
// This workflow will fail because the step will throw an error
|
|
19
|
+
// we define an onFailure step to handle this case
|
|
22
20
|
const workflow = {
|
|
21
|
+
// ... normal workflow definition
|
|
23
22
|
id: 'on-failure-example',
|
|
24
23
|
description: 'test',
|
|
25
24
|
on: {
|
|
26
25
|
event: 'user:create',
|
|
27
26
|
},
|
|
27
|
+
// ,
|
|
28
28
|
steps: [
|
|
29
29
|
{
|
|
30
|
-
name: '
|
|
30
|
+
name: 'step1',
|
|
31
31
|
run: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
-
|
|
33
|
-
yield sleep(1000);
|
|
32
|
+
// 👀 this step will always throw an error
|
|
34
33
|
throw new Error('Step 1 failed');
|
|
35
34
|
}),
|
|
36
35
|
},
|
|
37
36
|
],
|
|
37
|
+
// 👀 After the workflow fails, this special step will run
|
|
38
38
|
onFailure: {
|
|
39
39
|
name: 'on-failure-step',
|
|
40
40
|
run: (ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
-
|
|
41
|
+
// 👀 we can do things like perform cleanup logic
|
|
42
|
+
// or notify a user here
|
|
42
43
|
return { onFailure: 'step' };
|
|
43
44
|
}),
|
|
44
45
|
},
|
|
45
46
|
};
|
|
47
|
+
// ‼️
|
|
48
|
+
// ❓ OnFailure With Details
|
|
49
|
+
// Coming soon to TypeScript! https://github.com/hatchet-dev/hatchet-typescript/issues/447
|
|
50
|
+
// ‼️
|
|
46
51
|
function main() {
|
|
47
52
|
return __awaiter(this, void 0, void 0, function* () {
|
|
48
53
|
const worker = yield hatchet.worker('example-worker', 1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hatchet-dev/typescript-sdk",
|
|
3
|
-
"version": "0.15.1
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "Background task orchestration & visibility for developers",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"scripts": {
|
|
18
18
|
"build": "echo 'build hatchet sdk with `npn run tsc:build` to ensure it is not build during the publish step' && exit 0",
|
|
19
19
|
"prepare": "npm run build",
|
|
20
|
-
"
|
|
20
|
+
"dump-version": "node -e \"console.log('export const HATCHET_VERSION = \\'' + require('./package.json').version + '\\';');\" > src/version.ts",
|
|
21
|
+
"tsc:build": "npm run dump-version && tsc && resolve-tspaths",
|
|
21
22
|
"test:unit": "jest --testMatch='**/*.test.ts'",
|
|
22
23
|
"test:e2e": "jest --testMatch='**/*.e2e.ts'",
|
|
23
24
|
"test:unit:watch": "jest --testMatch='**/*.test.ts' --watch",
|
|
@@ -57,8 +58,8 @@
|
|
|
57
58
|
"worker:logger": "npm run exec -- ./src/examples/logger.ts",
|
|
58
59
|
"api": "npm run exec -- ./src/examples/api.ts",
|
|
59
60
|
"prepublish": "cp package.json dist/package.json;",
|
|
60
|
-
"publish:ci": "rm -rf ./dist && npm run tsc:build && npm run prepublish && cd dist && npm publish --access public --no-git-checks",
|
|
61
|
-
"publish:ci:alpha": "rm -rf ./dist && npm run tsc:build && npm run prepublish && cd dist && npm publish --access public --no-git-checks --tag alpha",
|
|
61
|
+
"publish:ci": "rm -rf ./dist && npm run dump-version && npm run tsc:build && npm run prepublish && cd dist && npm publish --access public --no-git-checks",
|
|
62
|
+
"publish:ci:alpha": "rm -rf ./dist && npm run dump-version && npm run tsc:build && npm run prepublish && cd dist && npm publish --access public --no-git-checks --tag alpha",
|
|
62
63
|
"generate-docs": "typedoc"
|
|
63
64
|
},
|
|
64
65
|
"keywords": [],
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire';
|
|
2
2
|
import { type CallContext, type CallOptions } from 'nice-grpc-common';
|
|
3
3
|
export declare const protobufPackage = "";
|
|
4
|
+
export declare enum SDKS {
|
|
5
|
+
UNKNOWN = 0,
|
|
6
|
+
GO = 1,
|
|
7
|
+
PYTHON = 2,
|
|
8
|
+
TYPESCRIPT = 3,
|
|
9
|
+
UNRECOGNIZED = -1
|
|
10
|
+
}
|
|
11
|
+
export declare function sDKSFromJSON(object: any): SDKS;
|
|
12
|
+
export declare function sDKSToJSON(object: SDKS): string;
|
|
4
13
|
export declare enum ActionType {
|
|
5
14
|
START_STEP_RUN = 0,
|
|
6
15
|
CANCEL_STEP_RUN = 1,
|
|
@@ -59,6 +68,13 @@ export interface WorkerLabels {
|
|
|
59
68
|
strValue?: string | undefined;
|
|
60
69
|
intValue?: number | undefined;
|
|
61
70
|
}
|
|
71
|
+
export interface RuntimeInfo {
|
|
72
|
+
sdkVersion?: string | undefined;
|
|
73
|
+
language?: SDKS | undefined;
|
|
74
|
+
languageVersion?: string | undefined;
|
|
75
|
+
os?: string | undefined;
|
|
76
|
+
extra?: string | undefined;
|
|
77
|
+
}
|
|
62
78
|
export interface WorkerRegisterRequest {
|
|
63
79
|
/** the name of the worker */
|
|
64
80
|
workerName: string;
|
|
@@ -74,6 +90,8 @@ export interface WorkerRegisterRequest {
|
|
|
74
90
|
};
|
|
75
91
|
/** (optional) webhookId is the id of the webhook that the worker is associated with (if any) */
|
|
76
92
|
webhookId?: string | undefined;
|
|
93
|
+
/** (optional) information regarding the runtime environment of the worker */
|
|
94
|
+
runtimeInfo?: RuntimeInfo | undefined;
|
|
77
95
|
}
|
|
78
96
|
export interface WorkerRegisterRequest_LabelsEntry {
|
|
79
97
|
key: string;
|
|
@@ -274,6 +292,7 @@ export interface ReleaseSlotRequest {
|
|
|
274
292
|
export interface ReleaseSlotResponse {
|
|
275
293
|
}
|
|
276
294
|
export declare const WorkerLabels: MessageFns<WorkerLabels>;
|
|
295
|
+
export declare const RuntimeInfo: MessageFns<RuntimeInfo>;
|
|
277
296
|
export declare const WorkerRegisterRequest: MessageFns<WorkerRegisterRequest>;
|
|
278
297
|
export declare const WorkerRegisterRequest_LabelsEntry: MessageFns<WorkerRegisterRequest_LabelsEntry>;
|
|
279
298
|
export declare const WorkerRegisterResponse: MessageFns<WorkerRegisterResponse>;
|