@grest-ts/discovery-local 0.0.37 → 0.0.39
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 +8 -0
- package/dist/src/_dedupCheck.js +1 -1
- package/dist/src/bin/discovery-local.d.ts +3 -0
- package/dist/src/bin/discovery-local.d.ts.map +1 -0
- package/dist/src/bin/discovery-local.js +58 -0
- package/dist/src/bin/discovery-local.js.map +1 -0
- package/dist/src/local/GGDiscoveryIPC.d.ts +8 -0
- package/dist/src/local/GGDiscoveryIPC.d.ts.map +1 -1
- package/dist/src/local/GGDiscoveryIPC.js +7 -0
- package/dist/src/local/GGDiscoveryIPC.js.map +1 -1
- package/dist/src/local/GGLocalDiscoveryClient.d.ts +3 -0
- package/dist/src/local/GGLocalDiscoveryClient.d.ts.map +1 -1
- package/dist/src/local/GGLocalDiscoveryClient.js +38 -2
- package/dist/src/local/GGLocalDiscoveryClient.js.map +1 -1
- package/dist/src/local/GGLocalDiscoveryResilientClient.d.ts +3 -0
- package/dist/src/local/GGLocalDiscoveryResilientClient.d.ts.map +1 -1
- package/dist/src/local/GGLocalDiscoveryResilientClient.js +32 -8
- package/dist/src/local/GGLocalDiscoveryResilientClient.js.map +1 -1
- package/dist/src/local/GGLocalDiscoveryServer.d.ts +4 -1
- package/dist/src/local/GGLocalDiscoveryServer.d.ts.map +1 -1
- package/dist/src/local/GGLocalDiscoveryServer.js +24 -4
- package/dist/src/local/GGLocalDiscoveryServer.js.map +1 -1
- package/dist/tsconfig.publish.tsbuildinfo +1 -1
- package/package.json +11 -7
- package/src/_dedupCheck.ts +1 -1
- package/src/bin/discovery-local.ts +58 -0
- package/src/local/GGDiscoveryIPC.ts +7 -0
- package/src/local/GGLocalDiscoveryClient.ts +36 -2
- package/src/local/GGLocalDiscoveryResilientClient.ts +33 -8
- package/src/local/GGLocalDiscoveryServer.ts +25 -5
- package/src/local/yield.test.ts +136 -0
package/README.md
CHANGED
|
@@ -13,6 +13,14 @@ For a full overview of how discovery works, see the [Discovery guide](@guide/dis
|
|
|
13
13
|
|
|
14
14
|
Runs a local discovery server that acts as a central router. Service instances connect over IPC, register their routes, and discover each other through the router. The router also acts as a reverse proxy, forwarding requests to the correct backend based on path prefix matching.
|
|
15
15
|
|
|
16
|
+
## Standalone bin
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
npx @grest-ts/discovery-local --port 9000
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Runs `GGLocalDiscoveryServer` as its own process (default port `9000`). Use this when you want the router up before any runtime, with clean ownership and its own logs. Without it, runtimes default to `GGLocalDiscoveryResilientClient` and leader-elect for the router port; with it running, point runtimes at it as plain `GGLocalDiscoveryClient`s.
|
|
23
|
+
|
|
16
24
|
## Exported classes
|
|
17
25
|
|
|
18
26
|
| Class | Purpose |
|
package/dist/src/_dedupCheck.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
const __KEY = Symbol.for("grest-ts:dedup:@grest-ts/discovery-local");
|
|
12
12
|
const __slot = globalThis;
|
|
13
13
|
const __existing = __slot[__KEY];
|
|
14
|
-
const __here = { path: import.meta.url, version: "0.0.
|
|
14
|
+
const __here = { path: import.meta.url, version: "0.0.39" };
|
|
15
15
|
// Same path + same version means the same physical package is being
|
|
16
16
|
// re-evaluated by a different ESM runner (e.g. vitest projects share one
|
|
17
17
|
// process but each project has its own module cache). That isn't a true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery-local.d.ts","sourceRoot":"","sources":["../../../src/bin/discovery-local.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env -S npx tsx
|
|
2
|
+
/**
|
|
3
|
+
* Standalone launcher for the local discovery router. The bin is
|
|
4
|
+
* authoritative: on EADDRINUSE it sends `requestYield` to the holder
|
|
5
|
+
* and retries the bind. Resilient clients that ever connect to a bin
|
|
6
|
+
* lock out their own leader bids for the rest of their lifetime.
|
|
7
|
+
*
|
|
8
|
+
* npx @grest-ts/discovery-local
|
|
9
|
+
*/
|
|
10
|
+
import { GGLog } from "@grest-ts/logger";
|
|
11
|
+
import { GGLocatorScope } from "@grest-ts/locator";
|
|
12
|
+
import { IPCServer, IPCClient } from "@grest-ts/ipc";
|
|
13
|
+
import { GGLocalDiscoveryServer } from "../local/GGLocalDiscoveryServer.js";
|
|
14
|
+
import { GGDiscoveryIPC, DiscoveryServerKind } from "../local/GGDiscoveryIPC.js";
|
|
15
|
+
import { getLocalDiscoveryPort } from "../local/GGLocalDiscoveryClient.js";
|
|
16
|
+
async function main() {
|
|
17
|
+
const port = getLocalDiscoveryPort();
|
|
18
|
+
let router;
|
|
19
|
+
for (let i = 0; i < 100; i++) {
|
|
20
|
+
const candidate = new GGLocalDiscoveryServer(new IPCServer(port), DiscoveryServerKind.Bin);
|
|
21
|
+
if (await candidate.start()) {
|
|
22
|
+
router = candidate;
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const c = new IPCClient(port);
|
|
27
|
+
try {
|
|
28
|
+
await c.connect();
|
|
29
|
+
await c.sendFrameworkRequest(GGDiscoveryIPC.discoveryServer.requestYield, undefined);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
/* holder may have already gone */
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
c.disconnect();
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
/* tolerated */
|
|
39
|
+
}
|
|
40
|
+
GGLog.info("discovery-local", `Trying to take over discovery port ${port}`);
|
|
41
|
+
await new Promise(r => setTimeout(r, 50));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (!router) {
|
|
45
|
+
GGLog.error("discovery-local", `Could not bind port ${port} after 100 attempts`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
GGLog.info("discovery-local", `Discovery router listening on port ${port}`);
|
|
49
|
+
const shutdown = () => { router.teardown().finally(() => process.exit(0)); };
|
|
50
|
+
process.on("SIGINT", shutdown);
|
|
51
|
+
process.on("SIGTERM", shutdown);
|
|
52
|
+
}
|
|
53
|
+
const scope = new GGLocatorScope("discovery-local", undefined, "discovery-local");
|
|
54
|
+
scope.run(main).catch((err) => {
|
|
55
|
+
GGLog.error("discovery-local", err);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=discovery-local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery-local.js","sourceRoot":"","sources":["../../../src/bin/discovery-local.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AACH,OAAO,EAAC,KAAK,EAAC,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAC,SAAS,EAAE,SAAS,EAAC,MAAM,eAAe,CAAC;AACnD,OAAO,EAAC,sBAAsB,EAAC,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAC,cAAc,EAAE,mBAAmB,EAAC,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAC,qBAAqB,EAAC,MAAM,iCAAiC,CAAC;AAEtE,KAAK,UAAU,IAAI;IACf,MAAM,IAAI,GAAG,qBAAqB,EAAE,CAAC;IAErC,IAAI,MAA0C,CAAC;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAI,sBAAsB,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC3F,IAAI,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;YAC1B,MAAM,GAAG,SAAS,CAAC;YACnB,MAAM;QACV,CAAC;aAAM,CAAC;YACJ,MAAM,CAAC,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC;gBACD,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,CAAC,CAAC,oBAAoB,CAAC,cAAc,CAAC,eAAe,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YACzF,CAAC;YAAC,MAAM,CAAC;gBACD,kCAAkC;YAC1C,CAAC;YACD,IAAI,CAAC;gBACD,CAAC,CAAC,UAAU,EAAE,CAAC;YACnB,CAAC;YAAC,MAAM,CAAC;gBACL,eAAe;YACnB,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,sCAAsC,IAAI,EAAE,CAAC,CAAC;YAC5E,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;IACL,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,KAAK,CAAC,KAAK,CAAC,iBAAiB,EAAE,uBAAuB,IAAI,qBAAqB,CAAC,CAAC;QACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,sCAAsC,IAAI,EAAE,CAAC,CAAC;IAE5E,MAAM,QAAQ,GAAG,GAAG,EAAE,GAAG,MAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,iBAAiB,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAClF,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC1B,KAAK,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
|
|
@@ -4,11 +4,19 @@ export interface DiscoverApiResult {
|
|
|
4
4
|
url?: string;
|
|
5
5
|
error?: string;
|
|
6
6
|
}
|
|
7
|
+
export declare enum DiscoveryServerKind {
|
|
8
|
+
Bin = "bin",
|
|
9
|
+
Embedded = "embedded"
|
|
10
|
+
}
|
|
7
11
|
export declare const GGDiscoveryIPC: {
|
|
8
12
|
discoveryServer: {
|
|
9
13
|
register: import("@grest-ts/ipc").IPCServerRequest<GGServiceDiscoveryEntry[], void>;
|
|
10
14
|
unregister: import("@grest-ts/ipc").IPCServerRequest<GGServiceDiscoveryEntry[], void>;
|
|
11
15
|
discoverApi: import("@grest-ts/ipc").IPCServerRequest<string, DiscoverApiResult>;
|
|
16
|
+
getServerInfo: import("@grest-ts/ipc").IPCServerRequest<undefined, {
|
|
17
|
+
kind: DiscoveryServerKind;
|
|
18
|
+
}>;
|
|
19
|
+
requestYield: import("@grest-ts/ipc").IPCServerRequest<undefined, void>;
|
|
12
20
|
};
|
|
13
21
|
};
|
|
14
22
|
//# sourceMappingURL=GGDiscoveryIPC.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGDiscoveryIPC.d.ts","sourceRoot":"","sources":["../../../src/local/GGDiscoveryIPC.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,uBAAuB,EAAC,MAAM,0BAA0B,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,cAAc;;;;;;
|
|
1
|
+
{"version":3,"file":"GGDiscoveryIPC.d.ts","sourceRoot":"","sources":["../../../src/local/GGDiscoveryIPC.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,uBAAuB,EAAC,MAAM,0BAA0B,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,oBAAY,mBAAmB;IAC3B,GAAG,QAAQ;IACX,QAAQ,aAAa;CACxB;AAED,eAAO,MAAM,cAAc;;;;;;kBAKsC,mBAAmB;;;;CAGnF,CAAA"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { IPCServer } from "@grest-ts/ipc";
|
|
2
|
+
export var DiscoveryServerKind;
|
|
3
|
+
(function (DiscoveryServerKind) {
|
|
4
|
+
DiscoveryServerKind["Bin"] = "bin";
|
|
5
|
+
DiscoveryServerKind["Embedded"] = "embedded";
|
|
6
|
+
})(DiscoveryServerKind || (DiscoveryServerKind = {}));
|
|
2
7
|
export const GGDiscoveryIPC = {
|
|
3
8
|
discoveryServer: {
|
|
4
9
|
register: IPCServer.defineRequest("discovery/register"),
|
|
5
10
|
unregister: IPCServer.defineRequest("discovery/unregister"),
|
|
6
11
|
discoverApi: IPCServer.defineRequest("discovery/discoverApi"),
|
|
12
|
+
getServerInfo: IPCServer.defineRequest("discovery/getServerInfo"),
|
|
13
|
+
requestYield: IPCServer.defineRequest("discovery/requestYield"),
|
|
7
14
|
}
|
|
8
15
|
};
|
|
9
16
|
//# sourceMappingURL=GGDiscoveryIPC.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGDiscoveryIPC.js","sourceRoot":"","sources":["../../../src/local/GGDiscoveryIPC.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,eAAe,CAAC;AAUxC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC1B,eAAe,EAAE;QACb,QAAQ,EAAE,SAAS,CAAC,aAAa,CAAkC,oBAAoB,CAAC;QACxF,UAAU,EAAE,SAAS,CAAC,aAAa,CAAkC,sBAAsB,CAAC;QAC5F,WAAW,EAAE,SAAS,CAAC,aAAa,CAA4B,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"GGDiscoveryIPC.js","sourceRoot":"","sources":["../../../src/local/GGDiscoveryIPC.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,eAAe,CAAC;AAUxC,MAAM,CAAN,IAAY,mBAGX;AAHD,WAAY,mBAAmB;IAC3B,kCAAW,CAAA;IACX,4CAAqB,CAAA;AACzB,CAAC,EAHW,mBAAmB,KAAnB,mBAAmB,QAG9B;AAED,MAAM,CAAC,MAAM,cAAc,GAAG;IAC1B,eAAe,EAAE;QACb,QAAQ,EAAE,SAAS,CAAC,aAAa,CAAkC,oBAAoB,CAAC;QACxF,UAAU,EAAE,SAAS,CAAC,aAAa,CAAkC,sBAAsB,CAAC;QAC5F,WAAW,EAAE,SAAS,CAAC,aAAa,CAA4B,uBAAuB,CAAC;QACxF,aAAa,EAAE,SAAS,CAAC,aAAa,CAAyC,yBAAyB,CAAC;QACzG,YAAY,EAAE,SAAS,CAAC,aAAa,CAAkB,wBAAwB,CAAC;KACnF;CACJ,CAAA"}
|
|
@@ -5,6 +5,9 @@ import { IPCClient } from "@grest-ts/ipc";
|
|
|
5
5
|
* If running in tests, the test itself also acts as a service discovery of sorts, allowing multiple instances to run in parallel.
|
|
6
6
|
*/
|
|
7
7
|
export declare const GG_LOCAL_ROUTER_PORT = "GG_LOCAL_ROUTER_PORT";
|
|
8
|
+
/** Default port for the local discovery router. Centralised so a future
|
|
9
|
+
* change (env-var override, per-environment isolation) has one hook. */
|
|
10
|
+
export declare function getLocalDiscoveryPort(): number;
|
|
8
11
|
export declare class GGLocalDiscoveryClient extends GGDiscoveryClient {
|
|
9
12
|
readonly isLocal = true;
|
|
10
13
|
readonly port: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGLocalDiscoveryClient.d.ts","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,iBAAiB,EAAE,qBAAqB,EAAC,MAAM,qBAAqB,CAAC;AAE3F,OAAO,EAAC,SAAS,EAAC,MAAM,eAAe,CAAC;AAKxC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,yBAAyB,CAAA;AAE1D,qBAAa,sBAAuB,SAAQ,iBAAiB;IAEzD,SAAyB,OAAO,QAAQ;IACxC,SAAgB,IAAI,SAAC;IACrB,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,EAAE,CAAM;IAC3D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;gBAEzB,IAAI,CAAC,EAAE,MAAM;IAgBlB,cAAc,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,IAAI;IAUtD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa7C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAQzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;cAWxB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"GGLocalDiscoveryClient.d.ts","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,iBAAiB,EAAE,qBAAqB,EAAC,MAAM,qBAAqB,CAAC;AAE3F,OAAO,EAAC,SAAS,EAAC,MAAM,eAAe,CAAC;AAKxC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,yBAAyB,CAAA;AAE1D;yEACyE;AACzE,wBAAgB,qBAAqB,IAAI,MAAM,CAQ9C;AAED,qBAAa,sBAAuB,SAAQ,iBAAiB;IAEzD,SAAyB,OAAO,QAAQ;IACxC,SAAgB,IAAI,SAAC;IACrB,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,EAAE,CAAM;IAC3D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;gBAEzB,IAAI,CAAC,EAAE,MAAM;IAgBlB,cAAc,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,IAAI;IAUtD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa7C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAQzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;cAWxB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;CAkBnD;AAWD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -9,6 +9,18 @@ import { SERVER_ERROR } from "@grest-ts/schema";
|
|
|
9
9
|
* If running in tests, the test itself also acts as a service discovery of sorts, allowing multiple instances to run in parallel.
|
|
10
10
|
*/
|
|
11
11
|
export const GG_LOCAL_ROUTER_PORT = "GG_LOCAL_ROUTER_PORT";
|
|
12
|
+
/** Default port for the local discovery router. Centralised so a future
|
|
13
|
+
* change (env-var override, per-environment isolation) has one hook. */
|
|
14
|
+
export function getLocalDiscoveryPort() {
|
|
15
|
+
const v = process.env[GG_LOCAL_ROUTER_PORT];
|
|
16
|
+
if (v === undefined)
|
|
17
|
+
return 9000;
|
|
18
|
+
const n = Number(v);
|
|
19
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
20
|
+
throw new Error(`Invalid ${GG_LOCAL_ROUTER_PORT}=${v}, expected positive integer`);
|
|
21
|
+
}
|
|
22
|
+
return n;
|
|
23
|
+
}
|
|
12
24
|
export class GGLocalDiscoveryClient extends GGDiscoveryClient {
|
|
13
25
|
isLocal = true;
|
|
14
26
|
port;
|
|
@@ -69,9 +81,33 @@ export class GGLocalDiscoveryClient extends GGDiscoveryClient {
|
|
|
69
81
|
this.client.disconnect();
|
|
70
82
|
}
|
|
71
83
|
async ensureConnected() {
|
|
72
|
-
if (
|
|
73
|
-
|
|
84
|
+
if (this.client.isConnected())
|
|
85
|
+
return;
|
|
86
|
+
// Retry with backoff: when the router runs as its own process
|
|
87
|
+
// (e.g. launched via the `discovery-local` bin), a runtime can
|
|
88
|
+
// come up before the router has bound its port. Tolerate that
|
|
89
|
+
// instead of failing the runtime's startup outright.
|
|
90
|
+
const maxRetries = 20;
|
|
91
|
+
for (let attempt = 0;; attempt++) {
|
|
92
|
+
try {
|
|
93
|
+
await this.client.connect();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
if (attempt >= maxRetries || !isConnectionError(err))
|
|
98
|
+
throw err;
|
|
99
|
+
GGLog.debug(this, "Waiting for discovery router...");
|
|
100
|
+
await new Promise(r => setTimeout(r, Math.min(500 * Math.pow(1.5, attempt), 5000)));
|
|
101
|
+
}
|
|
74
102
|
}
|
|
75
103
|
}
|
|
76
104
|
}
|
|
105
|
+
/** True for the transient socket errors seen while a router process is
|
|
106
|
+
* still coming up — worth retrying, unlike a real protocol failure. */
|
|
107
|
+
function isConnectionError(err) {
|
|
108
|
+
const codes = ["ECONNREFUSED", "ETIMEDOUT", "ECONNRESET", "ENOENT"];
|
|
109
|
+
const has = (code) => code !== undefined && codes.includes(code);
|
|
110
|
+
return has(err?.code) || has(err?.cause?.code)
|
|
111
|
+
|| has(err?.originalError?.code) || has(err?.originalError?.cause?.code);
|
|
112
|
+
}
|
|
77
113
|
//# sourceMappingURL=GGLocalDiscoveryClient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGLocalDiscoveryClient.js","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryClient.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"GGLocalDiscoveryClient.js","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,9 @@ export declare class GGLocalDiscoveryResilientClient extends GGLocalDiscoveryCli
|
|
|
3
3
|
private discoveryServer?;
|
|
4
4
|
private isLeader;
|
|
5
5
|
private isShuttingDown;
|
|
6
|
+
/** Once any bin has held the port in this runtime's lifetime, never
|
|
7
|
+
* bid for it again. In-memory only. */
|
|
8
|
+
private seenBinBasedMaster;
|
|
6
9
|
constructor(port?: number);
|
|
7
10
|
register(): Promise<void>;
|
|
8
11
|
unregister(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGLocalDiscoveryResilientClient.d.ts","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryResilientClient.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"GGLocalDiscoveryResilientClient.d.ts","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryResilientClient.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,sBAAsB,EAAwB,MAAM,0BAA0B,CAAC;AAGvF,qBAAa,+BAAgC,SAAQ,sBAAsB;IAEvE,OAAO,CAAC,eAAe,CAAC,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAAS;IAC/B;4CACwC;IACxC,OAAO,CAAC,kBAAkB,CAAS;gBAEvB,IAAI,SAA0B;IAIpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAOzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAUnC,sBAAsB;YAuBtB,eAAe;cAqCJ,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBzD,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,iBAAiB;CAQ5B"}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { GGLog } from "@grest-ts/logger";
|
|
2
2
|
import { IPCServer } from "@grest-ts/ipc";
|
|
3
3
|
import { GGLocalDiscoveryServer } from "./GGLocalDiscoveryServer.js";
|
|
4
|
-
import { GGLocalDiscoveryClient } from "./GGLocalDiscoveryClient.js";
|
|
4
|
+
import { GGLocalDiscoveryClient, getLocalDiscoveryPort } from "./GGLocalDiscoveryClient.js";
|
|
5
|
+
import { GGDiscoveryIPC, DiscoveryServerKind } from "./GGDiscoveryIPC.js";
|
|
5
6
|
export class GGLocalDiscoveryResilientClient extends GGLocalDiscoveryClient {
|
|
6
7
|
discoveryServer;
|
|
7
8
|
isLeader = false;
|
|
8
9
|
isShuttingDown = false;
|
|
9
|
-
|
|
10
|
+
/** Once any bin has held the port in this runtime's lifetime, never
|
|
11
|
+
* bid for it again. In-memory only. */
|
|
12
|
+
seenBinBasedMaster = false;
|
|
13
|
+
constructor(port = getLocalDiscoveryPort()) {
|
|
10
14
|
super(port);
|
|
11
15
|
}
|
|
12
16
|
async register() {
|
|
@@ -26,11 +30,19 @@ export class GGLocalDiscoveryResilientClient extends GGLocalDiscoveryClient {
|
|
|
26
30
|
async becomeLeaderOrFollower() {
|
|
27
31
|
if (this.isShuttingDown)
|
|
28
32
|
return;
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
if (this.seenBinBasedMaster)
|
|
34
|
+
return this.connectToLeader();
|
|
35
|
+
const router = new GGLocalDiscoveryServer(new IPCServer(this.port));
|
|
31
36
|
if (await router.start()) {
|
|
32
37
|
this.discoveryServer = router;
|
|
33
38
|
this.isLeader = true;
|
|
39
|
+
router.onYield = async () => {
|
|
40
|
+
GGLog.warn(this, "Yielding leadership to authoritative discovery (bin); will not bid for the port again in this runtime");
|
|
41
|
+
this.seenBinBasedMaster = true;
|
|
42
|
+
this.isLeader = false;
|
|
43
|
+
this.discoveryServer = undefined;
|
|
44
|
+
await this.connectToLeader();
|
|
45
|
+
};
|
|
34
46
|
GGLog.info(this, "This instance is LEADER");
|
|
35
47
|
}
|
|
36
48
|
else {
|
|
@@ -44,19 +56,31 @@ export class GGLocalDiscoveryResilientClient extends GGLocalDiscoveryClient {
|
|
|
44
56
|
return;
|
|
45
57
|
try {
|
|
46
58
|
await this.client.connect();
|
|
59
|
+
if (!this.seenBinBasedMaster) {
|
|
60
|
+
const info = await this.client.sendFrameworkRequest(GGDiscoveryIPC.discoveryServer.getServerInfo, undefined);
|
|
61
|
+
if (info.kind === DiscoveryServerKind.Bin) {
|
|
62
|
+
GGLog.warn(this, "Connected to authoritative discovery (bin); will not bid for the port in this runtime");
|
|
63
|
+
this.seenBinBasedMaster = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Re-publish entries on every successful connect — covers
|
|
67
|
+
// initial register, follower-on-leader-death, and post-yield
|
|
68
|
+
// reconnect uniformly. Server-side dedup on (clientId, api)
|
|
69
|
+
// makes this idempotent, so the wrapped register()'s own
|
|
70
|
+
// super.register() call is a harmless no-op.
|
|
71
|
+
if (this.entries.length > 0) {
|
|
72
|
+
await this.client.sendFrameworkRequest(GGDiscoveryIPC.discoveryServer.register, this.entries);
|
|
73
|
+
}
|
|
47
74
|
this.client.onClose(async () => {
|
|
48
75
|
if (this.isShuttingDown)
|
|
49
76
|
return;
|
|
50
77
|
GGLog.warn(this, "Leader died");
|
|
51
78
|
await this.becomeLeaderOrFollower();
|
|
52
|
-
if (this.isLeader && this.entries.length > 0) {
|
|
53
|
-
await super.register();
|
|
54
|
-
}
|
|
55
79
|
});
|
|
56
80
|
GGLog.debug(this, "Connected to leader");
|
|
57
81
|
}
|
|
58
82
|
catch (err) {
|
|
59
|
-
GGLog.error(this, `
|
|
83
|
+
GGLog.error(this, `Discovery router not reachable on port ${this.port} — is @grest-ts/discovery-local running? Will retry. (${err.message || err.code || err})`);
|
|
60
84
|
await this.delay(1000);
|
|
61
85
|
await this.connectToLeader();
|
|
62
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGLocalDiscoveryResilientClient.js","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryResilientClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAC,SAAS,EAAC,MAAM,eAAe,CAAC;AACxC,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"GGLocalDiscoveryResilientClient.js","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryResilientClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import { FirstStrategy } from "./routing/strategies/FirstStrategy";
|
|
|
4
4
|
import { LastStrategy } from "./routing/strategies/LastStrategy";
|
|
5
5
|
import { RandomStrategy } from "./routing/strategies/RandomStrategy";
|
|
6
6
|
import { RoundRobinStrategy } from "./routing/strategies/RoundRobinStrategy";
|
|
7
|
+
import { DiscoveryServerKind } from "./GGDiscoveryIPC";
|
|
7
8
|
import { GGServiceDiscoveryEntry } from "./GGLocalDiscoveryClient";
|
|
8
9
|
export declare const ROUTING_STRATEGIES: {
|
|
9
10
|
readonly first: FirstStrategy;
|
|
@@ -13,10 +14,12 @@ export declare const ROUTING_STRATEGIES: {
|
|
|
13
14
|
};
|
|
14
15
|
export type RoutingStrategyName = "first" | "last" | "roundRobin" | "random" | RoutingStrategy;
|
|
15
16
|
export declare class GGLocalDiscoveryServer {
|
|
17
|
+
readonly kind: DiscoveryServerKind;
|
|
16
18
|
private readonly server;
|
|
17
19
|
private readonly routes;
|
|
18
20
|
private readonly routingStrategies;
|
|
19
|
-
|
|
21
|
+
onYield?: () => Promise<void>;
|
|
22
|
+
constructor(server: IPCServer, kind?: DiscoveryServerKind);
|
|
20
23
|
start(): Promise<boolean>;
|
|
21
24
|
teardown(): Promise<void>;
|
|
22
25
|
setRoutingStrategy(api: string, strategy: RoutingStrategyName | RoutingStrategy): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGLocalDiscoveryServer.d.ts","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryServer.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAC,MAAM,eAAe,CAAC;AACxC,OAAO,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAC,aAAa,EAAC,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAC,YAAY,EAAC,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAC,cAAc,EAAC,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAC,kBAAkB,EAAC,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"GGLocalDiscoveryServer.d.ts","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryServer.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,SAAS,EAAC,MAAM,eAAe,CAAC;AACxC,OAAO,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAC,aAAa,EAAC,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAC,YAAY,EAAC,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAC,cAAc,EAAC,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAC,kBAAkB,EAAC,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAiB,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAC,uBAAuB,EAAC,MAAM,0BAA0B,CAAC;AAEjE,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG,QAAQ,GAAG,eAAe,CAAC;AAY/F,qBAAa,sBAAsB;aAOgB,IAAI,EAAE,mBAAmB;IALxE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6C;IACpE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2C;IACtE,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;gBAEzB,MAAM,EAAE,SAAS,EAAkB,IAAI,GAAE,mBAAkD;IAgD1F,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAQzB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,eAAe,GAAG,IAAI;IAM7F,OAAO,CAAC,kBAAkB;IAInB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS;IAS1D,QAAQ,CAAC,KAAK,EAAE,uBAAuB,GAAG,IAAI;IAerD;sEACkE;IAClE,OAAO,CAAC,oBAAoB;IAgBrB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAqBhD,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAUzC,OAAO,CAAC,UAAU;CAqBrB"}
|
|
@@ -3,7 +3,7 @@ import { FirstStrategy } from "./routing/strategies/FirstStrategy.js";
|
|
|
3
3
|
import { LastStrategy } from "./routing/strategies/LastStrategy.js";
|
|
4
4
|
import { RandomStrategy } from "./routing/strategies/RandomStrategy.js";
|
|
5
5
|
import { RoundRobinStrategy } from "./routing/strategies/RoundRobinStrategy.js";
|
|
6
|
-
import { GGDiscoveryIPC } from "./GGDiscoveryIPC.js";
|
|
6
|
+
import { GGDiscoveryIPC, DiscoveryServerKind } from "./GGDiscoveryIPC.js";
|
|
7
7
|
export const ROUTING_STRATEGIES = {
|
|
8
8
|
first: new FirstStrategy(),
|
|
9
9
|
last: new LastStrategy(),
|
|
@@ -11,10 +11,13 @@ export const ROUTING_STRATEGIES = {
|
|
|
11
11
|
roundRobin: new RoundRobinStrategy(),
|
|
12
12
|
};
|
|
13
13
|
export class GGLocalDiscoveryServer {
|
|
14
|
+
kind;
|
|
14
15
|
server;
|
|
15
16
|
routes = new Map();
|
|
16
17
|
routingStrategies = new Map();
|
|
17
|
-
|
|
18
|
+
onYield;
|
|
19
|
+
constructor(server, kind = DiscoveryServerKind.Embedded) {
|
|
20
|
+
this.kind = kind;
|
|
18
21
|
this.server = server;
|
|
19
22
|
// Socket handlers for framework communication
|
|
20
23
|
this.server.onFrameworkMessage(GGDiscoveryIPC.discoveryServer.register, async (routes, msg) => {
|
|
@@ -34,6 +37,15 @@ export class GGLocalDiscoveryServer {
|
|
|
34
37
|
}
|
|
35
38
|
return { success: false, error: "Service '" + apiName + "' is not registered! Did you forget to start it?" };
|
|
36
39
|
});
|
|
40
|
+
this.server.onFrameworkMessage(GGDiscoveryIPC.discoveryServer.getServerInfo, async () => ({ kind: this.kind }));
|
|
41
|
+
// Defer release so the ack flushes before we close the socket.
|
|
42
|
+
// onYield owners (e.g. resilient client) own teardown themselves.
|
|
43
|
+
this.server.onFrameworkMessage(GGDiscoveryIPC.discoveryServer.requestYield, async () => {
|
|
44
|
+
setTimeout(async () => {
|
|
45
|
+
await this.teardown();
|
|
46
|
+
await this.onYield?.();
|
|
47
|
+
}, 10);
|
|
48
|
+
});
|
|
37
49
|
this.server.setRouteProxyResolver((path) => {
|
|
38
50
|
return this.matchRoute(path)?.baseUrl || undefined;
|
|
39
51
|
});
|
|
@@ -76,8 +88,16 @@ export class GGLocalDiscoveryServer {
|
|
|
76
88
|
}
|
|
77
89
|
addRoute(route) {
|
|
78
90
|
const existing = this.routes.get(route.api) ?? [];
|
|
79
|
-
|
|
80
|
-
|
|
91
|
+
const stored = route;
|
|
92
|
+
// Dedup on (clientId, api) so a client re-registering its own
|
|
93
|
+
// route — e.g. on reconnect after a leader restart — replaces
|
|
94
|
+
// its previous entry instead of appending a duplicate. Routes
|
|
95
|
+
// from different clients (legitimate replicas) coexist.
|
|
96
|
+
const filtered = stored.clientId !== undefined
|
|
97
|
+
? existing.filter(r => r.clientId !== stored.clientId)
|
|
98
|
+
: existing;
|
|
99
|
+
filtered.push(stored);
|
|
100
|
+
this.routes.set(route.api, filtered);
|
|
81
101
|
GGLog.info(this, `Added route: ${route.pathPrefix} (${route.api}) -> ${route.baseUrl}`);
|
|
82
102
|
}
|
|
83
103
|
/** Drop every route registered by a given IPC client. Routes added
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGLocalDiscoveryServer.js","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,kBAAkB,CAAC;AAGvC,OAAO,EAAC,aAAa,EAAC,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAC,YAAY,EAAC,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAC,cAAc,EAAC,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAC,kBAAkB,EAAC,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"GGLocalDiscoveryServer.js","sourceRoot":"","sources":["../../../src/local/GGLocalDiscoveryServer.ts"],"names":[],"mappings":"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"}
|