@lensmcp/cluster 1.11.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/executors/gateway/gateway-errors.d.ts +36 -0
- package/executors/gateway/gateway-errors.d.ts.map +1 -0
- package/executors/gateway/gateway-errors.js +43 -0
- package/executors/gateway/gateway.lib.d.ts +15 -167
- package/executors/gateway/gateway.lib.d.ts.map +1 -1
- package/executors/gateway/gateway.lib.js +24 -1034
- package/executors/gateway/main.prod-gateway.js +74 -2
- package/executors/gateway/prod-gateway.lib.d.ts +19 -143
- package/executors/gateway/prod-gateway.lib.d.ts.map +1 -1
- package/executors/gateway/prod-gateway.lib.js +16 -831
- package/executors/gateway/prod-runtime/access-log.d.ts +9 -0
- package/executors/gateway/prod-runtime/access-log.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/access-log.js +24 -0
- package/executors/gateway/prod-runtime/app.d.ts +23 -0
- package/executors/gateway/prod-runtime/app.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/app.js +123 -0
- package/executors/gateway/prod-runtime/auth.d.ts +30 -0
- package/executors/gateway/prod-runtime/auth.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/auth.js +51 -0
- package/executors/gateway/prod-runtime/cors.d.ts +19 -0
- package/executors/gateway/prod-runtime/cors.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/cors.js +40 -0
- package/executors/gateway/prod-runtime/edge.d.ts +16 -0
- package/executors/gateway/prod-runtime/edge.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/edge.js +65 -0
- package/executors/gateway/prod-runtime/handler.d.ts +32 -0
- package/executors/gateway/prod-runtime/handler.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/handler.js +226 -0
- package/executors/gateway/prod-runtime/hooks.d.ts +20 -0
- package/executors/gateway/prod-runtime/hooks.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/hooks.js +42 -0
- package/executors/gateway/prod-runtime/observability.d.ts +23 -0
- package/executors/gateway/prod-runtime/observability.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/observability.js +125 -0
- package/executors/gateway/prod-runtime/rollout.d.ts +18 -0
- package/executors/gateway/prod-runtime/rollout.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/rollout.js +103 -0
- package/executors/gateway/prod-runtime/routing.d.ts +4 -0
- package/executors/gateway/prod-runtime/routing.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/routing.js +40 -0
- package/executors/gateway/prod-runtime/server.d.ts +3 -0
- package/executors/gateway/prod-runtime/server.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/server.js +79 -0
- package/executors/gateway/prod-runtime/trust.d.ts +12 -0
- package/executors/gateway/prod-runtime/trust.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/trust.js +32 -0
- package/executors/gateway/prod-runtime/types.d.ts +241 -0
- package/executors/gateway/prod-runtime/types.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/types.js +2 -0
- package/executors/gateway/prod-runtime/upgrade.d.ts +21 -0
- package/executors/gateway/prod-runtime/upgrade.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/upgrade.js +116 -0
- package/executors/gateway/prod-runtime/upstream.d.ts +13 -0
- package/executors/gateway/prod-runtime/upstream.d.ts.map +1 -0
- package/executors/gateway/prod-runtime/upstream.js +21 -0
- package/executors/gateway/runtime/auth.d.ts +8 -0
- package/executors/gateway/runtime/auth.d.ts.map +1 -0
- package/executors/gateway/runtime/auth.js +60 -0
- package/executors/gateway/runtime/dev-auth.d.ts +9 -0
- package/executors/gateway/runtime/dev-auth.d.ts.map +1 -0
- package/executors/gateway/runtime/dev-auth.js +79 -0
- package/executors/gateway/runtime/discovery.d.ts +17 -0
- package/executors/gateway/runtime/discovery.d.ts.map +1 -0
- package/executors/gateway/runtime/discovery.js +111 -0
- package/executors/gateway/runtime/edge.d.ts +31 -0
- package/executors/gateway/runtime/edge.d.ts.map +1 -0
- package/executors/gateway/runtime/edge.js +47 -0
- package/executors/gateway/runtime/handler.d.ts +24 -0
- package/executors/gateway/runtime/handler.d.ts.map +1 -0
- package/executors/gateway/runtime/handler.js +165 -0
- package/executors/gateway/runtime/hooks.d.ts +23 -0
- package/executors/gateway/runtime/hooks.d.ts.map +1 -0
- package/executors/gateway/runtime/hooks.js +55 -0
- package/executors/gateway/runtime/lens-children.d.ts +13 -0
- package/executors/gateway/runtime/lens-children.d.ts.map +1 -0
- package/executors/gateway/runtime/lens-children.js +136 -0
- package/executors/gateway/runtime/lifecycle.d.ts +13 -0
- package/executors/gateway/runtime/lifecycle.d.ts.map +1 -0
- package/executors/gateway/runtime/lifecycle.js +179 -0
- package/executors/gateway/runtime/observability.d.ts +17 -0
- package/executors/gateway/runtime/observability.d.ts.map +1 -0
- package/executors/gateway/runtime/observability.js +107 -0
- package/executors/gateway/runtime/proxy.d.ts +20 -0
- package/executors/gateway/runtime/proxy.d.ts.map +1 -0
- package/executors/gateway/runtime/proxy.js +113 -0
- package/executors/gateway/runtime/scope.d.ts +16 -0
- package/executors/gateway/runtime/scope.d.ts.map +1 -0
- package/executors/gateway/runtime/scope.js +68 -0
- package/executors/gateway/runtime/server.d.ts +3 -0
- package/executors/gateway/runtime/server.d.ts.map +1 -0
- package/executors/gateway/runtime/server.js +168 -0
- package/executors/gateway/runtime/service-keys.d.ts +11 -0
- package/executors/gateway/runtime/service-keys.d.ts.map +1 -0
- package/executors/gateway/runtime/service-keys.js +49 -0
- package/executors/gateway/runtime/types.d.ts +234 -0
- package/executors/gateway/runtime/types.d.ts.map +1 -0
- package/executors/gateway/runtime/types.js +2 -0
- package/executors/gateway/runtime/upgrade.d.ts +22 -0
- package/executors/gateway/runtime/upgrade.d.ts.map +1 -0
- package/executors/gateway/runtime/upgrade.js +63 -0
- package/package.json +3 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
3
4
|
/**
|
|
4
5
|
* Production gateway process entry — the thing the Docker image runs. Reads
|
|
5
6
|
* its whole configuration from the environment (12-factor) and composes
|
|
@@ -8,6 +9,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
8
9
|
*
|
|
9
10
|
* Env:
|
|
10
11
|
* LENSMCP_GW_PORTS csv of ports (default "8080", or "8443" with TLS)
|
|
12
|
+
* LENSMCP_GW_WORKERS cluster worker processes for multi-core (default 1; "auto"/"max" =
|
|
13
|
+
* os.cpus().length). Each worker shares the port. SECURITY: with the
|
|
14
|
+
* IN-MEMORY rate limiter the limit is enforced PER WORKER (~N×) — set
|
|
15
|
+
* LENSMCP_GW_RATE_LIMIT_REDIS=1 (one shared budget) when running >1 worker.
|
|
11
16
|
* LENSMCP_GW_MANIFESTS path to a manifests JSON file (array or {manifests:[]})
|
|
12
17
|
* LENSMCP_GW_ENDPOINTS path to an endpoints JSON for gateway-side LB / rollout
|
|
13
18
|
* (only needed for services whose manifest has no `upstream`).
|
|
@@ -52,8 +57,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
52
57
|
* proxy (set `cf-connecting-ip` behind Cloudflare; feeds IP-based ABAC)
|
|
53
58
|
* LENSMCP_GW_CLIENT_IP_TRUSTED_PROXIES csv of CIDRs allowed to set that header
|
|
54
59
|
* (default loopback only — prevents off-proxy IP spoofing)
|
|
55
|
-
* LENSMCP_GW_UNDICI_CONNECTIONS per-origin connection pool size (default 256
|
|
60
|
+
* LENSMCP_GW_UNDICI_CONNECTIONS per-origin connection pool size (default 256; RIGHT-SIZE to the
|
|
61
|
+
* upstream latency — fewer is faster for a fast/local upstream)
|
|
56
62
|
* LENSMCP_GW_UNDICI_BODY_TIMEOUT_MS undici response-body timeout; default 0 = unlimited
|
|
63
|
+
* LENSMCP_GW_UNDICI_PIPELINING requests packed per upstream connection (default 1; >1 lifts
|
|
64
|
+
* throughput on uniformly-fast upstreams but risks head-of-line
|
|
65
|
+
* blocking on streaming responses — leave 1 for mixed traffic)
|
|
66
|
+
* LENSMCP_GW_UNDICI_HEADERS_TIMEOUT_MS upstream response-headers timeout (default 60000)
|
|
67
|
+
* LENSMCP_GW_UNDICI_KEEPALIVE_MS undici per-origin keep-alive timeout (default 60000)
|
|
57
68
|
* (keeps long-lived SSE / streaming MCP responses open)
|
|
58
69
|
* LENSMCP_GW_KEEPALIVE_MS server keep-alive timeout; default 620000, kept ABOVE the GCP
|
|
59
70
|
* external ALB's 600s backend keep-alive (avoids intermittent 502s)
|
|
@@ -92,6 +103,7 @@ const node_fs_1 = require("node:fs");
|
|
|
92
103
|
const node_crypto_1 = require("node:crypto");
|
|
93
104
|
const node_path_1 = require("node:path");
|
|
94
105
|
const node_os_1 = require("node:os");
|
|
106
|
+
const node_cluster_1 = tslib_1.__importDefault(require("node:cluster"));
|
|
95
107
|
const prod_gateway_lib_1 = require("./prod-gateway.lib");
|
|
96
108
|
const jwks_verify_1 = require("./jwks-verify");
|
|
97
109
|
const otel_tracing_1 = require("./otel-tracing");
|
|
@@ -325,6 +337,15 @@ async function main() {
|
|
|
325
337
|
undici.connections = Number(env['LENSMCP_GW_UNDICI_CONNECTIONS']);
|
|
326
338
|
if (env['LENSMCP_GW_UNDICI_BODY_TIMEOUT_MS'])
|
|
327
339
|
undici.bodyTimeout = Number(env['LENSMCP_GW_UNDICI_BODY_TIMEOUT_MS']);
|
|
340
|
+
// Pipelining > 1 packs more requests per upstream connection (higher throughput on fast upstreams) but
|
|
341
|
+
// risks head-of-line blocking — a slow/streaming response stalls the requests queued behind it on that
|
|
342
|
+
// connection. Default 1 (safe for mixed/streaming traffic); raise only for uniformly-fast upstreams.
|
|
343
|
+
if (env['LENSMCP_GW_UNDICI_PIPELINING'])
|
|
344
|
+
undici.pipelining = Number(env['LENSMCP_GW_UNDICI_PIPELINING']);
|
|
345
|
+
if (env['LENSMCP_GW_UNDICI_HEADERS_TIMEOUT_MS'])
|
|
346
|
+
undici.headersTimeout = Number(env['LENSMCP_GW_UNDICI_HEADERS_TIMEOUT_MS']);
|
|
347
|
+
if (env['LENSMCP_GW_UNDICI_KEEPALIVE_MS'])
|
|
348
|
+
undici.keepAliveTimeout = Number(env['LENSMCP_GW_UNDICI_KEEPALIVE_MS']);
|
|
328
349
|
// ── mTLS client materials (optional): from the shared registry Redis, or files ──
|
|
329
350
|
if (env['LENSMCP_GW_MTLS_FROM_REDIS'] === '1' && redisClient) {
|
|
330
351
|
const p = env['LENSMCP_GW_REDIS_PREFIX'] ?? 'lensmcp:gw';
|
|
@@ -498,4 +519,55 @@ async function main() {
|
|
|
498
519
|
for (const sig of ['SIGTERM', 'SIGINT'])
|
|
499
520
|
process.on(sig, () => void shutdown(sig));
|
|
500
521
|
}
|
|
501
|
-
|
|
522
|
+
// ── Multi-core (opt-in via LENSMCP_GW_WORKERS) ──────────────────────────────
|
|
523
|
+
// A single Node process is ONE thread; a high-RPS edge should use every core. `LENSMCP_GW_WORKERS`
|
|
524
|
+
// forks N worker processes (default 1; `auto`/`max`/`0` ⇒ os.cpus().length). The PRIMARY only supervises
|
|
525
|
+
// — fork, respawn on crash, propagate SIGTERM — while each WORKER runs the full gateway and shares the
|
|
526
|
+
// listening port via Node's cluster module (connections round-robin across workers), so throughput scales
|
|
527
|
+
// ~linearly with cores. NB: state is per-worker — use the Redis rate limiter + Redis status fan-out for
|
|
528
|
+
// cross-worker consistency; a stateless route-and-forward proxy needs nothing extra.
|
|
529
|
+
function workerCount() {
|
|
530
|
+
const v = (process.env['LENSMCP_GW_WORKERS'] ?? '1').trim().toLowerCase();
|
|
531
|
+
if (v === 'auto' || v === 'max' || v === '0')
|
|
532
|
+
return Math.max(1, (0, node_os_1.cpus)().length);
|
|
533
|
+
const n = Math.floor(Number(v));
|
|
534
|
+
return Number.isFinite(n) && n > 0 ? n : 1;
|
|
535
|
+
}
|
|
536
|
+
const WORKERS = workerCount();
|
|
537
|
+
if (WORKERS > 1 && node_cluster_1.default.isPrimary) {
|
|
538
|
+
console.log(`[gateway] primary ${process.pid}: forking ${WORKERS} workers (one per core)…`);
|
|
539
|
+
// SECURITY: the in-memory rate limiter holds per-PROCESS buckets, so with N workers the effective
|
|
540
|
+
// global limit is ~N× the configured value (abuse/DoS protection is weakened). Use the Redis-backed
|
|
541
|
+
// limiter (one shared budget across workers) when running multi-core, or divide the per-worker limit.
|
|
542
|
+
if (process.env['LENSMCP_GW_RATE_LIMIT'] && !(process.env['LENSMCP_GW_RATE_LIMIT_REDIS'] === '1' || process.env['LENSMCP_GW_RATE_LIMIT_REDIS_URL'])) {
|
|
543
|
+
console.warn(`[gateway] WARNING: in-memory rate limiter + ${WORKERS} workers → the limit is enforced PER WORKER (effective ≈ ${WORKERS}× ${process.env['LENSMCP_GW_RATE_LIMIT']}/window). Set LENSMCP_GW_RATE_LIMIT_REDIS=1 for one shared global budget, or divide LENSMCP_GW_RATE_LIMIT by ${WORKERS}.`);
|
|
544
|
+
}
|
|
545
|
+
let stopping = false;
|
|
546
|
+
for (let i = 0; i < WORKERS; i++)
|
|
547
|
+
node_cluster_1.default.fork();
|
|
548
|
+
node_cluster_1.default.on('exit', (w, code, sig) => {
|
|
549
|
+
if (stopping)
|
|
550
|
+
return;
|
|
551
|
+
console.warn(`[gateway] worker ${w.process.pid} exited (code=${code} sig=${sig ?? ''}) — respawning.`);
|
|
552
|
+
node_cluster_1.default.fork();
|
|
553
|
+
});
|
|
554
|
+
const stopAll = (sig) => {
|
|
555
|
+
if (stopping)
|
|
556
|
+
return;
|
|
557
|
+
stopping = true;
|
|
558
|
+
console.log(`[gateway] primary: ${sig} — stopping ${Object.keys(node_cluster_1.default.workers ?? {}).length} workers…`);
|
|
559
|
+
for (const w of Object.values(node_cluster_1.default.workers ?? {})) {
|
|
560
|
+
try {
|
|
561
|
+
w?.kill(sig);
|
|
562
|
+
}
|
|
563
|
+
catch { /* gone */ }
|
|
564
|
+
}
|
|
565
|
+
setTimeout(() => process.exit(0), 12_000).unref(); // hard cap after workers drain
|
|
566
|
+
};
|
|
567
|
+
process.on('SIGTERM', () => stopAll('SIGTERM'));
|
|
568
|
+
process.on('SIGINT', () => stopAll('SIGINT'));
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
// Worker (or single-process default): run the full gateway.
|
|
572
|
+
void main();
|
|
573
|
+
}
|
|
@@ -1,144 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
export interface ProdGatewayOptions {
|
|
21
|
-
/** Ports to bind. Default `[8080]` (or `[8443]` with TLS). One Fastify
|
|
22
|
-
* instance per port; all share the route table + providers. */
|
|
23
|
-
ports?: number[];
|
|
24
|
-
manifests: ManifestProvider;
|
|
25
|
-
/** Resolves a service → upstream when a route has no direct `upstream`. */
|
|
26
|
-
pods?: PodProvider;
|
|
27
|
-
/** service → its `x-internal-token` (from a k8s Secret / Vault in prod). */
|
|
28
|
-
serviceKeys?: Record<string, string>;
|
|
29
|
-
/** Validate a `jwt`-mode request; THROW to reject (→ 401). Default: a
|
|
30
|
-
* pass-through with a one-time warning — wire a real JWKS validator in prod. */
|
|
31
|
-
authenticate?: (mode: AuthMode, req: http.IncomingMessage) => void;
|
|
32
|
-
tls?: {
|
|
33
|
-
key: string | Buffer;
|
|
34
|
-
cert: string | Buffer;
|
|
35
|
-
};
|
|
36
|
-
/** Lens bus sink — OPT-IN. Omit (default) for zero observability overhead. */
|
|
37
|
-
emit?: (event: Record<string, unknown>) => void;
|
|
38
|
-
/** Traffic-edge flush period (ms). Default 5000. */
|
|
39
|
-
trafficFlushMs?: number;
|
|
40
|
-
/** Request header that PINS a rollout cohort (sticky canary / debugging).
|
|
41
|
-
* Default `x-lensmcp-version`. The chosen version is echoed on the response. */
|
|
42
|
-
versionHeader?: string;
|
|
43
|
-
/** undici pool tuning passed to reply-from. `bodyTimeout: 0` (default) keeps
|
|
44
|
-
* long-lived SSE / streamable-HTTP MCP responses open — undici's 300s default
|
|
45
|
-
* would otherwise abort an idle stream. `rejectUnauthorized` defaults false
|
|
46
|
-
* (local-CA / self-signed upstreams); set true for verified east-west on GCP.
|
|
47
|
-
* `allowH2` multiplexes many concurrent streams over few HTTP/2 connections
|
|
48
|
-
* (Cloud Run supports h2 end-to-end) — useful when one upstream fans many MCP streams.
|
|
49
|
-
* `cert`/`key` present a client certificate to upstreams (mTLS); `ca` trusts a
|
|
50
|
-
* private CA for the server side. `rejectUnauthorized:false` keeps mTLS while
|
|
51
|
-
* skipping server-cert validation (self-signed internal services). */
|
|
52
|
-
undici?: {
|
|
53
|
-
connections?: number;
|
|
54
|
-
pipelining?: number;
|
|
55
|
-
keepAliveTimeout?: number;
|
|
56
|
-
bodyTimeout?: number;
|
|
57
|
-
headersTimeout?: number;
|
|
58
|
-
rejectUnauthorized?: boolean;
|
|
59
|
-
allowH2?: boolean;
|
|
60
|
-
cert?: string | Buffer;
|
|
61
|
-
key?: string | Buffer;
|
|
62
|
-
ca?: string | Buffer;
|
|
63
|
-
};
|
|
64
|
-
/** Header carrying the AUTHORITATIVE client IP from a trusted front proxy
|
|
65
|
-
* (e.g. `cf-connecting-ip` behind Cloudflare). When set, the `ip` ABAC
|
|
66
|
-
* attribute comes from this header instead of the (multi-proxy, spoofable)
|
|
67
|
-
* X-Forwarded-For chain. Safe only when the origin is locked to that proxy —
|
|
68
|
-
* which Cloudflare Tunnel guarantees (there is no public origin to bypass). */
|
|
69
|
-
clientIpHeader?: string;
|
|
70
|
-
/** CIDRs of trusted front proxies. `clientIpHeader` is honored ONLY when the
|
|
71
|
-
* immediate peer (socket address) is in this set — otherwise the header is
|
|
72
|
-
* ignored and the socket IP is used (prevents spoofing the `ip` ABAC attribute
|
|
73
|
-
* by hitting the origin directly). Default when omitted: loopback only
|
|
74
|
-
* (matches a co-located cloudflared/sidecar). */
|
|
75
|
-
clientIpTrustedProxies?: string[];
|
|
76
|
-
/** OpenTelemetry tracer (from `setupTracing`). When set, each request gets a
|
|
77
|
-
* SERVER span whose context is propagated downstream (W3C `traceparent`), so
|
|
78
|
-
* the gateway hop stitches into the distributed trace. Omit → no span work. */
|
|
79
|
-
tracing?: GatewayTracer;
|
|
80
|
-
/** Expose `GET /statusz` — the per-service health rollup as JSON. Requires
|
|
81
|
-
* `statusToken` too (fail-closed: served only when both are set). Default off (404). */
|
|
82
|
-
statusEndpoint?: boolean;
|
|
83
|
-
/** Token `/statusz` requires (via `?token=` or `x-status-token`), compared in
|
|
84
|
-
* constant time. REQUIRED for the endpoint to serve — no token → /statusz is 404. */
|
|
85
|
-
statusToken?: string;
|
|
86
|
-
/** How many flush windows the rolling status sums over (default 12 → ~60s at the 5s flush). */
|
|
87
|
-
statusWindows?: number;
|
|
88
|
-
/** Called each flush window with the per-service status snapshot — wire it to a
|
|
89
|
-
* Redis `status:*` fan-out / status page. The gateway is the only thing that
|
|
90
|
-
* sees every request, so this is the natural source of observed health. */
|
|
91
|
-
onStatus?: (snapshot: ServiceStatus[]) => void;
|
|
92
|
-
/** Active upstream health-checker (from `createHealthChecker`). When set, the
|
|
93
|
-
* gateway probes upstreams, steers pooled picks toward healthy endpoints, and
|
|
94
|
-
* reflects true liveness in /statusz. Omit → passive drop-on-error only. */
|
|
95
|
-
healthChecker?: HealthChecker;
|
|
96
|
-
/** Opt-in per-client-IP rate limiter — defense-in-depth behind the edge throttle.
|
|
97
|
-
* In-memory + per-instance (`createRateLimiter`) or ONE global budget across all
|
|
98
|
-
* containers (`createRedisRateLimiter`). The check is `await`ed either way; it
|
|
99
|
-
* runs before routing/auth and applies only to proxied traffic (ops endpoints exempt). */
|
|
100
|
-
rateLimiter?: RateLimiter;
|
|
101
|
-
/** Process self-metrics (event-loop lag / rss / cpu / req rates) from `createProcessMetrics`;
|
|
102
|
-
* exposed at the token-gated `/metricsz` for load/stress tests + production monitoring. */
|
|
103
|
-
metrics?: ProcessMetrics;
|
|
104
|
-
/** Server-side HTTP timeouts (ms). `keepAliveTimeout` default 620000 — kept
|
|
105
|
-
* ABOVE the GCP external ALB's 600s backend keep-alive so the gateway never
|
|
106
|
-
* closes a pooled connection the LB still considers live (the classic
|
|
107
|
-
* intermittent-502 race). `requestTimeout` default 0 (disabled) for streaming. */
|
|
108
|
-
server?: {
|
|
109
|
-
keepAliveTimeout?: number;
|
|
110
|
-
requestTimeout?: number;
|
|
111
|
-
connectionTimeout?: number;
|
|
112
|
-
headersTimeout?: number;
|
|
113
|
-
};
|
|
114
|
-
/** Opt-in one-JSON-line-per-request access log to stdout, shaped for Cloud
|
|
115
|
-
* Logging (severity + time + message). Default off (zero overhead). */
|
|
116
|
-
accessLog?: boolean;
|
|
117
|
-
/** Return verified subject attributes (e.g. JWT claims) for ABAC routing.
|
|
118
|
-
* MUST verify (signature/exp) — forged claims must not reach the rules. */
|
|
119
|
-
identify?: (req: http.IncomingMessage) => Record<string, unknown> | undefined;
|
|
120
|
-
/** Allowlist of request headers exposed to rules as `header.<name>` attributes. */
|
|
121
|
-
attributeHeaders?: string[];
|
|
122
|
-
/** Take the `ip` attribute from `X-Forwarded-For` (behind a trusted LB) via
|
|
123
|
-
* Fastify `trustProxy`; default false → socket IP. */
|
|
124
|
-
trustProxyIp?: boolean;
|
|
125
|
-
/** Gateway-issued device cookie for sticky bucketing (anonymous-friendly).
|
|
126
|
-
* Omit to disable cookie stickiness. `secret` enables HMAC signing. */
|
|
127
|
-
cookie?: {
|
|
128
|
-
name?: string;
|
|
129
|
-
secret?: string;
|
|
130
|
-
domain?: string;
|
|
131
|
-
maxAge?: number;
|
|
132
|
-
};
|
|
133
|
-
/** Header carrying a client device/user id — the sticky key when no cookie
|
|
134
|
-
* is present (native/mobile/API clients), e.g. `x-device-id`. */
|
|
135
|
-
uidHeader?: string;
|
|
136
|
-
}
|
|
137
|
-
export interface ProdGatewayHandle {
|
|
138
|
-
ports: number[];
|
|
139
|
-
routes: () => Route[];
|
|
140
|
-
status: () => ServiceStatus[];
|
|
141
|
-
stop: () => Promise<void>;
|
|
142
|
-
}
|
|
143
|
-
export declare function startProdGateway(opts: ProdGatewayOptions): Promise<ProdGatewayHandle>;
|
|
1
|
+
/**
|
|
2
|
+
* Public facade for the PRODUCTION gateway runtime (Fastify + @fastify/reply-from).
|
|
3
|
+
*
|
|
4
|
+
* The implementation now lives in `./prod-runtime/*` as composable LAYERS,
|
|
5
|
+
* mirroring the dev gateway's `./runtime/*` — see `prod-runtime/server.ts` for the
|
|
6
|
+
* composition root (`startProdGateway`), `prod-runtime/types.ts` for the shared
|
|
7
|
+
* types + the customer **hooks** API, and the sibling modules for each layer
|
|
8
|
+
* (routing, observability, rollout, upstream, auth, cors, trust, handler, upgrade,
|
|
9
|
+
* app, access-log, hooks). This barrel preserves the original module's public
|
|
10
|
+
* surface so the entry (`main.prod-gateway.ts`), the `@lensmcp/cluster` re-export
|
|
11
|
+
* (`gateway.ts`), the e2e suite, and the pentest/perf suites import from one stable
|
|
12
|
+
* path, and additionally exposes the hooks types for customer-authored layers.
|
|
13
|
+
*
|
|
14
|
+
* The same routing brain as dev (shared `matchRoute` / `buildRouteTable` / manifest
|
|
15
|
+
* schema); the HTTP transport differs on purpose (dev: node:http + http-proxy over
|
|
16
|
+
* unix-socket pods; prod: Fastify + reply-from's undici pool for the high-RPS edge).
|
|
17
|
+
*/
|
|
18
|
+
export { startProdGateway } from './prod-runtime/server';
|
|
19
|
+
export type { ServiceStatus, ProdGatewayOptions, ProdGatewayHandle, ProdGatewayHooks, ProdGatewayPhase, ProdHookHandler, ProdHookContext, } from './prod-runtime/types';
|
|
144
20
|
//# sourceMappingURL=prod-gateway.lib.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prod-gateway.lib.d.ts","sourceRoot":"","sources":["../../../../../libs/cluster/src/executors/gateway/prod-gateway.lib.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prod-gateway.lib.d.ts","sourceRoot":"","sources":["../../../../../libs/cluster/src/executors/gateway/prod-gateway.lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EAEjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
|