@dbx-tools/tunnel 0.6.215 → 0.6.216
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/README.md +5 -0
- package/index.ts +2 -2
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/src/portr.d.ts +7 -0
- package/lib/src/portr.js +22 -1
- package/lib/src/supervisor.d.ts +14 -2
- package/lib/src/supervisor.js +61 -3
- package/package.json +8 -8
- package/src/portr.ts +21 -0
- package/src/supervisor.ts +81 -4
package/README.md
CHANGED
|
@@ -89,6 +89,11 @@ middleware on the app's OWN Express server (no separate proxy process).
|
|
|
89
89
|
- Supervised teardown - `tunnelInterceptor` binds portr through the `createApp`
|
|
90
90
|
interceptor context, so the app and the tunnel are tied together: if either
|
|
91
91
|
exits, `bindProcess` brings the whole set down and passes signals through.
|
|
92
|
+
- Public liveness probes - while portr is running, the supervisor HEADs the
|
|
93
|
+
public URL. An `x-portr-error: unregistered-subdomain` (or any other
|
|
94
|
+
`x-portr-error`) kills the child so the forever-loop restarts it. Process-exit
|
|
95
|
+
supervision alone is not enough: portr can stay alive after the edge drops the
|
|
96
|
+
registration, leaving the subdomain dark until a full app bounce.
|
|
92
97
|
- The gate fails fast when email is not configured for SMTP, because a gate that
|
|
93
98
|
cannot send codes locks everyone out. `@dbx-tools/email` is an OPTIONAL peer
|
|
94
99
|
dependency, imported lazily; the app that mounts the gate provides it.
|
package/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
|
|
5
5
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/tunnel";
|
|
6
|
-
export const PACKAGE_VERSION = "0.6.
|
|
6
|
+
export const PACKAGE_VERSION = "0.6.216";
|
|
7
7
|
export * as allowlist from "./src/allowlist.ts";
|
|
8
8
|
export * as codeEmail from "./src/code-email.ts";
|
|
9
9
|
export * as frp from "./src/frp.ts";
|
|
@@ -30,4 +30,4 @@ export type { AuthGateConfig, SendCodeOptions, ResolvedAuthGateConfig, AuthGateA
|
|
|
30
30
|
export type { PortrInstallOptions, PortrConfig } from "./src/portr.ts";
|
|
31
31
|
export { KEY_TTL_SECONDS } from "./src/signing-key.ts";
|
|
32
32
|
export type { SigningKey } from "./src/signing-key.ts";
|
|
33
|
-
export type { ProcessSupervisor } from "./src/supervisor.ts";
|
|
33
|
+
export type { ProcessSupervisor, ProcessSupervisorOptions } from "./src/supervisor.ts";
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const PACKAGE_IDENTIFIER = "@dbx-tools/tunnel";
|
|
2
|
-
export declare const PACKAGE_VERSION = "0.6.
|
|
2
|
+
export declare const PACKAGE_VERSION = "0.6.216";
|
|
3
3
|
export * as allowlist from "./src/allowlist.ts";
|
|
4
4
|
export * as codeEmail from "./src/code-email.ts";
|
|
5
5
|
export * as frp from "./src/frp.ts";
|
|
@@ -26,4 +26,4 @@ export type { AuthGateConfig, SendCodeOptions, ResolvedAuthGateConfig, AuthGateA
|
|
|
26
26
|
export type { PortrInstallOptions, PortrConfig } from "./src/portr.ts";
|
|
27
27
|
export { KEY_TTL_SECONDS } from "./src/signing-key.ts";
|
|
28
28
|
export type { SigningKey } from "./src/signing-key.ts";
|
|
29
|
-
export type { ProcessSupervisor } from "./src/supervisor.ts";
|
|
29
|
+
export type { ProcessSupervisor, ProcessSupervisorOptions } from "./src/supervisor.ts";
|
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Regenerated from the exporting modules in ./src.
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/tunnel";
|
|
5
|
-
export const PACKAGE_VERSION = "0.6.
|
|
5
|
+
export const PACKAGE_VERSION = "0.6.216";
|
|
6
6
|
export * as allowlist from "./src/allowlist.js";
|
|
7
7
|
export * as codeEmail from "./src/code-email.js";
|
|
8
8
|
export * as frp from "./src/frp.js";
|
|
@@ -20,4 +20,4 @@ export { AUTH_PREFIX, UNAUTHORIZED_BODY } from "./src/gate.js";
|
|
|
20
20
|
export { PROTECTED_HEADERS, DEFAULT_FORWARD_HEADERS } from "./src/headers.js";
|
|
21
21
|
export { AuthGatePlugin, authGate } from "./src/plugin.js";
|
|
22
22
|
export { KEY_TTL_SECONDS } from "./src/signing-key.js";
|
|
23
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxtQkFBbUIsQ0FBQztBQUN0RCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxLQUFLLFNBQVMsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEtBQUssR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUNwQyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sS0FBSyxXQUFXLE1BQU0sc0JBQXNCLENBQUM7QUFDcEQsT0FBTyxLQUFLLFNBQVMsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEtBQUssU0FBUyxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLEtBQUssTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QyxPQUFPLEtBQUssUUFBUSxNQUFNLG9CQUFvQixDQUFDO0FBQy9DLE9BQU8sS0FBSyxVQUFVLE1BQU0sc0JBQXNCLENBQUM7QUFDbkQsT0FBTyxLQUFLLFVBQVUsTUFBTSxxQkFBcUIsQ0FBQztBQUdsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRS9ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBSTlFLE9BQU8sRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHM0QsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gR0VORVJBVEVEIGJ5IHByb2plbiB3YXRjaCAtIERPIE5PVCBFRElULlxuLy8gUmVnZW5lcmF0ZWQgZnJvbSB0aGUgZXhwb3J0aW5nIG1vZHVsZXMgaW4gLi9zcmMuXG4vLyBIYW5kIGVkaXRzIGFyZSBvdmVyd3JpdHRlbiBvbiB0aGUgbmV4dCB3YXRjaDsgdGhpcyBmaWxlIGlzIHJlYWQtb25seS5cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfSURFTlRJRklFUiA9IFwiQGRieC10b29scy90dW5uZWxcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX1ZFUlNJT04gPSBcIjAuNi4yMTZcIjtcbmV4cG9ydCAqIGFzIGFsbG93bGlzdCBmcm9tIFwiLi9zcmMvYWxsb3dsaXN0LnRzXCI7XG5leHBvcnQgKiBhcyBjb2RlRW1haWwgZnJvbSBcIi4vc3JjL2NvZGUtZW1haWwudHNcIjtcbmV4cG9ydCAqIGFzIGZycCBmcm9tIFwiLi9zcmMvZnJwLnRzXCI7XG5leHBvcnQgKiBhcyBnYXRlIGZyb20gXCIuL3NyYy9nYXRlLnRzXCI7XG5leHBvcnQgKiBhcyBoZWFkZXJzIGZyb20gXCIuL3NyYy9oZWFkZXJzLnRzXCI7XG5leHBvcnQgKiBhcyBpbnRlcmNlcHRvciBmcm9tIFwiLi9zcmMvaW50ZXJjZXB0b3IudHNcIjtcbmV4cG9ydCAqIGFzIGxvZ2luUGFnZSBmcm9tIFwiLi9zcmMvbG9naW4tcGFnZS50c1wiO1xuZXhwb3J0ICogYXMgcGF0aFByb3h5IGZyb20gXCIuL3NyYy9wYXRoLXByb3h5LnRzXCI7XG5leHBvcnQgKiBhcyBwbHVnaW4gZnJvbSBcIi4vc3JjL3BsdWdpbi50c1wiO1xuZXhwb3J0ICogYXMgcG9ydHIgZnJvbSBcIi4vc3JjL3BvcnRyLnRzXCI7XG5leHBvcnQgKiBhcyBzZW5kQ29kZSBmcm9tIFwiLi9zcmMvc2VuZC1jb2RlLnRzXCI7XG5leHBvcnQgKiBhcyBzaWduaW5nS2V5IGZyb20gXCIuL3NyYy9zaWduaW5nLWtleS50c1wiO1xuZXhwb3J0ICogYXMgc3VwZXJ2aXNvciBmcm9tIFwiLi9zcmMvc3VwZXJ2aXNvci50c1wiO1xuZXhwb3J0IHR5cGUgeyBDb2RlQ29weSB9IGZyb20gXCIuL3NyYy9jb2RlLWVtYWlsLnRzXCI7XG5leHBvcnQgdHlwZSB7IEZycEluc3RhbGxPcHRpb25zLCBGcnBDb25maWcgfSBmcm9tIFwiLi9zcmMvZnJwLnRzXCI7XG5leHBvcnQgeyBBVVRIX1BSRUZJWCwgVU5BVVRIT1JJWkVEX0JPRFkgfSBmcm9tIFwiLi9zcmMvZ2F0ZS50c1wiO1xuZXhwb3J0IHR5cGUgeyBHYXRlT3B0aW9ucywgR2F0ZUFjdGlvbiB9IGZyb20gXCIuL3NyYy9nYXRlLnRzXCI7XG5leHBvcnQgeyBQUk9URUNURURfSEVBREVSUywgREVGQVVMVF9GT1JXQVJEX0hFQURFUlMgfSBmcm9tIFwiLi9zcmMvaGVhZGVycy50c1wiO1xuZXhwb3J0IHR5cGUgeyBIZWFkZXJQb2xpY3kgfSBmcm9tIFwiLi9zcmMvaGVhZGVycy50c1wiO1xuZXhwb3J0IHR5cGUgeyBUdW5uZWxJbnRlcmNlcHRvck9wdGlvbnMsIFR1bm5lbFRyYW5zcG9ydCB9IGZyb20gXCIuL3NyYy9pbnRlcmNlcHRvci50c1wiO1xuZXhwb3J0IHR5cGUgeyBMb2dpblBhZ2VPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2xvZ2luLXBhZ2UudHNcIjtcbmV4cG9ydCB7IEF1dGhHYXRlUGx1Z2luLCBhdXRoR2F0ZSB9IGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCB0eXBlIHsgQXV0aEdhdGVDb25maWcsIFNlbmRDb2RlT3B0aW9ucywgUmVzb2x2ZWRBdXRoR2F0ZUNvbmZpZywgQXV0aEdhdGVBcGkgfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgdHlwZSB7IFBvcnRySW5zdGFsbE9wdGlvbnMsIFBvcnRyQ29uZmlnIH0gZnJvbSBcIi4vc3JjL3BvcnRyLnRzXCI7XG5leHBvcnQgeyBLRVlfVFRMX1NFQ09ORFMgfSBmcm9tIFwiLi9zcmMvc2lnbmluZy1rZXkudHNcIjtcbmV4cG9ydCB0eXBlIHsgU2lnbmluZ0tleSB9IGZyb20gXCIuL3NyYy9zaWduaW5nLWtleS50c1wiO1xuZXhwb3J0IHR5cGUgeyBQcm9jZXNzU3VwZXJ2aXNvciwgUHJvY2Vzc1N1cGVydmlzb3JPcHRpb25zIH0gZnJvbSBcIi4vc3JjL3N1cGVydmlzb3IudHNcIjtcbiJdfQ==
|
package/lib/src/portr.d.ts
CHANGED
|
@@ -45,4 +45,11 @@ export declare function installPortr(options?: PortrInstallOptions): Promise<Nod
|
|
|
45
45
|
export declare function writePortrConfig(config: PortrConfig, childEnv: NodeJS.ProcessEnv): Promise<void>;
|
|
46
46
|
/** Launch `portr start` as a child process (caller supervises + kills it). */
|
|
47
47
|
export declare function startPortr(config: PortrConfig, childEnv: NodeJS.ProcessEnv): Promise<ReturnType<typeof spawn>>;
|
|
48
|
+
/**
|
|
49
|
+
* Probe the public portr URL. A registered tunnel is healthy even when the app
|
|
50
|
+
* returns an auth challenge (401/302) - those prove the edge still has the
|
|
51
|
+
* subdomain. Only an explicit `unregistered-subdomain` (or any other
|
|
52
|
+
* `x-portr-error`) means the client must be restarted.
|
|
53
|
+
*/
|
|
54
|
+
export declare function probePortrPublicUrl(publicUrl: string): Promise<boolean>;
|
|
48
55
|
export declare function supervisePortr(config: PortrConfig, childEnv: NodeJS.ProcessEnv): ProcessSupervisor;
|
package/lib/src/portr.js
CHANGED
|
@@ -126,11 +126,32 @@ export async function startPortr(config, childEnv) {
|
|
|
126
126
|
child.stderr?.pipe(normalizedOutput(process.stderr));
|
|
127
127
|
return child;
|
|
128
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Probe the public portr URL. A registered tunnel is healthy even when the app
|
|
131
|
+
* returns an auth challenge (401/302) - those prove the edge still has the
|
|
132
|
+
* subdomain. Only an explicit `unregistered-subdomain` (or any other
|
|
133
|
+
* `x-portr-error`) means the client must be restarted.
|
|
134
|
+
*/
|
|
135
|
+
export async function probePortrPublicUrl(publicUrl) {
|
|
136
|
+
const response = await fetch(publicUrl, {
|
|
137
|
+
method: "HEAD",
|
|
138
|
+
redirect: "manual",
|
|
139
|
+
signal: AbortSignal.timeout(5_000),
|
|
140
|
+
});
|
|
141
|
+
if (response.headers.get("x-portr-error") === "true")
|
|
142
|
+
return false;
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
129
145
|
export function supervisePortr(config, childEnv) {
|
|
146
|
+
const publicUrl = `https://${config.subdomain}.${config.server}`;
|
|
130
147
|
return superviseProcessForever({
|
|
131
148
|
name: "portr",
|
|
132
149
|
logger,
|
|
133
150
|
start: () => startPortr(config, childEnv),
|
|
151
|
+
// Kill + restart when the edge drops the registration while the local
|
|
152
|
+
// process is still alive. Without this, lensiq.apps.dbx.tools (and any
|
|
153
|
+
// other in-process tunnel) stays unregistered until a full app bounce.
|
|
154
|
+
isHealthy: () => probePortrPublicUrl(publicUrl),
|
|
134
155
|
});
|
|
135
156
|
}
|
|
136
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydHIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcG9ydHIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7R0FVRztBQUNILE9BQU8sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUM1QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXRDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDOUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUFFLHVCQUF1QixFQUEwQixNQUFNLGlCQUFpQixDQUFDO0FBRWxGLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDMUMsTUFBTSxhQUFhLEdBQUcsY0FBYyxDQUFDO0FBQ3JDLE1BQU0saUJBQWlCLEdBQUcseURBQXlELGFBQWEsRUFBRSxDQUFDO0FBQ25HLE1BQU0saUJBQWlCLEdBQUcsU0FBUyxDQUFDO0FBQ3BDLE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUUxQyxNQUFNLEtBQUssR0FBRyxvQ0FBb0MsQ0FBQztBQUVuRCwrRUFBK0U7QUFDL0UsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQWE7SUFD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QUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMvRixLQUFLLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNyRCxLQUFLLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNyRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxNQUFNLFVBQVUsY0FBYyxDQUM1QixNQUFtQixFQUNuQixRQUEyQjtJQUUzQixPQUFPLHVCQUF1QixDQUFDO1FBQzdCLElBQUksRUFBRSxPQUFPO1FBQ2IsTUFBTTtRQUNOLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQztLQUMxQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBwb3J0ciBpbnN0YWxsLCBjb25maWcsIGFuZCBsYXVuY2ggc3VwcG9ydCBmb3IgdGhlIHR1bm5lbCBydW50aW1lLlxuICpcbiAqIFRoZSBiaW5hcnkgYW5kIGNvbmZpZyB1c2UgcG9ydHIncyBjb252ZW50aW9uYWwgYCRIT01FLy5wb3J0cmAgdHJlZS4gVGhlXG4gKiBpbnN0YWxsIGlzIGlkZW1wb3RlbnQgKHRoZSBpbnN0YWxsZXIgc2tpcHMgYW4gZXhpc3RpbmcgZXhlY3V0YWJsZSkuIFRoZVxuICogY29uZmlnIGlzIHJlbmRlcmVkIGZyb20gYFRVTk5FTF9QVUJMSUNfRE9NQUlOYFxuICogKGA8c3ViZG9tYWluPi48c2VydmVyPmApICsgYFBPUlRSX1RPS0VOYCBhbmQgcG9pbnRzIHBvcnRyIGF0IHRoZSBQVUJMSUMgcG9ydFxuICogKHRoZSBwcm94eSBsaXN0ZW5zIHRoZXJlKS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cbmltcG9ydCB7IGV4ZWNGaWxlLCBzcGF3biB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IHdyaXRlRmlsZSB9IGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGRlbGltaXRlciwgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IFRyYW5zZm9ybSB9IGZyb20gXCJub2RlOnN0cmVhbVwiO1xuaW1wb3J0IHsgU3RyaW5nRGVjb2RlciB9IGZyb20gXCJub2RlOnN0cmluZ19kZWNvZGVyXCI7XG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tIFwibm9kZTp1dGlsXCI7XG5cbmltcG9ydCB7IGJpbiwgY29uZmlnIH0gZnJvbSBcIkBkYngtdG9vbHMvY29yZVwiO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IFRVTk5FTF9DT05GSUcgfSBmcm9tIFwiLi9fY29uZmlnLnRzXCI7XG5pbXBvcnQgeyBzdXBlcnZpc2VQcm9jZXNzRm9yZXZlciwgdHlwZSBQcm9jZXNzU3VwZXJ2aXNvciB9IGZyb20gXCIuL3N1cGVydmlzb3IudHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDpwb3J0clwiKTtcbmNvbnN0IFBPUlRSX1ZFUlNJT04gPSBcIjEuMC4xNS1zc2UuMlwiO1xuY29uc3QgUE9SVFJfUkVMRUFTRV9VUkwgPSBgaHR0cHM6Ly9naXRodWIuY29tL3JlZ2dpZS1kYi9wb3J0ci9yZWxlYXNlcy9kb3dubG9hZC92JHtQT1JUUl9WRVJTSU9OfWA7XG5jb25zdCBQT1JUUl9NSU5fVkVSU0lPTiA9IFwidjEuMC4xNVwiO1xuY29uc3QgZXhlY0ZpbGVBc3luYyA9IHByb21pc2lmeShleGVjRmlsZSk7XG5cbmNvbnN0IEVNT0pJID0gL1xccHtFeHRlbmRlZF9QaWN0b2dyYXBoaWN9XFx1RkUwRj8vZ3U7XG5cbi8qKiBSZW1vdmUgcGljdG9ncmFwaHMgZnJvbSB0aGlyZC1wYXJ0eSBwcm9jZXNzIG91dHB1dCBiZWZvcmUgZm9yd2FyZGluZyBpdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVQb3J0ck91dHB1dCh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoRU1PSkksIFwiXCIpLnJlcGxhY2UoL15bIFxcdF0rL2dtLCBcIlwiKTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplZE91dHB1dChkZXN0aW5hdGlvbjogTm9kZUpTLldyaXRlU3RyZWFtKTogVHJhbnNmb3JtIHtcbiAgY29uc3QgZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKFwidXRmOFwiKTtcbiAgcmV0dXJuIG5ldyBUcmFuc2Zvcm0oe1xuICAgIHRyYW5zZm9ybShjaHVuaywgX2VuY29kaW5nLCBjYWxsYmFjaykge1xuICAgICAgZGVzdGluYXRpb24ud3JpdGUobm9ybWFsaXplUG9ydHJPdXRwdXQoZGVjb2Rlci53cml0ZShjaHVuaykpKTtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSxcbiAgICBmbHVzaChjYWxsYmFjaykge1xuICAgICAgZGVzdGluYXRpb24ud3JpdGUobm9ybWFsaXplUG9ydHJPdXRwdXQoZGVjb2Rlci5lbmQoKSkpO1xuICAgICAgY2FsbGJhY2soKTtcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqIE9wdGlvbnMgZm9yIGluc3RhbGxpbmcgdGhlIHBvcnRyIGV4ZWN1dGFibGUuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvcnRySW5zdGFsbE9wdGlvbnMge1xuICAvKiogSG9tZSBkaXJlY3RvcnkgY29udGFpbmluZyBgLnBvcnRyYDsgZGVmYXVsdHMgdG8gdGhlIE9TIGhvbWUgZGlyZWN0b3J5LiAqL1xuICBob21lRGlyPzogc3RyaW5nO1xufVxuXG4vKiogUmVzb2x2ZWQgcG9ydHIgd2lyaW5nLCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vIHR1bm5lbCBpcyBjb25maWd1cmVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQb3J0ckNvbmZpZyB7XG4gIHN1YmRvbWFpbjogc3RyaW5nO1xuICBzZXJ2ZXI6IHN0cmluZztcbiAgdG9rZW46IHN0cmluZztcbiAgcG9ydDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFJlc29sdmUgcG9ydHIgY29uZmlnIGZyb20gYFRVTk5FTF9QVUJMSUNfRE9NQUlOYCArIGBQT1JUUl9UT0tFTmAsIG9yIGFuXG4gKiBleHBsaWNpdCBgc3ViZG9tYWluYC4gVGhlIGRvbWFpbiBpcyBgPHN1YmRvbWFpbj4uPHNlcnZlcj5gIChlLmcuXG4gKiBgZGVtby5hcHBzLmRieC50b29sc2ApLiBSZXR1cm5zIGB1bmRlZmluZWRgIChubyB0dW5uZWwpIHdoZW4gdGhlIHRva2VuIG9yIGFcbiAqIHVzYWJsZSBkb21haW4gaXMgYWJzZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVBvcnRyQ29uZmlnKG9wdHM6IHtcbiAgcHVibGljRG9tYWluPzogc3RyaW5nO1xuICBzdWJkb21haW4/OiBzdHJpbmc7XG4gIHRva2VuPzogc3RyaW5nO1xuICBwb3J0OiBudW1iZXI7XG59KTogUG9ydHJDb25maWcgfCB1bmRlZmluZWQge1xuICAvLyBQT1JUUl8qIGlzIHVwc3RyZWFtIHBvcnRyJ3Mgb3duIG5hbWVzcGFjZSwgc28gaXQga2VlcHMgaXRzIG5hbWUuXG4gIGNvbnN0IHRva2VuID0gY29uZmlnLnN0cmluZyhvcHRzLnRva2VuLCBcIlBPUlRSX1RPS0VOXCIpO1xuICBjb25zdCBkb21haW4gPSBjb25maWcuc3RyaW5nKG9wdHMucHVibGljRG9tYWluLCBcIlBVQkxJQ19ET01BSU5cIiwgVFVOTkVMX0NPTkZJRyk7XG4gIGlmICghdG9rZW4pIHJldHVybiB1bmRlZmluZWQ7XG4gIGxldCBzdWJkb21haW4gPSBvcHRzLnN1YmRvbWFpbjtcbiAgbGV0IHNlcnZlcjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBpZiAoZG9tYWluKSB7XG4gICAgc3ViZG9tYWluID8/PSBkb21haW4uc3BsaXQoXCIuXCIpWzBdO1xuICAgIHNlcnZlciA9IGRvbWFpbi5zbGljZShkb21haW4uaW5kZXhPZihcIi5cIikgKyAxKTtcbiAgfVxuICBzZXJ2ZXIgPz89IGNvbmZpZy50ZXh0KFwiUE9SVFJfU0VSVkVSXCIpO1xuICBpZiAoIXN1YmRvbWFpbiB8fCAhc2VydmVyIHx8IHNlcnZlciA9PT0gZG9tYWluKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4geyBzdWJkb21haW4sIHNlcnZlciwgdG9rZW4sIHBvcnQ6IG9wdHMucG9ydCB9O1xufVxuXG4vKiogR2l0SHViIHJlbGVhc2UgYXNzZXQgbmFtZSBmb3IgdGhlIGN1cnJlbnQgb3Igc3VwcGxpZWQgT1MvYXJjaGl0ZWN0dXJlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvcnRyQXNzZXROYW1lKFxuICB2ZXJzaW9uOiBzdHJpbmcsXG4gIHBsYXRmb3JtOiBOb2RlSlMuUGxhdGZvcm0gPSBwcm9jZXNzLnBsYXRmb3JtLFxuICBhcmNoOiBzdHJpbmcgPSBwcm9jZXNzLmFyY2gsXG4pOiBzdHJpbmcge1xuICBjb25zdCBvc05hbWUgPSBwbGF0Zm9ybSA9PT0gXCJkYXJ3aW5cIiA/IFwiRGFyd2luXCIgOiBwbGF0Zm9ybSA9PT0gXCJsaW51eFwiID8gXCJMaW51eFwiIDogdW5kZWZpbmVkO1xuICBjb25zdCBhcmNoTmFtZSA9IGFyY2ggPT09IFwiYXJtNjRcIiA/IFwiYXJtNjRcIiA6IGFyY2ggPT09IFwieDY0XCIgPyBcIng4Nl82NFwiIDogdW5kZWZpbmVkO1xuICBpZiAoIW9zTmFtZSB8fCAhYXJjaE5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBvcnRyIGhhcyBubyBzdXBwb3J0ZWQgcmVsZWFzZSBhc3NldCBmb3IgJHtwbGF0Zm9ybX0vJHthcmNofWApO1xuICB9XG4gIHJldHVybiBgcG9ydHJfJHt2ZXJzaW9ufV8ke29zTmFtZX1fJHthcmNoTmFtZX0uemlwYDtcbn1cblxuZnVuY3Rpb24gcG9ydHJEb3dubG9hZFVybCgpOiBzdHJpbmcge1xuICBjb25zdCBhc3NldE5hbWUgPSBwb3J0ckFzc2V0TmFtZShQT1JUUl9WRVJTSU9OKTtcbiAgbG9nZ2VyLmluZm8oXCJpbnN0YWxsaW5nIHBvcnRyXCIsIHsgdmVyc2lvbjogUE9SVFJfVkVSU0lPTiwgYXNzZXQ6IGFzc2V0TmFtZSB9KTtcbiAgcmV0dXJuIGAke1BPUlRSX1JFTEVBU0VfVVJMfS8ke2Fzc2V0TmFtZX1gO1xufVxuXG4vKiogSW5zdGFsbCBwb3J0ciB3aGVuIGFic2VudCBhbmQgcmV0dXJuIHRoZSBlbnZpcm9ubWVudCB1c2VkIGJ5IGl0cyBwcm9jZXNzLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluc3RhbGxQb3J0cihvcHRpb25zOiBQb3J0ckluc3RhbGxPcHRpb25zID0ge30pOiBQcm9taXNlPE5vZGVKUy5Qcm9jZXNzRW52PiB7XG4gIGNvbnN0IGhvbWVEaXIgPSBvcHRpb25zLmhvbWVEaXIgPz8gb3MuaG9tZWRpcigpO1xuICBjb25zdCBjb250ZXh0ID0gYXdhaXQgYmluLmVuc3VyZShcInBvcnRyXCIsIHBvcnRyRG93bmxvYWRVcmwsIHtcbiAgICBhdXRvVW5wYWNrYWdlOiB0cnVlLFxuICAgIGhvbWVEaXIsXG4gICAgbWluVmVyc2lvbjogUE9SVFJfTUlOX1ZFUlNJT04sXG4gICAgc2VsZWN0b3I6ICh7IHNvdXJjZSB9KSA9PiBqb2luKHNvdXJjZSwgXCJwb3J0clwiKSxcbiAgICB2ZXJzaW9uUGFyc2VyOiAob3V0cHV0KSA9PiB7XG4gICAgICBjb25zdCB2ZXJzaW9uID0gYmluLnBhcnNlVmVyc2lvbihvdXRwdXQpO1xuICAgICAgcmV0dXJuIHZlcnNpb24gPT09IFBPUlRSX1ZFUlNJT04gPyB2ZXJzaW9uIDogdW5kZWZpbmVkO1xuICAgIH0sXG4gIH0pO1xuICByZXR1cm4ge1xuICAgIC4uLnByb2Nlc3MuZW52LFxuICAgIEhPTUU6IGhvbWVEaXIsXG4gICAgUE9SVFJfQVVUT19BRERfUEFUSDogXCJub1wiLFxuICAgIFBBVEg6IFtjb250ZXh0LmJpbkRpciwgcHJvY2Vzcy5lbnYuUEFUSCA/PyBcIlwiXS5qb2luKGRlbGltaXRlciksXG4gIH07XG59XG5cbi8qKiBSZW5kZXIgYH4vLnBvcnRyL2NvbmZpZy55YW1sYCBmb3IgdGhlIHJlc29sdmVkIHR1bm5lbC4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZVBvcnRyQ29uZmlnKFxuICBjb25maWc6IFBvcnRyQ29uZmlnLFxuICBjaGlsZEVudjogTm9kZUpTLlByb2Nlc3NFbnYsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcGF0aCA9IGpvaW4oY2hpbGRFbnYuSE9NRSA/PyBvcy5ob21lZGlyKCksIFwiLnBvcnRyXCIsIFwiY29uZmlnLnlhbWxcIik7XG4gIGF3YWl0IHdyaXRlRmlsZShcbiAgICBwYXRoLFxuICAgIFtcbiAgICAgIGBzZXJ2ZXJfdXJsOiAke2NvbmZpZy5zZXJ2ZXJ9YCxcbiAgICAgIGBzc2hfdXJsOiAke2NvbmZpZy5zZXJ2ZXJ9OjQ0NDRgLFxuICAgICAgYHNlY3JldF9rZXk6ICR7Y29uZmlnLnRva2VufWAsXG4gICAgICBcImRpc2FibGVfZGFzaGJvYXJkOiB0cnVlXCIsXG4gICAgICBcImRpc2FibGVfdHVpOiB0cnVlXCIsXG4gICAgICBcInR1bm5lbHM6XCIsXG4gICAgICBgICAtIG5hbWU6ICR7Y29uZmlnLnN1YmRvbWFpbn1gLFxuICAgICAgYCAgICBzdWJkb21haW46ICR7Y29uZmlnLnN1YmRvbWFpbn1gLFxuICAgICAgYCAgICBwb3J0OiAke2NvbmZpZy5wb3J0fWAsXG4gICAgICBcIlwiLFxuICAgIF0uam9pbihcIlxcblwiKSxcbiAgKTtcbn1cblxuLyoqIExhdW5jaCBgcG9ydHIgc3RhcnRgIGFzIGEgY2hpbGQgcHJvY2VzcyAoY2FsbGVyIHN1cGVydmlzZXMgKyBraWxscyBpdCkuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRQb3J0cihcbiAgY29uZmlnOiBQb3J0ckNvbmZpZyxcbiAgY2hpbGRFbnY6IE5vZGVKUy5Qcm9jZXNzRW52LFxuKTogUHJvbWlzZTxSZXR1cm5UeXBlPHR5cGVvZiBzcGF3bj4+IHtcbiAgLy8gUmVjbGFpbSB0aGUgc3ViZG9tYWluIGZyb20gYW55IHBvcnRyIGxlZnQgYnkgYSBwcmV2aW91cyBib290IGluIHRoaXMgY29udGFpbmVyLlxuICBhd2FpdCBleGVjRmlsZUFzeW5jKFwicGtpbGxcIiwgW1wiLXhcIiwgXCJwb3J0clwiXSkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcblxuICBsb2dnZXIuaW5mbyhgcG9ydHIgdHVubmVsaW5nIGh0dHBzOi8vJHtjb25maWcuc3ViZG9tYWlufS4ke2NvbmZpZy5zZXJ2ZXJ9IC0+IDoke2NvbmZpZy5wb3J0fWApO1xuICBjb25zdCBjaGlsZCA9IHNwYXduKFwicG9ydHJcIiwgW1wic3RhcnRcIl0sIHsgZW52OiBjaGlsZEVudiwgc3RkaW86IFtcImluaGVyaXRcIiwgXCJwaXBlXCIsIFwicGlwZVwiXSB9KTtcbiAgY2hpbGQuc3Rkb3V0Py5waXBlKG5vcm1hbGl6ZWRPdXRwdXQocHJvY2Vzcy5zdGRvdXQpKTtcbiAgY2hpbGQuc3RkZXJyPy5waXBlKG5vcm1hbGl6ZWRPdXRwdXQocHJvY2Vzcy5zdGRlcnIpKTtcbiAgcmV0dXJuIGNoaWxkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3VwZXJ2aXNlUG9ydHIoXG4gIGNvbmZpZzogUG9ydHJDb25maWcsXG4gIGNoaWxkRW52OiBOb2RlSlMuUHJvY2Vzc0Vudixcbik6IFByb2Nlc3NTdXBlcnZpc29yIHtcbiAgcmV0dXJuIHN1cGVydmlzZVByb2Nlc3NGb3JldmVyKHtcbiAgICBuYW1lOiBcInBvcnRyXCIsXG4gICAgbG9nZ2VyLFxuICAgIHN0YXJ0OiAoKSA9PiBzdGFydFBvcnRyKGNvbmZpZywgY2hpbGRFbnYpLFxuICB9KTtcbn1cbiJdfQ==
|
|
157
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9ydHIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcG9ydHIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7R0FVRztBQUNILE9BQU8sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUM1QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXRDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDOUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUFFLHVCQUF1QixFQUEwQixNQUFNLGlCQUFpQixDQUFDO0FBRWxGLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDMUMsTUFBTSxhQUFhLEdBQUcsY0FBYyxDQUFDO0FBQ3JDLE1BQU0saUJBQWlCLEdBQUcseURBQXlELGFBQWEsRUFBRSxDQUFDO0FBQ25HLE1BQU0saUJBQWlCLEdBQUcsU0FBUyxDQUFDO0FBQ3BDLE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUUxQyxNQUFNLEtBQUssR0FBRyxvQ0FBb0MsQ0FBQztBQUVuRCwrRUFBK0U7QUFDL0UsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQWE7SUFD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LyoqXG4gKiBwb3J0ciBpbnN0YWxsLCBjb25maWcsIGFuZCBsYXVuY2ggc3VwcG9ydCBmb3IgdGhlIHR1bm5lbCBydW50aW1lLlxuICpcbiAqIFRoZSBiaW5hcnkgYW5kIGNvbmZpZyB1c2UgcG9ydHIncyBjb252ZW50aW9uYWwgYCRIT01FLy5wb3J0cmAgdHJlZS4gVGhlXG4gKiBpbnN0YWxsIGlzIGlkZW1wb3RlbnQgKHRoZSBpbnN0YWxsZXIgc2tpcHMgYW4gZXhpc3RpbmcgZXhlY3V0YWJsZSkuIFRoZVxuICogY29uZmlnIGlzIHJlbmRlcmVkIGZyb20gYFRVTk5FTF9QVUJMSUNfRE9NQUlOYFxuICogKGA8c3ViZG9tYWluPi48c2VydmVyPmApICsgYFBPUlRSX1RPS0VOYCBhbmQgcG9pbnRzIHBvcnRyIGF0IHRoZSBQVUJMSUMgcG9ydFxuICogKHRoZSBwcm94eSBsaXN0ZW5zIHRoZXJlKS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cbmltcG9ydCB7IGV4ZWNGaWxlLCBzcGF3biB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IHdyaXRlRmlsZSB9IGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGRlbGltaXRlciwgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IFRyYW5zZm9ybSB9IGZyb20gXCJub2RlOnN0cmVhbVwiO1xuaW1wb3J0IHsgU3RyaW5nRGVjb2RlciB9IGZyb20gXCJub2RlOnN0cmluZ19kZWNvZGVyXCI7XG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tIFwibm9kZTp1dGlsXCI7XG5cbmltcG9ydCB7IGJpbiwgY29uZmlnIH0gZnJvbSBcIkBkYngtdG9vbHMvY29yZVwiO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IFRVTk5FTF9DT05GSUcgfSBmcm9tIFwiLi9fY29uZmlnLnRzXCI7XG5pbXBvcnQgeyBzdXBlcnZpc2VQcm9jZXNzRm9yZXZlciwgdHlwZSBQcm9jZXNzU3VwZXJ2aXNvciB9IGZyb20gXCIuL3N1cGVydmlzb3IudHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDpwb3J0clwiKTtcbmNvbnN0IFBPUlRSX1ZFUlNJT04gPSBcIjEuMC4xNS1zc2UuMlwiO1xuY29uc3QgUE9SVFJfUkVMRUFTRV9VUkwgPSBgaHR0cHM6Ly9naXRodWIuY29tL3JlZ2dpZS1kYi9wb3J0ci9yZWxlYXNlcy9kb3dubG9hZC92JHtQT1JUUl9WRVJTSU9OfWA7XG5jb25zdCBQT1JUUl9NSU5fVkVSU0lPTiA9IFwidjEuMC4xNVwiO1xuY29uc3QgZXhlY0ZpbGVBc3luYyA9IHByb21pc2lmeShleGVjRmlsZSk7XG5cbmNvbnN0IEVNT0pJID0gL1xccHtFeHRlbmRlZF9QaWN0b2dyYXBoaWN9XFx1RkUwRj8vZ3U7XG5cbi8qKiBSZW1vdmUgcGljdG9ncmFwaHMgZnJvbSB0aGlyZC1wYXJ0eSBwcm9jZXNzIG91dHB1dCBiZWZvcmUgZm9yd2FyZGluZyBpdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVQb3J0ck91dHB1dCh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoRU1PSkksIFwiXCIpLnJlcGxhY2UoL15bIFxcdF0rL2dtLCBcIlwiKTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplZE91dHB1dChkZXN0aW5hdGlvbjogTm9kZUpTLldyaXRlU3RyZWFtKTogVHJhbnNmb3JtIHtcbiAgY29uc3QgZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKFwidXRmOFwiKTtcbiAgcmV0dXJuIG5ldyBUcmFuc2Zvcm0oe1xuICAgIHRyYW5zZm9ybShjaHVuaywgX2VuY29kaW5nLCBjYWxsYmFjaykge1xuICAgICAgZGVzdGluYXRpb24ud3JpdGUobm9ybWFsaXplUG9ydHJPdXRwdXQoZGVjb2Rlci53cml0ZShjaHVuaykpKTtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSxcbiAgICBmbHVzaChjYWxsYmFjaykge1xuICAgICAgZGVzdGluYXRpb24ud3JpdGUobm9ybWFsaXplUG9ydHJPdXRwdXQoZGVjb2Rlci5lbmQoKSkpO1xuICAgICAgY2FsbGJhY2soKTtcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqIE9wdGlvbnMgZm9yIGluc3RhbGxpbmcgdGhlIHBvcnRyIGV4ZWN1dGFibGUuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvcnRySW5zdGFsbE9wdGlvbnMge1xuICAvKiogSG9tZSBkaXJlY3RvcnkgY29udGFpbmluZyBgLnBvcnRyYDsgZGVmYXVsdHMgdG8gdGhlIE9TIGhvbWUgZGlyZWN0b3J5LiAqL1xuICBob21lRGlyPzogc3RyaW5nO1xufVxuXG4vKiogUmVzb2x2ZWQgcG9ydHIgd2lyaW5nLCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vIHR1bm5lbCBpcyBjb25maWd1cmVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQb3J0ckNvbmZpZyB7XG4gIHN1YmRvbWFpbjogc3RyaW5nO1xuICBzZXJ2ZXI6IHN0cmluZztcbiAgdG9rZW46IHN0cmluZztcbiAgcG9ydDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFJlc29sdmUgcG9ydHIgY29uZmlnIGZyb20gYFRVTk5FTF9QVUJMSUNfRE9NQUlOYCArIGBQT1JUUl9UT0tFTmAsIG9yIGFuXG4gKiBleHBsaWNpdCBgc3ViZG9tYWluYC4gVGhlIGRvbWFpbiBpcyBgPHN1YmRvbWFpbj4uPHNlcnZlcj5gIChlLmcuXG4gKiBgZGVtby5hcHBzLmRieC50b29sc2ApLiBSZXR1cm5zIGB1bmRlZmluZWRgIChubyB0dW5uZWwpIHdoZW4gdGhlIHRva2VuIG9yIGFcbiAqIHVzYWJsZSBkb21haW4gaXMgYWJzZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVBvcnRyQ29uZmlnKG9wdHM6IHtcbiAgcHVibGljRG9tYWluPzogc3RyaW5nO1xuICBzdWJkb21haW4/OiBzdHJpbmc7XG4gIHRva2VuPzogc3RyaW5nO1xuICBwb3J0OiBudW1iZXI7XG59KTogUG9ydHJDb25maWcgfCB1bmRlZmluZWQge1xuICAvLyBQT1JUUl8qIGlzIHVwc3RyZWFtIHBvcnRyJ3Mgb3duIG5hbWVzcGFjZSwgc28gaXQga2VlcHMgaXRzIG5hbWUuXG4gIGNvbnN0IHRva2VuID0gY29uZmlnLnN0cmluZyhvcHRzLnRva2VuLCBcIlBPUlRSX1RPS0VOXCIpO1xuICBjb25zdCBkb21haW4gPSBjb25maWcuc3RyaW5nKG9wdHMucHVibGljRG9tYWluLCBcIlBVQkxJQ19ET01BSU5cIiwgVFVOTkVMX0NPTkZJRyk7XG4gIGlmICghdG9rZW4pIHJldHVybiB1bmRlZmluZWQ7XG4gIGxldCBzdWJkb21haW4gPSBvcHRzLnN1YmRvbWFpbjtcbiAgbGV0IHNlcnZlcjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBpZiAoZG9tYWluKSB7XG4gICAgc3ViZG9tYWluID8/PSBkb21haW4uc3BsaXQoXCIuXCIpWzBdO1xuICAgIHNlcnZlciA9IGRvbWFpbi5zbGljZShkb21haW4uaW5kZXhPZihcIi5cIikgKyAxKTtcbiAgfVxuICBzZXJ2ZXIgPz89IGNvbmZpZy50ZXh0KFwiUE9SVFJfU0VSVkVSXCIpO1xuICBpZiAoIXN1YmRvbWFpbiB8fCAhc2VydmVyIHx8IHNlcnZlciA9PT0gZG9tYWluKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4geyBzdWJkb21haW4sIHNlcnZlciwgdG9rZW4sIHBvcnQ6IG9wdHMucG9ydCB9O1xufVxuXG4vKiogR2l0SHViIHJlbGVhc2UgYXNzZXQgbmFtZSBmb3IgdGhlIGN1cnJlbnQgb3Igc3VwcGxpZWQgT1MvYXJjaGl0ZWN0dXJlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvcnRyQXNzZXROYW1lKFxuICB2ZXJzaW9uOiBzdHJpbmcsXG4gIHBsYXRmb3JtOiBOb2RlSlMuUGxhdGZvcm0gPSBwcm9jZXNzLnBsYXRmb3JtLFxuICBhcmNoOiBzdHJpbmcgPSBwcm9jZXNzLmFyY2gsXG4pOiBzdHJpbmcge1xuICBjb25zdCBvc05hbWUgPSBwbGF0Zm9ybSA9PT0gXCJkYXJ3aW5cIiA/IFwiRGFyd2luXCIgOiBwbGF0Zm9ybSA9PT0gXCJsaW51eFwiID8gXCJMaW51eFwiIDogdW5kZWZpbmVkO1xuICBjb25zdCBhcmNoTmFtZSA9IGFyY2ggPT09IFwiYXJtNjRcIiA/IFwiYXJtNjRcIiA6IGFyY2ggPT09IFwieDY0XCIgPyBcIng4Nl82NFwiIDogdW5kZWZpbmVkO1xuICBpZiAoIW9zTmFtZSB8fCAhYXJjaE5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBvcnRyIGhhcyBubyBzdXBwb3J0ZWQgcmVsZWFzZSBhc3NldCBmb3IgJHtwbGF0Zm9ybX0vJHthcmNofWApO1xuICB9XG4gIHJldHVybiBgcG9ydHJfJHt2ZXJzaW9ufV8ke29zTmFtZX1fJHthcmNoTmFtZX0uemlwYDtcbn1cblxuZnVuY3Rpb24gcG9ydHJEb3dubG9hZFVybCgpOiBzdHJpbmcge1xuICBjb25zdCBhc3NldE5hbWUgPSBwb3J0ckFzc2V0TmFtZShQT1JUUl9WRVJTSU9OKTtcbiAgbG9nZ2VyLmluZm8oXCJpbnN0YWxsaW5nIHBvcnRyXCIsIHsgdmVyc2lvbjogUE9SVFJfVkVSU0lPTiwgYXNzZXQ6IGFzc2V0TmFtZSB9KTtcbiAgcmV0dXJuIGAke1BPUlRSX1JFTEVBU0VfVVJMfS8ke2Fzc2V0TmFtZX1gO1xufVxuXG4vKiogSW5zdGFsbCBwb3J0ciB3aGVuIGFic2VudCBhbmQgcmV0dXJuIHRoZSBlbnZpcm9ubWVudCB1c2VkIGJ5IGl0cyBwcm9jZXNzLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluc3RhbGxQb3J0cihvcHRpb25zOiBQb3J0ckluc3RhbGxPcHRpb25zID0ge30pOiBQcm9taXNlPE5vZGVKUy5Qcm9jZXNzRW52PiB7XG4gIGNvbnN0IGhvbWVEaXIgPSBvcHRpb25zLmhvbWVEaXIgPz8gb3MuaG9tZWRpcigpO1xuICBjb25zdCBjb250ZXh0ID0gYXdhaXQgYmluLmVuc3VyZShcInBvcnRyXCIsIHBvcnRyRG93bmxvYWRVcmwsIHtcbiAgICBhdXRvVW5wYWNrYWdlOiB0cnVlLFxuICAgIGhvbWVEaXIsXG4gICAgbWluVmVyc2lvbjogUE9SVFJfTUlOX1ZFUlNJT04sXG4gICAgc2VsZWN0b3I6ICh7IHNvdXJjZSB9KSA9PiBqb2luKHNvdXJjZSwgXCJwb3J0clwiKSxcbiAgICB2ZXJzaW9uUGFyc2VyOiAob3V0cHV0KSA9PiB7XG4gICAgICBjb25zdCB2ZXJzaW9uID0gYmluLnBhcnNlVmVyc2lvbihvdXRwdXQpO1xuICAgICAgcmV0dXJuIHZlcnNpb24gPT09IFBPUlRSX1ZFUlNJT04gPyB2ZXJzaW9uIDogdW5kZWZpbmVkO1xuICAgIH0sXG4gIH0pO1xuICByZXR1cm4ge1xuICAgIC4uLnByb2Nlc3MuZW52LFxuICAgIEhPTUU6IGhvbWVEaXIsXG4gICAgUE9SVFJfQVVUT19BRERfUEFUSDogXCJub1wiLFxuICAgIFBBVEg6IFtjb250ZXh0LmJpbkRpciwgcHJvY2Vzcy5lbnYuUEFUSCA/PyBcIlwiXS5qb2luKGRlbGltaXRlciksXG4gIH07XG59XG5cbi8qKiBSZW5kZXIgYH4vLnBvcnRyL2NvbmZpZy55YW1sYCBmb3IgdGhlIHJlc29sdmVkIHR1bm5lbC4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZVBvcnRyQ29uZmlnKFxuICBjb25maWc6IFBvcnRyQ29uZmlnLFxuICBjaGlsZEVudjogTm9kZUpTLlByb2Nlc3NFbnYsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcGF0aCA9IGpvaW4oY2hpbGRFbnYuSE9NRSA/PyBvcy5ob21lZGlyKCksIFwiLnBvcnRyXCIsIFwiY29uZmlnLnlhbWxcIik7XG4gIGF3YWl0IHdyaXRlRmlsZShcbiAgICBwYXRoLFxuICAgIFtcbiAgICAgIGBzZXJ2ZXJfdXJsOiAke2NvbmZpZy5zZXJ2ZXJ9YCxcbiAgICAgIGBzc2hfdXJsOiAke2NvbmZpZy5zZXJ2ZXJ9OjQ0NDRgLFxuICAgICAgYHNlY3JldF9rZXk6ICR7Y29uZmlnLnRva2VufWAsXG4gICAgICBcImRpc2FibGVfZGFzaGJvYXJkOiB0cnVlXCIsXG4gICAgICBcImRpc2FibGVfdHVpOiB0cnVlXCIsXG4gICAgICBcInR1bm5lbHM6XCIsXG4gICAgICBgICAtIG5hbWU6ICR7Y29uZmlnLnN1YmRvbWFpbn1gLFxuICAgICAgYCAgICBzdWJkb21haW46ICR7Y29uZmlnLnN1YmRvbWFpbn1gLFxuICAgICAgYCAgICBwb3J0OiAke2NvbmZpZy5wb3J0fWAsXG4gICAgICBcIlwiLFxuICAgIF0uam9pbihcIlxcblwiKSxcbiAgKTtcbn1cblxuLyoqIExhdW5jaCBgcG9ydHIgc3RhcnRgIGFzIGEgY2hpbGQgcHJvY2VzcyAoY2FsbGVyIHN1cGVydmlzZXMgKyBraWxscyBpdCkuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRQb3J0cihcbiAgY29uZmlnOiBQb3J0ckNvbmZpZyxcbiAgY2hpbGRFbnY6IE5vZGVKUy5Qcm9jZXNzRW52LFxuKTogUHJvbWlzZTxSZXR1cm5UeXBlPHR5cGVvZiBzcGF3bj4+IHtcbiAgLy8gUmVjbGFpbSB0aGUgc3ViZG9tYWluIGZyb20gYW55IHBvcnRyIGxlZnQgYnkgYSBwcmV2aW91cyBib290IGluIHRoaXMgY29udGFpbmVyLlxuICBhd2FpdCBleGVjRmlsZUFzeW5jKFwicGtpbGxcIiwgW1wiLXhcIiwgXCJwb3J0clwiXSkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcblxuICBsb2dnZXIuaW5mbyhgcG9ydHIgdHVubmVsaW5nIGh0dHBzOi8vJHtjb25maWcuc3ViZG9tYWlufS4ke2NvbmZpZy5zZXJ2ZXJ9IC0+IDoke2NvbmZpZy5wb3J0fWApO1xuICBjb25zdCBjaGlsZCA9IHNwYXduKFwicG9ydHJcIiwgW1wic3RhcnRcIl0sIHsgZW52OiBjaGlsZEVudiwgc3RkaW86IFtcImluaGVyaXRcIiwgXCJwaXBlXCIsIFwicGlwZVwiXSB9KTtcbiAgY2hpbGQuc3Rkb3V0Py5waXBlKG5vcm1hbGl6ZWRPdXRwdXQocHJvY2Vzcy5zdGRvdXQpKTtcbiAgY2hpbGQuc3RkZXJyPy5waXBlKG5vcm1hbGl6ZWRPdXRwdXQocHJvY2Vzcy5zdGRlcnIpKTtcbiAgcmV0dXJuIGNoaWxkO1xufVxuXG4vKipcbiAqIFByb2JlIHRoZSBwdWJsaWMgcG9ydHIgVVJMLiBBIHJlZ2lzdGVyZWQgdHVubmVsIGlzIGhlYWx0aHkgZXZlbiB3aGVuIHRoZSBhcHBcbiAqIHJldHVybnMgYW4gYXV0aCBjaGFsbGVuZ2UgKDQwMS8zMDIpIC0gdGhvc2UgcHJvdmUgdGhlIGVkZ2Ugc3RpbGwgaGFzIHRoZVxuICogc3ViZG9tYWluLiBPbmx5IGFuIGV4cGxpY2l0IGB1bnJlZ2lzdGVyZWQtc3ViZG9tYWluYCAob3IgYW55IG90aGVyXG4gKiBgeC1wb3J0ci1lcnJvcmApIG1lYW5zIHRoZSBjbGllbnQgbXVzdCBiZSByZXN0YXJ0ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm9iZVBvcnRyUHVibGljVXJsKHB1YmxpY1VybDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gocHVibGljVXJsLCB7XG4gICAgbWV0aG9kOiBcIkhFQURcIixcbiAgICByZWRpcmVjdDogXCJtYW51YWxcIixcbiAgICBzaWduYWw6IEFib3J0U2lnbmFsLnRpbWVvdXQoNV8wMDApLFxuICB9KTtcbiAgaWYgKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwieC1wb3J0ci1lcnJvclwiKSA9PT0gXCJ0cnVlXCIpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdXBlcnZpc2VQb3J0cihcbiAgY29uZmlnOiBQb3J0ckNvbmZpZyxcbiAgY2hpbGRFbnY6IE5vZGVKUy5Qcm9jZXNzRW52LFxuKTogUHJvY2Vzc1N1cGVydmlzb3Ige1xuICBjb25zdCBwdWJsaWNVcmwgPSBgaHR0cHM6Ly8ke2NvbmZpZy5zdWJkb21haW59LiR7Y29uZmlnLnNlcnZlcn1gO1xuICByZXR1cm4gc3VwZXJ2aXNlUHJvY2Vzc0ZvcmV2ZXIoe1xuICAgIG5hbWU6IFwicG9ydHJcIixcbiAgICBsb2dnZXIsXG4gICAgc3RhcnQ6ICgpID0+IHN0YXJ0UG9ydHIoY29uZmlnLCBjaGlsZEVudiksXG4gICAgLy8gS2lsbCArIHJlc3RhcnQgd2hlbiB0aGUgZWRnZSBkcm9wcyB0aGUgcmVnaXN0cmF0aW9uIHdoaWxlIHRoZSBsb2NhbFxuICAgIC8vIHByb2Nlc3MgaXMgc3RpbGwgYWxpdmUuIFdpdGhvdXQgdGhpcywgbGVuc2lxLmFwcHMuZGJ4LnRvb2xzIChhbmQgYW55XG4gICAgLy8gb3RoZXIgaW4tcHJvY2VzcyB0dW5uZWwpIHN0YXlzIHVucmVnaXN0ZXJlZCB1bnRpbCBhIGZ1bGwgYXBwIGJvdW5jZS5cbiAgICBpc0hlYWx0aHk6ICgpID0+IHByb2JlUG9ydHJQdWJsaWNVcmwocHVibGljVXJsKSxcbiAgfSk7XG59XG4iXX0=
|
package/lib/src/supervisor.d.ts
CHANGED
|
@@ -3,10 +3,22 @@ import { type Logger } from "@dbx-tools/shared-core";
|
|
|
3
3
|
export interface ProcessSupervisor {
|
|
4
4
|
stop(): void;
|
|
5
5
|
}
|
|
6
|
-
export
|
|
6
|
+
export interface ProcessSupervisorOptions {
|
|
7
7
|
name: string;
|
|
8
8
|
logger: Logger;
|
|
9
9
|
start: () => ChildProcess | Promise<ChildProcess>;
|
|
10
10
|
retryDelaysMs?: readonly number[];
|
|
11
11
|
shutdownGraceMs?: number;
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Optional public liveness probe. When it returns `false` while the child is
|
|
14
|
+
* still running, the supervisor kills the child so the forever-loop restarts
|
|
15
|
+
* it. Used by portr to recover from an edge that dropped the subdomain
|
|
16
|
+
* registration while the local process kept running (see
|
|
17
|
+
* `x-portr-error-reason: unregistered-subdomain`).
|
|
18
|
+
*/
|
|
19
|
+
isHealthy?: () => boolean | Promise<boolean>;
|
|
20
|
+
healthCheckGraceMs?: number;
|
|
21
|
+
healthCheckIntervalMs?: number;
|
|
22
|
+
healthCheckFailures?: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function superviseProcessForever(options: ProcessSupervisorOptions): ProcessSupervisor;
|
package/lib/src/supervisor.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { async as asyncTools } from "@dbx-tools/shared-core";
|
|
2
2
|
const STABLE_CONNECTION_MS = 60_000;
|
|
3
3
|
const DEFAULT_SHUTDOWN_GRACE_MS = 10_000;
|
|
4
|
+
/** How long to wait after a child start before the first public liveness probe. */
|
|
5
|
+
const DEFAULT_HEALTH_CHECK_GRACE_MS = 45_000;
|
|
6
|
+
/** Interval between public liveness probes while a child is running. */
|
|
7
|
+
const DEFAULT_HEALTH_CHECK_INTERVAL_MS = 30_000;
|
|
8
|
+
/** Consecutive failed probes required before killing a still-running child. */
|
|
9
|
+
const DEFAULT_HEALTH_CHECK_FAILURES = 2;
|
|
4
10
|
export function superviseProcessForever(options) {
|
|
5
11
|
const controller = new AbortController();
|
|
6
12
|
let child;
|
|
@@ -30,7 +36,7 @@ export function superviseProcessForever(options) {
|
|
|
30
36
|
let outcome;
|
|
31
37
|
try {
|
|
32
38
|
child = await options.start();
|
|
33
|
-
outcome = await processOutcome(child, controller.signal);
|
|
39
|
+
outcome = await processOutcome(child, controller.signal, options);
|
|
34
40
|
}
|
|
35
41
|
catch (error) {
|
|
36
42
|
outcome = { error };
|
|
@@ -57,9 +63,17 @@ export function superviseProcessForever(options) {
|
|
|
57
63
|
stop,
|
|
58
64
|
};
|
|
59
65
|
}
|
|
60
|
-
function processOutcome(child, signal) {
|
|
66
|
+
function processOutcome(child, signal, options) {
|
|
61
67
|
return new Promise((resolve) => {
|
|
68
|
+
let settled = false;
|
|
69
|
+
let healthTimer;
|
|
70
|
+
let consecutiveFailures = 0;
|
|
62
71
|
const finish = (outcome) => {
|
|
72
|
+
if (settled)
|
|
73
|
+
return;
|
|
74
|
+
settled = true;
|
|
75
|
+
if (healthTimer)
|
|
76
|
+
clearTimeout(healthTimer);
|
|
63
77
|
child.off("exit", onExit);
|
|
64
78
|
child.off("error", onError);
|
|
65
79
|
signal.removeEventListener("abort", onAbort);
|
|
@@ -73,9 +87,53 @@ function processOutcome(child, signal) {
|
|
|
73
87
|
const onAbort = () => {
|
|
74
88
|
finish({ signal: "SIGTERM" });
|
|
75
89
|
};
|
|
90
|
+
const scheduleHealthCheck = (delayMs) => {
|
|
91
|
+
if (!options.isHealthy || settled || signal.aborted)
|
|
92
|
+
return;
|
|
93
|
+
healthTimer = setTimeout(() => {
|
|
94
|
+
void runHealthCheck();
|
|
95
|
+
}, delayMs);
|
|
96
|
+
healthTimer.unref?.();
|
|
97
|
+
};
|
|
98
|
+
const runHealthCheck = async () => {
|
|
99
|
+
if (!options.isHealthy || settled || signal.aborted)
|
|
100
|
+
return;
|
|
101
|
+
let healthy = true;
|
|
102
|
+
try {
|
|
103
|
+
healthy = await options.isHealthy();
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
// Probe errors (DNS blips, timeouts) are not proof the tunnel is dead;
|
|
107
|
+
// only an explicit unhealthy result triggers a restart.
|
|
108
|
+
options.logger.debug(`${options.name} health probe errored; ignoring`, { error });
|
|
109
|
+
healthy = true;
|
|
110
|
+
}
|
|
111
|
+
if (settled || signal.aborted)
|
|
112
|
+
return;
|
|
113
|
+
if (healthy) {
|
|
114
|
+
consecutiveFailures = 0;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
consecutiveFailures += 1;
|
|
118
|
+
const threshold = options.healthCheckFailures ?? DEFAULT_HEALTH_CHECK_FAILURES;
|
|
119
|
+
options.logger.warn(`${options.name} public endpoint unhealthy`, {
|
|
120
|
+
consecutiveFailures,
|
|
121
|
+
threshold,
|
|
122
|
+
});
|
|
123
|
+
if (consecutiveFailures >= threshold) {
|
|
124
|
+
options.logger.warn(`${options.name} restarting after failed public liveness probes`);
|
|
125
|
+
child.kill("SIGTERM");
|
|
126
|
+
setTimeout(() => child.kill("SIGKILL"), options.shutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS).unref();
|
|
127
|
+
finish({ unhealthy: true, signal: "SIGTERM" });
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
scheduleHealthCheck(options.healthCheckIntervalMs ?? DEFAULT_HEALTH_CHECK_INTERVAL_MS);
|
|
132
|
+
};
|
|
76
133
|
child.once("exit", onExit);
|
|
77
134
|
child.once("error", onError);
|
|
78
135
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
136
|
+
scheduleHealthCheck(options.healthCheckGraceMs ?? DEFAULT_HEALTH_CHECK_GRACE_MS);
|
|
79
137
|
});
|
|
80
138
|
}
|
|
81
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VwZXJ2aXNvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdXBlcnZpc29yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxLQUFLLElBQUksVUFBVSxFQUFlLE1BQU0sd0JBQXdCLENBQUM7QUFFMUUsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUM7QUFDcEMsTUFBTSx5QkFBeUIsR0FBRyxNQUFNLENBQUM7QUFZekMsTUFBTSxVQUFVLHVCQUF1QixDQUFDLE9BTXZDO0lBQ0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztJQUN6QyxJQUFJLEtBQStCLENBQUM7SUFFcEMsTUFBTSxjQUFjLEdBQUcsR0FBRyxFQUFFO1FBQzFCLE1BQU0sYUFBYSxHQUFHLEtBQUssQ0FBQztRQUM1QixJQUFJLENBQUMsYUFBYTtZQUFFLE9BQU87UUFDM0IsYUFBYSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM5QixVQUFVLENBQ1IsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFDbkMsT0FBTyxDQUFDLGVBQWUsSUFBSSx5QkFBeUIsQ0FDckQsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNaLENBQUMsQ0FBQztJQUVGLE1BQU0sSUFBSSxHQUFHLEdBQUcsRUFBRTtRQUNoQixJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsT0FBTztZQUFFLE9BQU87UUFDdEMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25CLGNBQWMsRUFBRSxDQUFDO1FBQ2pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ3JDLENBQUMsQ0FBQztJQUNGLE1BQU0sYUFBYSxHQUFHLEdBQUcsRUFBRTtRQUN6QixJQUFJLEtBQUs7WUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ25DLENBQUMsQ0FBQztJQUNGLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBRXBDLE1BQU0sR0FBRyxHQUFHLEtBQUssSUFBSSxFQUFFO1FBQ3JCLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztRQUNqQixPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNsQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDN0IsSUFBSSxPQUF1QixDQUFDO1lBQzVCLElBQUksQ0FBQztnQkFDSCxLQUFLLEdBQUcsTUFBTSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQzlCLE9BQU8sR0FBRyxNQUFNLGNBQWMsQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzNELENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQ3RCLENBQUM7b0JBQVMsQ0FBQztnQkFDVCxLQUFLLEdBQUcsU0FBUyxDQUFDO1lBQ3BCLENBQUM7WUFDRCxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsT0FBTztnQkFBRSxPQUFPO1lBQ3RDLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVMsSUFBSSxvQkFBb0I7Z0JBQUUsUUFBUSxHQUFHLENBQUMsQ0FBQztZQUNqRSxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2hGLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksb0JBQW9CLEVBQUUsRUFBRSxHQUFHLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQ2xGLElBQUksQ0FBQztnQkFDSCxNQUFNLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyRCxDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLE9BQU87WUFDVCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLEtBQUssR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLG9CQUFvQixFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2xHLE9BQU87UUFDTCxJQUFJO0tBQ0wsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxLQUFtQixFQUFFLE1BQW1CO0lBQzlELE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUM3QixNQUFNLE1BQU0sR0FBRyxDQUFDLE9BQXVCLEVBQUUsRUFBRTtZQUN6QyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxQixLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUM1QixNQUFNLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQzdDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuQixDQUFDLENBQUM7UUFDRixNQUFNLE1BQU0sR0FBRyxDQUFDLElBQW1CLEVBQUUsVUFBaUMsRUFBRSxFQUFFLENBQ3hFLE1BQU0sQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztRQUN2QyxNQUFNLE9BQU8sR0FBRyxDQUFDLEtBQVksRUFBRSxFQUFFO1lBQy9CLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDdEIsTUFBTSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUNwQixDQUFDLENBQUM7UUFDRixNQUFNLE9BQU8sR0FBRyxHQUFHLEVBQUU7WUFDbkIsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDO1FBQ0YsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDM0IsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDN0IsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUM1RCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IENoaWxkUHJvY2VzcyB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IGFzeW5jIGFzIGFzeW5jVG9vbHMsIHR5cGUgTG9nZ2VyIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcblxuY29uc3QgU1RBQkxFX0NPTk5FQ1RJT05fTVMgPSA2MF8wMDA7XG5jb25zdCBERUZBVUxUX1NIVVRET1dOX0dSQUNFX01TID0gMTBfMDAwO1xuXG5leHBvcnQgaW50ZXJmYWNlIFByb2Nlc3NTdXBlcnZpc29yIHtcbiAgc3RvcCgpOiB2b2lkO1xufVxuXG50eXBlIFByb2Nlc3NPdXRjb21lID0ge1xuICBjb2RlPzogbnVtYmVyIHwgbnVsbDtcbiAgc2lnbmFsPzogTm9kZUpTLlNpZ25hbHMgfCBudWxsO1xuICBlcnJvcj86IHVua25vd247XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gc3VwZXJ2aXNlUHJvY2Vzc0ZvcmV2ZXIob3B0aW9uczoge1xuICBuYW1lOiBzdHJpbmc7XG4gIGxvZ2dlcjogTG9nZ2VyO1xuICBzdGFydDogKCkgPT4gQ2hpbGRQcm9jZXNzIHwgUHJvbWlzZTxDaGlsZFByb2Nlc3M+O1xuICByZXRyeURlbGF5c01zPzogcmVhZG9ubHkgbnVtYmVyW107XG4gIHNodXRkb3duR3JhY2VNcz86IG51bWJlcjtcbn0pOiBQcm9jZXNzU3VwZXJ2aXNvciB7XG4gIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gIGxldCBjaGlsZDogQ2hpbGRQcm9jZXNzIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0IHRlcm1pbmF0ZUNoaWxkID0gKCkgPT4ge1xuICAgIGNvbnN0IHN0b3BwaW5nQ2hpbGQgPSBjaGlsZDtcbiAgICBpZiAoIXN0b3BwaW5nQ2hpbGQpIHJldHVybjtcbiAgICBzdG9wcGluZ0NoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgIHNldFRpbWVvdXQoXG4gICAgICAoKSA9PiBzdG9wcGluZ0NoaWxkLmtpbGwoXCJTSUdLSUxMXCIpLFxuICAgICAgb3B0aW9ucy5zaHV0ZG93bkdyYWNlTXMgPz8gREVGQVVMVF9TSFVURE9XTl9HUkFDRV9NUyxcbiAgICApLnVucmVmKCk7XG4gIH07XG5cbiAgY29uc3Qgc3RvcCA9ICgpID0+IHtcbiAgICBpZiAoY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICAgIGNvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICB0ZXJtaW5hdGVDaGlsZCgpO1xuICAgIHByb2Nlc3Mub2ZmKFwiZXhpdFwiLCBvblByb2Nlc3NFeGl0KTtcbiAgfTtcbiAgY29uc3Qgb25Qcm9jZXNzRXhpdCA9ICgpID0+IHtcbiAgICBpZiAoY2hpbGQpIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICB9O1xuICBwcm9jZXNzLm9uY2UoXCJleGl0XCIsIG9uUHJvY2Vzc0V4aXQpO1xuXG4gIGNvbnN0IHJ1biA9IGFzeW5jICgpID0+IHtcbiAgICBsZXQgZmFpbHVyZXMgPSAwO1xuICAgIHdoaWxlICghY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGxldCBvdXRjb21lOiBQcm9jZXNzT3V0Y29tZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNoaWxkID0gYXdhaXQgb3B0aW9ucy5zdGFydCgpO1xuICAgICAgICBvdXRjb21lID0gYXdhaXQgcHJvY2Vzc091dGNvbWUoY2hpbGQsIGNvbnRyb2xsZXIuc2lnbmFsKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIG91dGNvbWUgPSB7IGVycm9yIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBjaGlsZCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmIChjb250cm9sbGVyLnNpZ25hbC5hYm9ydGVkKSByZXR1cm47XG4gICAgICBpZiAoRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdCA+PSBTVEFCTEVfQ09OTkVDVElPTl9NUykgZmFpbHVyZXMgPSAwO1xuICAgICAgY29uc3QgZGVsYXlNcyA9IGFzeW5jVG9vbHMuYm91bmRlZFJldHJ5RGVsYXkoZmFpbHVyZXMrKywgb3B0aW9ucy5yZXRyeURlbGF5c01zKTtcbiAgICAgIG9wdGlvbnMubG9nZ2VyLndhcm4oYCR7b3B0aW9ucy5uYW1lfSBzdG9wcGVkOyByZXRyeWluZ2AsIHsgLi4ub3V0Y29tZSwgZGVsYXlNcyB9KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGFzeW5jVG9vbHMuc2xlZXAoZGVsYXlNcywgY29udHJvbGxlci5zaWduYWwpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdm9pZCBydW4oKS5jYXRjaCgoZXJyb3IpID0+IG9wdGlvbnMubG9nZ2VyLmVycm9yKGAke29wdGlvbnMubmFtZX0gc3VwZXJ2aXNvciBmYWlsZWRgLCB7IGVycm9yIH0pKTtcbiAgcmV0dXJuIHtcbiAgICBzdG9wLFxuICB9O1xufVxuXG5mdW5jdGlvbiBwcm9jZXNzT3V0Y29tZShjaGlsZDogQ2hpbGRQcm9jZXNzLCBzaWduYWw6IEFib3J0U2lnbmFsKTogUHJvbWlzZTxQcm9jZXNzT3V0Y29tZT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBjb25zdCBmaW5pc2ggPSAob3V0Y29tZTogUHJvY2Vzc091dGNvbWUpID0+IHtcbiAgICAgIGNoaWxkLm9mZihcImV4aXRcIiwgb25FeGl0KTtcbiAgICAgIGNoaWxkLm9mZihcImVycm9yXCIsIG9uRXJyb3IpO1xuICAgICAgc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBvbkFib3J0KTtcbiAgICAgIHJlc29sdmUob3V0Y29tZSk7XG4gICAgfTtcbiAgICBjb25zdCBvbkV4aXQgPSAoY29kZTogbnVtYmVyIHwgbnVsbCwgZXhpdFNpZ25hbDogTm9kZUpTLlNpZ25hbHMgfCBudWxsKSA9PlxuICAgICAgZmluaXNoKHsgY29kZSwgc2lnbmFsOiBleGl0U2lnbmFsIH0pO1xuICAgIGNvbnN0IG9uRXJyb3IgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBjaGlsZC5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICAgIGZpbmlzaCh7IGVycm9yIH0pO1xuICAgIH07XG4gICAgY29uc3Qgb25BYm9ydCA9ICgpID0+IHtcbiAgICAgIGZpbmlzaCh7IHNpZ25hbDogXCJTSUdURVJNXCIgfSk7XG4gICAgfTtcbiAgICBjaGlsZC5vbmNlKFwiZXhpdFwiLCBvbkV4aXQpO1xuICAgIGNoaWxkLm9uY2UoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uQWJvcnQsIHsgb25jZTogdHJ1ZSB9KTtcbiAgfSk7XG59XG4iXX0=
|
|
139
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VwZXJ2aXNvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdXBlcnZpc29yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxLQUFLLElBQUksVUFBVSxFQUFlLE1BQU0sd0JBQXdCLENBQUM7QUFFMUUsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUM7QUFDcEMsTUFBTSx5QkFBeUIsR0FBRyxNQUFNLENBQUM7QUFDekMsbUZBQW1GO0FBQ25GLE1BQU0sNkJBQTZCLEdBQUcsTUFBTSxDQUFDO0FBQzdDLHdFQUF3RTtBQUN4RSxNQUFNLGdDQUFnQyxHQUFHLE1BQU0sQ0FBQztBQUNoRCwrRUFBK0U7QUFDL0UsTUFBTSw2QkFBNkIsR0FBRyxDQUFDLENBQUM7QUFpQ3hDLE1BQU0sVUFBVSx1QkFBdUIsQ0FBQyxPQUFpQztJQUN2RSxNQUFNLFVBQVUsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO0lBQ3pDLElBQUksS0FBK0IsQ0FBQztJQUVwQyxNQUFNLGNBQWMsR0FBRyxHQUFHLEVBQUU7UUFDMUIsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDO1FBQzVCLElBQUksQ0FBQyxhQUFhO1lBQUUsT0FBTztRQUMzQixhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzlCLFVBQVUsQ0FDUixHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUNuQyxPQUFPLENBQUMsZUFBZSxJQUFJLHlCQUF5QixDQUNyRCxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ1osQ0FBQyxDQUFDO0lBRUYsTUFBTSxJQUFJLEdBQUcsR0FBRyxFQUFFO1FBQ2hCLElBQUksVUFBVSxDQUFDLE1BQU0sQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUN0QyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbkIsY0FBYyxFQUFFLENBQUM7UUFDakIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUs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QUVGLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzNCLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzdCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUQsbUJBQW1CLENBQUMsT0FBTyxDQUFDLGtCQUFrQixJQUFJLDZCQUE2QixDQUFDLENBQUM7SUFDbkYsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBDaGlsZFByb2Nlc3MgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBhc3luYyBhcyBhc3luY1Rvb2xzLCB0eXBlIExvZ2dlciB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5cbmNvbnN0IFNUQUJMRV9DT05ORUNUSU9OX01TID0gNjBfMDAwO1xuY29uc3QgREVGQVVMVF9TSFVURE9XTl9HUkFDRV9NUyA9IDEwXzAwMDtcbi8qKiBIb3cgbG9uZyB0byB3YWl0IGFmdGVyIGEgY2hpbGQgc3RhcnQgYmVmb3JlIHRoZSBmaXJzdCBwdWJsaWMgbGl2ZW5lc3MgcHJvYmUuICovXG5jb25zdCBERUZBVUxUX0hFQUxUSF9DSEVDS19HUkFDRV9NUyA9IDQ1XzAwMDtcbi8qKiBJbnRlcnZhbCBiZXR3ZWVuIHB1YmxpYyBsaXZlbmVzcyBwcm9iZXMgd2hpbGUgYSBjaGlsZCBpcyBydW5uaW5nLiAqL1xuY29uc3QgREVGQVVMVF9IRUFMVEhfQ0hFQ0tfSU5URVJWQUxfTVMgPSAzMF8wMDA7XG4vKiogQ29uc2VjdXRpdmUgZmFpbGVkIHByb2JlcyByZXF1aXJlZCBiZWZvcmUga2lsbGluZyBhIHN0aWxsLXJ1bm5pbmcgY2hpbGQuICovXG5jb25zdCBERUZBVUxUX0hFQUxUSF9DSEVDS19GQUlMVVJFUyA9IDI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvY2Vzc1N1cGVydmlzb3Ige1xuICBzdG9wKCk6IHZvaWQ7XG59XG5cbnR5cGUgUHJvY2Vzc091dGNvbWUgPSB7XG4gIGNvZGU/OiBudW1iZXIgfCBudWxsO1xuICBzaWduYWw/OiBOb2RlSlMuU2lnbmFscyB8IG51bGw7XG4gIGVycm9yPzogdW5rbm93bjtcbiAgLyoqIFNldCB3aGVuIHRoZSBzdXBlcnZpc29yIGtpbGxlZCB0aGUgY2hpbGQgYWZ0ZXIgYSBmYWlsZWQgbGl2ZW5lc3MgcHJvYmUuICovXG4gIHVuaGVhbHRoeT86IHRydWU7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFByb2Nlc3NTdXBlcnZpc29yT3B0aW9ucyB7XG4gIG5hbWU6IHN0cmluZztcbiAgbG9nZ2VyOiBMb2dnZXI7XG4gIHN0YXJ0OiAoKSA9PiBDaGlsZFByb2Nlc3MgfCBQcm9taXNlPENoaWxkUHJvY2Vzcz47XG4gIHJldHJ5RGVsYXlzTXM/OiByZWFkb25seSBudW1iZXJbXTtcbiAgc2h1dGRvd25HcmFjZU1zPzogbnVtYmVyO1xuICAvKipcbiAgICogT3B0aW9uYWwgcHVibGljIGxpdmVuZXNzIHByb2JlLiBXaGVuIGl0IHJldHVybnMgYGZhbHNlYCB3aGlsZSB0aGUgY2hpbGQgaXNcbiAgICogc3RpbGwgcnVubmluZywgdGhlIHN1cGVydmlzb3Iga2lsbHMgdGhlIGNoaWxkIHNvIHRoZSBmb3JldmVyLWxvb3AgcmVzdGFydHNcbiAgICogaXQuIFVzZWQgYnkgcG9ydHIgdG8gcmVjb3ZlciBmcm9tIGFuIGVkZ2UgdGhhdCBkcm9wcGVkIHRoZSBzdWJkb21haW5cbiAgICogcmVnaXN0cmF0aW9uIHdoaWxlIHRoZSBsb2NhbCBwcm9jZXNzIGtlcHQgcnVubmluZyAoc2VlXG4gICAqIGB4LXBvcnRyLWVycm9yLXJlYXNvbjogdW5yZWdpc3RlcmVkLXN1YmRvbWFpbmApLlxuICAgKi9cbiAgaXNIZWFsdGh5PzogKCkgPT4gYm9vbGVhbiB8IFByb21pc2U8Ym9vbGVhbj47XG4gIGhlYWx0aENoZWNrR3JhY2VNcz86IG51bWJlcjtcbiAgaGVhbHRoQ2hlY2tJbnRlcnZhbE1zPzogbnVtYmVyO1xuICBoZWFsdGhDaGVja0ZhaWx1cmVzPzogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3VwZXJ2aXNlUHJvY2Vzc0ZvcmV2ZXIob3B0aW9uczogUHJvY2Vzc1N1cGVydmlzb3JPcHRpb25zKTogUHJvY2Vzc1N1cGVydmlzb3Ige1xuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBsZXQgY2hpbGQ6IENoaWxkUHJvY2VzcyB8IHVuZGVmaW5lZDtcblxuICBjb25zdCB0ZXJtaW5hdGVDaGlsZCA9ICgpID0+IHtcbiAgICBjb25zdCBzdG9wcGluZ0NoaWxkID0gY2hpbGQ7XG4gICAgaWYgKCFzdG9wcGluZ0NoaWxkKSByZXR1cm47XG4gICAgc3RvcHBpbmdDaGlsZC5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICBzZXRUaW1lb3V0KFxuICAgICAgKCkgPT4gc3RvcHBpbmdDaGlsZC5raWxsKFwiU0lHS0lMTFwiKSxcbiAgICAgIG9wdGlvbnMuc2h1dGRvd25HcmFjZU1zID8/IERFRkFVTFRfU0hVVERPV05fR1JBQ0VfTVMsXG4gICAgKS51bnJlZigpO1xuICB9O1xuXG4gIGNvbnN0IHN0b3AgPSAoKSA9PiB7XG4gICAgaWYgKGNvbnRyb2xsZXIuc2lnbmFsLmFib3J0ZWQpIHJldHVybjtcbiAgICBjb250cm9sbGVyLmFib3J0KCk7XG4gICAgdGVybWluYXRlQ2hpbGQoKTtcbiAgICBwcm9jZXNzLm9mZihcImV4aXRcIiwgb25Qcm9jZXNzRXhpdCk7XG4gIH07XG4gIGNvbnN0IG9uUHJvY2Vzc0V4aXQgPSAoKSA9PiB7XG4gICAgaWYgKGNoaWxkKSBjaGlsZC5raWxsKFwiU0lHVEVSTVwiKTtcbiAgfTtcbiAgcHJvY2Vzcy5vbmNlKFwiZXhpdFwiLCBvblByb2Nlc3NFeGl0KTtcblxuICBjb25zdCBydW4gPSBhc3luYyAoKSA9PiB7XG4gICAgbGV0IGZhaWx1cmVzID0gMDtcbiAgICB3aGlsZSAoIWNvbnRyb2xsZXIuc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgIGNvbnN0IHN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gICAgICBsZXQgb3V0Y29tZTogUHJvY2Vzc091dGNvbWU7XG4gICAgICB0cnkge1xuICAgICAgICBjaGlsZCA9IGF3YWl0IG9wdGlvbnMuc3RhcnQoKTtcbiAgICAgICAgb3V0Y29tZSA9IGF3YWl0IHByb2Nlc3NPdXRjb21lKGNoaWxkLCBjb250cm9sbGVyLnNpZ25hbCwgb3B0aW9ucyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBvdXRjb21lID0geyBlcnJvciB9O1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgY2hpbGQgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBpZiAoY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICAgICAgaWYgKERhdGUubm93KCkgLSBzdGFydGVkQXQgPj0gU1RBQkxFX0NPTk5FQ1RJT05fTVMpIGZhaWx1cmVzID0gMDtcbiAgICAgIGNvbnN0IGRlbGF5TXMgPSBhc3luY1Rvb2xzLmJvdW5kZWRSZXRyeURlbGF5KGZhaWx1cmVzKyssIG9wdGlvbnMucmV0cnlEZWxheXNNcyk7XG4gICAgICBvcHRpb25zLmxvZ2dlci53YXJuKGAke29wdGlvbnMubmFtZX0gc3RvcHBlZDsgcmV0cnlpbmdgLCB7IC4uLm91dGNvbWUsIGRlbGF5TXMgfSk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBhc3luY1Rvb2xzLnNsZWVwKGRlbGF5TXMsIGNvbnRyb2xsZXIuc2lnbmFsKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZvaWQgcnVuKCkuY2F0Y2goKGVycm9yKSA9PiBvcHRpb25zLmxvZ2dlci5lcnJvcihgJHtvcHRpb25zLm5hbWV9IHN1cGVydmlzb3IgZmFpbGVkYCwgeyBlcnJvciB9KSk7XG4gIHJldHVybiB7XG4gICAgc3RvcCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gcHJvY2Vzc091dGNvbWUoXG4gIGNoaWxkOiBDaGlsZFByb2Nlc3MsXG4gIHNpZ25hbDogQWJvcnRTaWduYWwsXG4gIG9wdGlvbnM6IFByb2Nlc3NTdXBlcnZpc29yT3B0aW9ucyxcbik6IFByb21pc2U8UHJvY2Vzc091dGNvbWU+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgbGV0IHNldHRsZWQgPSBmYWxzZTtcbiAgICBsZXQgaGVhbHRoVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgdW5kZWZpbmVkO1xuICAgIGxldCBjb25zZWN1dGl2ZUZhaWx1cmVzID0gMDtcblxuICAgIGNvbnN0IGZpbmlzaCA9IChvdXRjb21lOiBQcm9jZXNzT3V0Y29tZSkgPT4ge1xuICAgICAgaWYgKHNldHRsZWQpIHJldHVybjtcbiAgICAgIHNldHRsZWQgPSB0cnVlO1xuICAgICAgaWYgKGhlYWx0aFRpbWVyKSBjbGVhclRpbWVvdXQoaGVhbHRoVGltZXIpO1xuICAgICAgY2hpbGQub2ZmKFwiZXhpdFwiLCBvbkV4aXQpO1xuICAgICAgY2hpbGQub2ZmKFwiZXJyb3JcIiwgb25FcnJvcik7XG4gICAgICBzaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uQWJvcnQpO1xuICAgICAgcmVzb2x2ZShvdXRjb21lKTtcbiAgICB9O1xuICAgIGNvbnN0IG9uRXhpdCA9IChjb2RlOiBudW1iZXIgfCBudWxsLCBleGl0U2lnbmFsOiBOb2RlSlMuU2lnbmFscyB8IG51bGwpID0+XG4gICAgICBmaW5pc2goeyBjb2RlLCBzaWduYWw6IGV4aXRTaWduYWwgfSk7XG4gICAgY29uc3Qgb25FcnJvciA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgICAgZmluaXNoKHsgZXJyb3IgfSk7XG4gICAgfTtcbiAgICBjb25zdCBvbkFib3J0ID0gKCkgPT4ge1xuICAgICAgZmluaXNoKHsgc2lnbmFsOiBcIlNJR1RFUk1cIiB9KTtcbiAgICB9O1xuXG4gICAgY29uc3Qgc2NoZWR1bGVIZWFsdGhDaGVjayA9IChkZWxheU1zOiBudW1iZXIpID0+IHtcbiAgICAgIGlmICghb3B0aW9ucy5pc0hlYWx0aHkgfHwgc2V0dGxlZCB8fCBzaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICAgICAgaGVhbHRoVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdm9pZCBydW5IZWFsdGhDaGVjaygpO1xuICAgICAgfSwgZGVsYXlNcyk7XG4gICAgICBoZWFsdGhUaW1lci51bnJlZj8uKCk7XG4gICAgfTtcblxuICAgIGNvbnN0IHJ1bkhlYWx0aENoZWNrID0gYXN5bmMgKCkgPT4ge1xuICAgICAgaWYgKCFvcHRpb25zLmlzSGVhbHRoeSB8fCBzZXR0bGVkIHx8IHNpZ25hbC5hYm9ydGVkKSByZXR1cm47XG4gICAgICBsZXQgaGVhbHRoeSA9IHRydWU7XG4gICAgICB0cnkge1xuICAgICAgICBoZWFsdGh5ID0gYXdhaXQgb3B0aW9ucy5pc0hlYWx0aHkoKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIFByb2JlIGVycm9ycyAoRE5TIGJsaXBzLCB0aW1lb3V0cykgYXJlIG5vdCBwcm9vZiB0aGUgdHVubmVsIGlzIGRlYWQ7XG4gICAgICAgIC8vIG9ubHkgYW4gZXhwbGljaXQgdW5oZWFsdGh5IHJlc3VsdCB0cmlnZ2VycyBhIHJlc3RhcnQuXG4gICAgICAgIG9wdGlvbnMubG9nZ2VyLmRlYnVnKGAke29wdGlvbnMubmFtZX0gaGVhbHRoIHByb2JlIGVycm9yZWQ7IGlnbm9yaW5nYCwgeyBlcnJvciB9KTtcbiAgICAgICAgaGVhbHRoeSA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAoc2V0dGxlZCB8fCBzaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICAgICAgaWYgKGhlYWx0aHkpIHtcbiAgICAgICAgY29uc2VjdXRpdmVGYWlsdXJlcyA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zZWN1dGl2ZUZhaWx1cmVzICs9IDE7XG4gICAgICAgIGNvbnN0IHRocmVzaG9sZCA9IG9wdGlvbnMuaGVhbHRoQ2hlY2tGYWlsdXJlcyA/PyBERUZBVUxUX0hFQUxUSF9DSEVDS19GQUlMVVJFUztcbiAgICAgICAgb3B0aW9ucy5sb2dnZXIud2FybihgJHtvcHRpb25zLm5hbWV9IHB1YmxpYyBlbmRwb2ludCB1bmhlYWx0aHlgLCB7XG4gICAgICAgICAgY29uc2VjdXRpdmVGYWlsdXJlcyxcbiAgICAgICAgICB0aHJlc2hvbGQsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY29uc2VjdXRpdmVGYWlsdXJlcyA+PSB0aHJlc2hvbGQpIHtcbiAgICAgICAgICBvcHRpb25zLmxvZ2dlci53YXJuKGAke29wdGlvbnMubmFtZX0gcmVzdGFydGluZyBhZnRlciBmYWlsZWQgcHVibGljIGxpdmVuZXNzIHByb2Jlc2ApO1xuICAgICAgICAgIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgICAgICAgIHNldFRpbWVvdXQoXG4gICAgICAgICAgICAoKSA9PiBjaGlsZC5raWxsKFwiU0lHS0lMTFwiKSxcbiAgICAgICAgICAgIG9wdGlvbnMuc2h1dGRvd25HcmFjZU1zID8/IERFRkFVTFRfU0hVVERPV05fR1JBQ0VfTVMsXG4gICAgICAgICAgKS51bnJlZigpO1xuICAgICAgICAgIGZpbmlzaCh7IHVuaGVhbHRoeTogdHJ1ZSwgc2lnbmFsOiBcIlNJR1RFUk1cIiB9KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHNjaGVkdWxlSGVhbHRoQ2hlY2sob3B0aW9ucy5oZWFsdGhDaGVja0ludGVydmFsTXMgPz8gREVGQVVMVF9IRUFMVEhfQ0hFQ0tfSU5URVJWQUxfTVMpO1xuICAgIH07XG5cbiAgICBjaGlsZC5vbmNlKFwiZXhpdFwiLCBvbkV4aXQpO1xuICAgIGNoaWxkLm9uY2UoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uQWJvcnQsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICBzY2hlZHVsZUhlYWx0aENoZWNrKG9wdGlvbnMuaGVhbHRoQ2hlY2tHcmFjZU1zID8/IERFRkFVTFRfSEVBTFRIX0NIRUNLX0dSQUNFX01TKTtcbiAgfSk7XG59XG4iXX0=
|
package/package.json
CHANGED
|
@@ -19,21 +19,21 @@
|
|
|
19
19
|
"projen": "projen"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@dbx-tools/email": "0.6.
|
|
22
|
+
"@dbx-tools/email": "0.6.216",
|
|
23
23
|
"@types/bun": "1.3.14",
|
|
24
24
|
"@types/node": "^24.6.0",
|
|
25
25
|
"typescript": "^5.9.3"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@dbx-tools/email": "0.6.
|
|
28
|
+
"@dbx-tools/email": "0.6.216"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@databricks/appkit": "^0.60.0",
|
|
32
|
-
"@dbx-tools/appkit": "0.6.
|
|
33
|
-
"@dbx-tools/auth-gate": "0.6.
|
|
34
|
-
"@dbx-tools/core": "0.6.
|
|
35
|
-
"@dbx-tools/shared-auth": "0.6.
|
|
36
|
-
"@dbx-tools/shared-core": "0.6.
|
|
32
|
+
"@dbx-tools/appkit": "0.6.216",
|
|
33
|
+
"@dbx-tools/auth-gate": "0.6.216",
|
|
34
|
+
"@dbx-tools/core": "0.6.216",
|
|
35
|
+
"@dbx-tools/shared-auth": "0.6.216",
|
|
36
|
+
"@dbx-tools/shared-core": "0.6.216",
|
|
37
37
|
"@types/express": "^5.0.5",
|
|
38
38
|
"http-proxy-3": "^1.23.1"
|
|
39
39
|
},
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"./package.json": "./package.json"
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
-
"version": "0.6.
|
|
54
|
+
"version": "0.6.216",
|
|
55
55
|
"types": "./lib/index.d.ts",
|
|
56
56
|
"type": "module",
|
|
57
57
|
"exports": {
|
package/src/portr.ts
CHANGED
|
@@ -169,13 +169,34 @@ export async function startPortr(
|
|
|
169
169
|
return child;
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Probe the public portr URL. A registered tunnel is healthy even when the app
|
|
174
|
+
* returns an auth challenge (401/302) - those prove the edge still has the
|
|
175
|
+
* subdomain. Only an explicit `unregistered-subdomain` (or any other
|
|
176
|
+
* `x-portr-error`) means the client must be restarted.
|
|
177
|
+
*/
|
|
178
|
+
export async function probePortrPublicUrl(publicUrl: string): Promise<boolean> {
|
|
179
|
+
const response = await fetch(publicUrl, {
|
|
180
|
+
method: "HEAD",
|
|
181
|
+
redirect: "manual",
|
|
182
|
+
signal: AbortSignal.timeout(5_000),
|
|
183
|
+
});
|
|
184
|
+
if (response.headers.get("x-portr-error") === "true") return false;
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
|
|
172
188
|
export function supervisePortr(
|
|
173
189
|
config: PortrConfig,
|
|
174
190
|
childEnv: NodeJS.ProcessEnv,
|
|
175
191
|
): ProcessSupervisor {
|
|
192
|
+
const publicUrl = `https://${config.subdomain}.${config.server}`;
|
|
176
193
|
return superviseProcessForever({
|
|
177
194
|
name: "portr",
|
|
178
195
|
logger,
|
|
179
196
|
start: () => startPortr(config, childEnv),
|
|
197
|
+
// Kill + restart when the edge drops the registration while the local
|
|
198
|
+
// process is still alive. Without this, lensiq.apps.dbx.tools (and any
|
|
199
|
+
// other in-process tunnel) stays unregistered until a full app bounce.
|
|
200
|
+
isHealthy: () => probePortrPublicUrl(publicUrl),
|
|
180
201
|
});
|
|
181
202
|
}
|
package/src/supervisor.ts
CHANGED
|
@@ -3,6 +3,12 @@ import { async as asyncTools, type Logger } from "@dbx-tools/shared-core";
|
|
|
3
3
|
|
|
4
4
|
const STABLE_CONNECTION_MS = 60_000;
|
|
5
5
|
const DEFAULT_SHUTDOWN_GRACE_MS = 10_000;
|
|
6
|
+
/** How long to wait after a child start before the first public liveness probe. */
|
|
7
|
+
const DEFAULT_HEALTH_CHECK_GRACE_MS = 45_000;
|
|
8
|
+
/** Interval between public liveness probes while a child is running. */
|
|
9
|
+
const DEFAULT_HEALTH_CHECK_INTERVAL_MS = 30_000;
|
|
10
|
+
/** Consecutive failed probes required before killing a still-running child. */
|
|
11
|
+
const DEFAULT_HEALTH_CHECK_FAILURES = 2;
|
|
6
12
|
|
|
7
13
|
export interface ProcessSupervisor {
|
|
8
14
|
stop(): void;
|
|
@@ -12,15 +18,30 @@ type ProcessOutcome = {
|
|
|
12
18
|
code?: number | null;
|
|
13
19
|
signal?: NodeJS.Signals | null;
|
|
14
20
|
error?: unknown;
|
|
21
|
+
/** Set when the supervisor killed the child after a failed liveness probe. */
|
|
22
|
+
unhealthy?: true;
|
|
15
23
|
};
|
|
16
24
|
|
|
17
|
-
export
|
|
25
|
+
export interface ProcessSupervisorOptions {
|
|
18
26
|
name: string;
|
|
19
27
|
logger: Logger;
|
|
20
28
|
start: () => ChildProcess | Promise<ChildProcess>;
|
|
21
29
|
retryDelaysMs?: readonly number[];
|
|
22
30
|
shutdownGraceMs?: number;
|
|
23
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Optional public liveness probe. When it returns `false` while the child is
|
|
33
|
+
* still running, the supervisor kills the child so the forever-loop restarts
|
|
34
|
+
* it. Used by portr to recover from an edge that dropped the subdomain
|
|
35
|
+
* registration while the local process kept running (see
|
|
36
|
+
* `x-portr-error-reason: unregistered-subdomain`).
|
|
37
|
+
*/
|
|
38
|
+
isHealthy?: () => boolean | Promise<boolean>;
|
|
39
|
+
healthCheckGraceMs?: number;
|
|
40
|
+
healthCheckIntervalMs?: number;
|
|
41
|
+
healthCheckFailures?: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function superviseProcessForever(options: ProcessSupervisorOptions): ProcessSupervisor {
|
|
24
45
|
const controller = new AbortController();
|
|
25
46
|
let child: ChildProcess | undefined;
|
|
26
47
|
|
|
@@ -52,7 +73,7 @@ export function superviseProcessForever(options: {
|
|
|
52
73
|
let outcome: ProcessOutcome;
|
|
53
74
|
try {
|
|
54
75
|
child = await options.start();
|
|
55
|
-
outcome = await processOutcome(child, controller.signal);
|
|
76
|
+
outcome = await processOutcome(child, controller.signal, options);
|
|
56
77
|
} catch (error) {
|
|
57
78
|
outcome = { error };
|
|
58
79
|
} finally {
|
|
@@ -76,9 +97,20 @@ export function superviseProcessForever(options: {
|
|
|
76
97
|
};
|
|
77
98
|
}
|
|
78
99
|
|
|
79
|
-
function processOutcome(
|
|
100
|
+
function processOutcome(
|
|
101
|
+
child: ChildProcess,
|
|
102
|
+
signal: AbortSignal,
|
|
103
|
+
options: ProcessSupervisorOptions,
|
|
104
|
+
): Promise<ProcessOutcome> {
|
|
80
105
|
return new Promise((resolve) => {
|
|
106
|
+
let settled = false;
|
|
107
|
+
let healthTimer: ReturnType<typeof setTimeout> | undefined;
|
|
108
|
+
let consecutiveFailures = 0;
|
|
109
|
+
|
|
81
110
|
const finish = (outcome: ProcessOutcome) => {
|
|
111
|
+
if (settled) return;
|
|
112
|
+
settled = true;
|
|
113
|
+
if (healthTimer) clearTimeout(healthTimer);
|
|
82
114
|
child.off("exit", onExit);
|
|
83
115
|
child.off("error", onError);
|
|
84
116
|
signal.removeEventListener("abort", onAbort);
|
|
@@ -93,8 +125,53 @@ function processOutcome(child: ChildProcess, signal: AbortSignal): Promise<Proce
|
|
|
93
125
|
const onAbort = () => {
|
|
94
126
|
finish({ signal: "SIGTERM" });
|
|
95
127
|
};
|
|
128
|
+
|
|
129
|
+
const scheduleHealthCheck = (delayMs: number) => {
|
|
130
|
+
if (!options.isHealthy || settled || signal.aborted) return;
|
|
131
|
+
healthTimer = setTimeout(() => {
|
|
132
|
+
void runHealthCheck();
|
|
133
|
+
}, delayMs);
|
|
134
|
+
healthTimer.unref?.();
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const runHealthCheck = async () => {
|
|
138
|
+
if (!options.isHealthy || settled || signal.aborted) return;
|
|
139
|
+
let healthy = true;
|
|
140
|
+
try {
|
|
141
|
+
healthy = await options.isHealthy();
|
|
142
|
+
} catch (error) {
|
|
143
|
+
// Probe errors (DNS blips, timeouts) are not proof the tunnel is dead;
|
|
144
|
+
// only an explicit unhealthy result triggers a restart.
|
|
145
|
+
options.logger.debug(`${options.name} health probe errored; ignoring`, { error });
|
|
146
|
+
healthy = true;
|
|
147
|
+
}
|
|
148
|
+
if (settled || signal.aborted) return;
|
|
149
|
+
if (healthy) {
|
|
150
|
+
consecutiveFailures = 0;
|
|
151
|
+
} else {
|
|
152
|
+
consecutiveFailures += 1;
|
|
153
|
+
const threshold = options.healthCheckFailures ?? DEFAULT_HEALTH_CHECK_FAILURES;
|
|
154
|
+
options.logger.warn(`${options.name} public endpoint unhealthy`, {
|
|
155
|
+
consecutiveFailures,
|
|
156
|
+
threshold,
|
|
157
|
+
});
|
|
158
|
+
if (consecutiveFailures >= threshold) {
|
|
159
|
+
options.logger.warn(`${options.name} restarting after failed public liveness probes`);
|
|
160
|
+
child.kill("SIGTERM");
|
|
161
|
+
setTimeout(
|
|
162
|
+
() => child.kill("SIGKILL"),
|
|
163
|
+
options.shutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS,
|
|
164
|
+
).unref();
|
|
165
|
+
finish({ unhealthy: true, signal: "SIGTERM" });
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
scheduleHealthCheck(options.healthCheckIntervalMs ?? DEFAULT_HEALTH_CHECK_INTERVAL_MS);
|
|
170
|
+
};
|
|
171
|
+
|
|
96
172
|
child.once("exit", onExit);
|
|
97
173
|
child.once("error", onError);
|
|
98
174
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
175
|
+
scheduleHealthCheck(options.healthCheckGraceMs ?? DEFAULT_HEALTH_CHECK_GRACE_MS);
|
|
99
176
|
});
|
|
100
177
|
}
|