@hatchet-dev/typescript-sdk 1.33.0 → 1.33.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/package.json +1 -1
- package/v1/embedded.js +61 -3
- package/version.d.ts +1 -1
- package/version.js +1 -1
package/package.json
CHANGED
package/v1/embedded.js
CHANGED
|
@@ -83,6 +83,46 @@ const net_1 = require("net");
|
|
|
83
83
|
const promises_1 = require("stream/promises");
|
|
84
84
|
const REPO_URL = 'https://github.com/hatchet-dev/hatchet-embedded';
|
|
85
85
|
const DEFAULT_READY_TIMEOUT_MS = 300000;
|
|
86
|
+
const SLOW_NOTICE_DELAY_MS = 2000;
|
|
87
|
+
const HEARTBEAT_INTERVAL_MS = 30000;
|
|
88
|
+
// first-contact progress goes to stderr (like the engine's own output) so it
|
|
89
|
+
// never corrupts program output; warm starts print at most one line
|
|
90
|
+
function logProgress(message) {
|
|
91
|
+
process.stderr.write(`hatchet embedded: ${message}\n`);
|
|
92
|
+
}
|
|
93
|
+
// prints startMsg only if fn is still running after SLOW_NOTICE_DELAY_MS (and
|
|
94
|
+
// doneMsg once it finishes), so fast warm-start network calls stay quiet while
|
|
95
|
+
// a blocked one explains what the process is waiting on
|
|
96
|
+
function withSlowNotice(startMsg, doneMsg, fn) {
|
|
97
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
+
var _a;
|
|
99
|
+
let noticed = false;
|
|
100
|
+
let finished = false;
|
|
101
|
+
const timer = setTimeout(() => {
|
|
102
|
+
// guards a callback already queued when fn settles, so a stale start
|
|
103
|
+
// message can never print after completion
|
|
104
|
+
if (finished) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
noticed = true;
|
|
108
|
+
logProgress(startMsg);
|
|
109
|
+
}, SLOW_NOTICE_DELAY_MS);
|
|
110
|
+
(_a = timer.unref) === null || _a === void 0 ? void 0 : _a.call(timer);
|
|
111
|
+
let result;
|
|
112
|
+
try {
|
|
113
|
+
result = yield fn();
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
finished = true;
|
|
117
|
+
clearTimeout(timer);
|
|
118
|
+
}
|
|
119
|
+
// only reached when fn succeeded
|
|
120
|
+
if (noticed) {
|
|
121
|
+
logProgress(doneMsg);
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
86
126
|
function sidecarAssetName() {
|
|
87
127
|
const platform = { darwin: 'darwin', linux: 'linux' }[process.platform];
|
|
88
128
|
const arch = { x64: 'amd64', arm64: 'arm64' }[process.arch];
|
|
@@ -168,17 +208,18 @@ function resolveExpectedChecksum(tag, asset, binPath) {
|
|
|
168
208
|
}
|
|
169
209
|
function ensureSidecarBinary(version, checksum) {
|
|
170
210
|
return __awaiter(this, void 0, void 0, function* () {
|
|
171
|
-
const tag = yield resolveVersion(version);
|
|
211
|
+
const tag = yield withSlowNotice(`resolving the latest hatchet-embedded release from ${REPO_URL}`, 'resolved the latest hatchet-embedded release', () => resolveVersion(version));
|
|
172
212
|
const asset = sidecarAssetName();
|
|
173
213
|
const binPath = path.join(os.homedir(), '.hatchet', 'embedded', tag, asset);
|
|
174
214
|
yield fs.mkdir(path.dirname(binPath), { recursive: true });
|
|
175
215
|
// verified on every start, not just at download; a cached binary that no
|
|
176
216
|
// longer matches the expected checksum is re-downloaded
|
|
177
|
-
const expected = checksum !== null && checksum !== void 0 ? checksum : (yield resolveExpectedChecksum(tag, asset, binPath));
|
|
217
|
+
const expected = checksum !== null && checksum !== void 0 ? checksum : (yield withSlowNotice(`resolving the expected checksum for ${tag} (the cached checksum is used if the release cannot be reached)`, 'expected checksum resolved', () => resolveExpectedChecksum(tag, asset, binPath)));
|
|
178
218
|
const cached = yield fs.access(binPath).then(() => true, () => false);
|
|
179
219
|
if (cached && (yield sha256File(binPath)) === expected) {
|
|
180
220
|
return binPath;
|
|
181
221
|
}
|
|
222
|
+
logProgress(`downloading the embedded engine sidecar ${tag} to ${binPath} (tens of MB, cached for later runs)`);
|
|
182
223
|
const url = `${REPO_URL}/releases/download/${tag}/${asset}`;
|
|
183
224
|
const res = yield fetch(url);
|
|
184
225
|
if (!res.ok || !res.body) {
|
|
@@ -199,12 +240,15 @@ function ensureSidecarBinary(version, checksum) {
|
|
|
199
240
|
finally {
|
|
200
241
|
yield fs.rm(tmpPath, { force: true });
|
|
201
242
|
}
|
|
243
|
+
logProgress(`sidecar ${tag} downloaded`);
|
|
202
244
|
return binPath;
|
|
203
245
|
});
|
|
204
246
|
}
|
|
205
247
|
function waitForHandshake(child, handshakePath, timeoutMs) {
|
|
206
248
|
return __awaiter(this, void 0, void 0, function* () {
|
|
207
|
-
const
|
|
249
|
+
const start = Date.now();
|
|
250
|
+
const deadline = start + timeoutMs;
|
|
251
|
+
let nextHeartbeat = start + HEARTBEAT_INTERVAL_MS;
|
|
208
252
|
let exited;
|
|
209
253
|
child.once('exit', (code) => {
|
|
210
254
|
exited = new Error(`hatchet embedded sidecar exited with code ${code} before becoming ready`);
|
|
@@ -213,6 +257,11 @@ function waitForHandshake(child, handshakePath, timeoutMs) {
|
|
|
213
257
|
if (exited) {
|
|
214
258
|
throw exited;
|
|
215
259
|
}
|
|
260
|
+
if (Date.now() >= nextHeartbeat) {
|
|
261
|
+
const elapsed = Math.round((Date.now() - start) / 1000);
|
|
262
|
+
logProgress(`still waiting for the embedded engine (${elapsed}s elapsed)`);
|
|
263
|
+
nextHeartbeat += HEARTBEAT_INTERVAL_MS;
|
|
264
|
+
}
|
|
216
265
|
try {
|
|
217
266
|
const handshake = JSON.parse(yield fs.readFile(handshakePath, 'utf8'));
|
|
218
267
|
if (handshake.token) {
|
|
@@ -232,6 +281,8 @@ function waitForHandshake(child, handshakePath, timeoutMs) {
|
|
|
232
281
|
}
|
|
233
282
|
// sidecars started in this process that have not been stopped yet
|
|
234
283
|
const activeSidecars = new Set();
|
|
284
|
+
// the ambient-token warning is printed at most once per process
|
|
285
|
+
let warnedAmbientToken = false;
|
|
235
286
|
/**
|
|
236
287
|
* Gracefully stops every sidecar started in this process by
|
|
237
288
|
* `HatchetEmbeddedClient.init()` (or `startEmbeddedSidecar`) and resolves once
|
|
@@ -254,6 +305,10 @@ function stopEmbeddedSidecar() {
|
|
|
254
305
|
function startEmbeddedSidecar() {
|
|
255
306
|
return __awaiter(this, arguments, void 0, function* (opts = {}) {
|
|
256
307
|
var _a, _b;
|
|
308
|
+
if (process.env.HATCHET_CLIENT_TOKEN && !warnedAmbientToken) {
|
|
309
|
+
warnedAmbientToken = true;
|
|
310
|
+
logProgress('warning: HATCHET_CLIENT_TOKEN is set in the environment. Hatchet clients created with the standard constructor in this process will NOT use the embedded engine; unset HATCHET_CLIENT_TOKEN for embedded runs.');
|
|
311
|
+
}
|
|
257
312
|
const suppliedPath = (_a = opts.binaryPath) !== null && _a !== void 0 ? _a : process.env.HATCHET_CLIENT_EMBEDDED_BINARY_PATH;
|
|
258
313
|
let binPath;
|
|
259
314
|
if (suppliedPath) {
|
|
@@ -299,6 +354,9 @@ function startEmbeddedSidecar() {
|
|
|
299
354
|
const child = (0, child_process_1.spawn)(binPath, args, { stdio: ['pipe', 'ignore', 'inherit'] });
|
|
300
355
|
const killChild = () => child.kill();
|
|
301
356
|
process.once('exit', killChild);
|
|
357
|
+
logProgress(opts.databaseUrl
|
|
358
|
+
? 'starting the embedded engine'
|
|
359
|
+
: 'starting the embedded engine (first run initializes a bundled Postgres and can take a minute)');
|
|
302
360
|
let handshake;
|
|
303
361
|
try {
|
|
304
362
|
handshake = yield waitForHandshake(child, handshakePath, (_b = opts.readyTimeoutMs) !== null && _b !== void 0 ? _b : DEFAULT_READY_TIMEOUT_MS);
|
package/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const HATCHET_VERSION = "1.33.
|
|
1
|
+
export declare const HATCHET_VERSION = "1.33.1";
|
package/version.js
CHANGED