threadforge 0.1.1 → 0.2.2
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 +69 -42
- package/bin/forge.js +2 -1058
- package/bin/host-commands.d.ts +2 -0
- package/bin/host-commands.d.ts.map +1 -0
- package/bin/host-commands.js +7 -8
- package/bin/platform-commands.d.ts +2 -0
- package/bin/platform-commands.d.ts.map +1 -0
- package/bin/platform-commands.js +118 -36
- package/dist/cli/base-command.d.ts +12 -0
- package/dist/cli/base-command.d.ts.map +1 -0
- package/dist/cli/base-command.js +25 -0
- package/dist/cli/base-command.js.map +1 -0
- package/dist/cli/commands/build.d.ts +10 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +110 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/deploy.d.ts +12 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -0
- package/dist/cli/commands/deploy.js +143 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +10 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +138 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +10 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +76 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/host.d.ts +8 -0
- package/dist/cli/commands/host.d.ts.map +1 -0
- package/dist/cli/commands/host.js +20 -0
- package/dist/cli/commands/host.js.map +1 -0
- package/dist/cli/commands/init.d.ts +16 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +246 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/platform.d.ts +8 -0
- package/dist/cli/commands/platform.d.ts.map +1 -0
- package/dist/cli/commands/platform.js +20 -0
- package/dist/cli/commands/platform.js.map +1 -0
- package/dist/cli/commands/restart.d.ts +8 -0
- package/dist/cli/commands/restart.d.ts.map +1 -0
- package/dist/cli/commands/restart.js +13 -0
- package/dist/cli/commands/restart.js.map +1 -0
- package/dist/cli/commands/scaffold/frontend.d.ts +10 -0
- package/dist/cli/commands/scaffold/frontend.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/frontend.js +130 -0
- package/dist/cli/commands/scaffold/frontend.js.map +1 -0
- package/dist/cli/commands/scaffold/react.d.ts +7 -0
- package/dist/cli/commands/scaffold/react.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/react.js +12 -0
- package/dist/cli/commands/scaffold/react.js.map +1 -0
- package/dist/cli/commands/scale.d.ts +8 -0
- package/dist/cli/commands/scale.d.ts.map +1 -0
- package/dist/cli/commands/scale.js +13 -0
- package/dist/cli/commands/scale.js.map +1 -0
- package/dist/cli/commands/start.d.ts +10 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +71 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +11 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +60 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +10 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +89 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/util/config-discovery.d.ts +8 -0
- package/dist/cli/util/config-discovery.d.ts.map +1 -0
- package/dist/cli/util/config-discovery.js +70 -0
- package/dist/cli/util/config-discovery.js.map +1 -0
- package/dist/cli/util/config-patcher.d.ts +17 -0
- package/dist/cli/util/config-patcher.d.ts.map +1 -0
- package/dist/cli/util/config-patcher.js +439 -0
- package/dist/cli/util/config-patcher.js.map +1 -0
- package/dist/cli/util/frontend-dev.d.ts +8 -0
- package/dist/cli/util/frontend-dev.d.ts.map +1 -0
- package/dist/cli/util/frontend-dev.js +117 -0
- package/dist/cli/util/frontend-dev.js.map +1 -0
- package/dist/cli/util/process.d.ts +5 -0
- package/dist/cli/util/process.d.ts.map +1 -0
- package/dist/cli/util/process.js +17 -0
- package/dist/cli/util/process.js.map +1 -0
- package/dist/cli/util/templates.d.ts +10 -0
- package/dist/cli/util/templates.d.ts.map +1 -0
- package/dist/cli/util/templates.js +157 -0
- package/dist/cli/util/templates.js.map +1 -0
- package/dist/core/AlertSink.d.ts +83 -0
- package/dist/core/AlertSink.d.ts.map +1 -0
- package/dist/core/AlertSink.js +126 -0
- package/dist/core/AlertSink.js.map +1 -0
- package/dist/core/DirectMessageBus.d.ts +88 -0
- package/dist/core/DirectMessageBus.d.ts.map +1 -0
- package/dist/core/DirectMessageBus.js +352 -0
- package/dist/core/DirectMessageBus.js.map +1 -0
- package/dist/core/EndpointResolver.d.ts +111 -0
- package/dist/core/EndpointResolver.d.ts.map +1 -0
- package/dist/core/EndpointResolver.js +336 -0
- package/dist/core/EndpointResolver.js.map +1 -0
- package/dist/core/ForgeContext.d.ts +221 -0
- package/dist/core/ForgeContext.d.ts.map +1 -0
- package/dist/core/ForgeContext.js +1169 -0
- package/dist/core/ForgeContext.js.map +1 -0
- package/dist/core/ForgeEndpoints.d.ts +71 -0
- package/dist/core/ForgeEndpoints.d.ts.map +1 -0
- package/dist/core/ForgeEndpoints.js +442 -0
- package/dist/core/ForgeEndpoints.js.map +1 -0
- package/dist/core/ForgeHost.d.ts +82 -0
- package/dist/core/ForgeHost.d.ts.map +1 -0
- package/dist/core/ForgeHost.js +107 -0
- package/dist/core/ForgeHost.js.map +1 -0
- package/dist/core/ForgePlatform.d.ts +96 -0
- package/dist/core/ForgePlatform.d.ts.map +1 -0
- package/dist/core/ForgePlatform.js +136 -0
- package/dist/core/ForgePlatform.js.map +1 -0
- package/dist/core/ForgeWebSocket.d.ts +56 -0
- package/dist/core/ForgeWebSocket.d.ts.map +1 -0
- package/dist/core/ForgeWebSocket.js +415 -0
- package/dist/core/ForgeWebSocket.js.map +1 -0
- package/dist/core/Ingress.d.ts +329 -0
- package/dist/core/Ingress.d.ts.map +1 -0
- package/dist/core/Ingress.js +694 -0
- package/dist/core/Ingress.js.map +1 -0
- package/dist/core/Interceptors.d.ts +134 -0
- package/dist/core/Interceptors.d.ts.map +1 -0
- package/dist/core/Interceptors.js +416 -0
- package/dist/core/Interceptors.js.map +1 -0
- package/dist/core/Logger.d.ts +20 -0
- package/dist/core/Logger.d.ts.map +1 -0
- package/dist/core/Logger.js +77 -0
- package/dist/core/Logger.js.map +1 -0
- package/dist/core/MessageBus.d.ts +15 -0
- package/dist/core/MessageBus.d.ts.map +1 -0
- package/dist/core/MessageBus.js +18 -0
- package/dist/core/MessageBus.js.map +1 -0
- package/dist/core/Prometheus.d.ts +80 -0
- package/dist/core/Prometheus.d.ts.map +1 -0
- package/dist/core/Prometheus.js +332 -0
- package/dist/core/Prometheus.js.map +1 -0
- package/dist/core/RequestContext.d.ts +214 -0
- package/dist/core/RequestContext.d.ts.map +1 -0
- package/dist/core/RequestContext.js +556 -0
- package/dist/core/RequestContext.js.map +1 -0
- package/dist/core/Router.d.ts +45 -0
- package/dist/core/Router.d.ts.map +1 -0
- package/dist/core/Router.js +285 -0
- package/dist/core/Router.js.map +1 -0
- package/dist/core/RoutingStrategy.d.ts +116 -0
- package/dist/core/RoutingStrategy.d.ts.map +1 -0
- package/dist/core/RoutingStrategy.js +306 -0
- package/dist/core/RoutingStrategy.js.map +1 -0
- package/dist/core/RpcConfig.d.ts +72 -0
- package/dist/core/RpcConfig.d.ts.map +1 -0
- package/dist/core/RpcConfig.js +127 -0
- package/dist/core/RpcConfig.js.map +1 -0
- package/dist/core/SignatureCache.d.ts +81 -0
- package/dist/core/SignatureCache.d.ts.map +1 -0
- package/dist/core/SignatureCache.js +172 -0
- package/dist/core/SignatureCache.js.map +1 -0
- package/dist/core/StaticFileServer.d.ts +34 -0
- package/dist/core/StaticFileServer.d.ts.map +1 -0
- package/dist/core/StaticFileServer.js +497 -0
- package/dist/core/StaticFileServer.js.map +1 -0
- package/dist/core/Supervisor.d.ts +198 -0
- package/dist/core/Supervisor.d.ts.map +1 -0
- package/dist/core/Supervisor.js +1418 -0
- package/dist/core/Supervisor.js.map +1 -0
- package/dist/core/ThreadAllocator.d.ts +52 -0
- package/dist/core/ThreadAllocator.d.ts.map +1 -0
- package/dist/core/ThreadAllocator.js +174 -0
- package/dist/core/ThreadAllocator.js.map +1 -0
- package/dist/core/WorkerChannelManager.d.ts +130 -0
- package/dist/core/WorkerChannelManager.d.ts.map +1 -0
- package/dist/core/WorkerChannelManager.js +956 -0
- package/dist/core/WorkerChannelManager.js.map +1 -0
- package/dist/core/config-enums.d.ts +41 -0
- package/dist/core/config-enums.d.ts.map +1 -0
- package/dist/core/config-enums.js +59 -0
- package/dist/core/config-enums.js.map +1 -0
- package/dist/core/config.d.ts +159 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +694 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/host-config.d.ts +146 -0
- package/dist/core/host-config.d.ts.map +1 -0
- package/dist/core/host-config.js +312 -0
- package/dist/core/host-config.js.map +1 -0
- package/dist/core/ipc-errors.d.ts +27 -0
- package/dist/core/ipc-errors.d.ts.map +1 -0
- package/dist/core/ipc-errors.js +36 -0
- package/dist/core/ipc-errors.js.map +1 -0
- package/dist/core/network-utils.d.ts +35 -0
- package/dist/core/network-utils.d.ts.map +1 -0
- package/dist/core/network-utils.js +145 -0
- package/dist/core/network-utils.js.map +1 -0
- package/dist/core/platform-config.d.ts +142 -0
- package/dist/core/platform-config.d.ts.map +1 -0
- package/dist/core/platform-config.js +299 -0
- package/dist/core/platform-config.js.map +1 -0
- package/dist/decorators/ServiceProxy.d.ts +175 -0
- package/dist/decorators/ServiceProxy.d.ts.map +1 -0
- package/dist/decorators/ServiceProxy.js +969 -0
- package/dist/decorators/ServiceProxy.js.map +1 -0
- package/dist/decorators/index.d.ts +146 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +545 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/deploy/NginxGenerator.d.ts +165 -0
- package/dist/deploy/NginxGenerator.d.ts.map +1 -0
- package/dist/deploy/NginxGenerator.js +781 -0
- package/dist/deploy/NginxGenerator.js.map +1 -0
- package/dist/deploy/PlatformManifestGenerator.d.ts +43 -0
- package/dist/deploy/PlatformManifestGenerator.d.ts.map +1 -0
- package/dist/deploy/PlatformManifestGenerator.js +80 -0
- package/dist/deploy/PlatformManifestGenerator.js.map +1 -0
- package/dist/deploy/RouteManifestGenerator.d.ts +42 -0
- package/dist/deploy/RouteManifestGenerator.d.ts.map +1 -0
- package/dist/deploy/RouteManifestGenerator.js +105 -0
- package/dist/deploy/RouteManifestGenerator.js.map +1 -0
- package/dist/deploy/index.d.ts +210 -0
- package/dist/deploy/index.d.ts.map +1 -0
- package/dist/deploy/index.js +918 -0
- package/dist/deploy/index.js.map +1 -0
- package/dist/frontend/FrontendDevLifecycle.d.ts +26 -0
- package/dist/frontend/FrontendDevLifecycle.d.ts.map +1 -0
- package/dist/frontend/FrontendDevLifecycle.js +60 -0
- package/dist/frontend/FrontendDevLifecycle.js.map +1 -0
- package/dist/frontend/FrontendPluginOrchestrator.d.ts +64 -0
- package/dist/frontend/FrontendPluginOrchestrator.d.ts.map +1 -0
- package/dist/frontend/FrontendPluginOrchestrator.js +167 -0
- package/dist/frontend/FrontendPluginOrchestrator.js.map +1 -0
- package/dist/frontend/SiteResolver.d.ts +33 -0
- package/dist/frontend/SiteResolver.d.ts.map +1 -0
- package/dist/frontend/SiteResolver.js +53 -0
- package/dist/frontend/SiteResolver.js.map +1 -0
- package/dist/frontend/StaticMountRegistry.d.ts +36 -0
- package/dist/frontend/StaticMountRegistry.d.ts.map +1 -0
- package/dist/frontend/StaticMountRegistry.js +94 -0
- package/dist/frontend/StaticMountRegistry.js.map +1 -0
- package/dist/frontend/index.d.ts +7 -0
- package/dist/frontend/index.d.ts.map +1 -0
- package/{src → dist}/frontend/index.js +4 -2
- package/dist/frontend/index.js.map +1 -0
- package/dist/frontend/pathUtils.d.ts +8 -0
- package/dist/frontend/pathUtils.d.ts.map +1 -0
- package/dist/frontend/pathUtils.js +17 -0
- package/dist/frontend/pathUtils.js.map +1 -0
- package/dist/frontend/plugins/index.d.ts +2 -0
- package/dist/frontend/plugins/index.d.ts.map +1 -0
- package/{src → dist}/frontend/plugins/index.js +1 -1
- package/dist/frontend/plugins/index.js.map +1 -0
- package/dist/frontend/plugins/viteFrontend.d.ts +51 -0
- package/dist/frontend/plugins/viteFrontend.d.ts.map +1 -0
- package/dist/frontend/plugins/viteFrontend.js +134 -0
- package/dist/frontend/plugins/viteFrontend.js.map +1 -0
- package/dist/frontend/types.d.ts +25 -0
- package/dist/frontend/types.d.ts.map +1 -0
- package/dist/frontend/types.js +2 -0
- package/dist/frontend/types.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/internals.d.ts +21 -0
- package/dist/internals.d.ts.map +1 -0
- package/{src → dist}/internals.js +12 -14
- package/dist/internals.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +209 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/PluginManager.js +365 -0
- package/dist/plugins/PluginManager.js.map +1 -0
- package/dist/plugins/ScopedPostgres.d.ts +78 -0
- package/dist/plugins/ScopedPostgres.d.ts.map +1 -0
- package/dist/plugins/ScopedPostgres.js +190 -0
- package/dist/plugins/ScopedPostgres.js.map +1 -0
- package/dist/plugins/ScopedRedis.d.ts +88 -0
- package/dist/plugins/ScopedRedis.d.ts.map +1 -0
- package/dist/plugins/ScopedRedis.js +169 -0
- package/dist/plugins/ScopedRedis.js.map +1 -0
- package/dist/plugins/index.d.ts +289 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +1942 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/types.d.ts +59 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/registry/ServiceRegistry.d.ts +305 -0
- package/dist/registry/ServiceRegistry.d.ts.map +1 -0
- package/dist/registry/ServiceRegistry.js +735 -0
- package/dist/registry/ServiceRegistry.js.map +1 -0
- package/dist/scaling/ScaleAdvisor.d.ts +214 -0
- package/dist/scaling/ScaleAdvisor.d.ts.map +1 -0
- package/dist/scaling/ScaleAdvisor.js +526 -0
- package/dist/scaling/ScaleAdvisor.js.map +1 -0
- package/dist/services/Service.d.ts +164 -0
- package/dist/services/Service.d.ts.map +1 -0
- package/dist/services/Service.js +106 -0
- package/dist/services/Service.js.map +1 -0
- package/dist/services/worker-bootstrap.d.ts +15 -0
- package/dist/services/worker-bootstrap.d.ts.map +1 -0
- package/dist/services/worker-bootstrap.js +744 -0
- package/dist/services/worker-bootstrap.js.map +1 -0
- package/dist/templates/auth-service.d.ts +42 -0
- package/dist/templates/auth-service.d.ts.map +1 -0
- package/dist/templates/auth-service.js +54 -0
- package/dist/templates/auth-service.js.map +1 -0
- package/dist/templates/identity-service.d.ts +50 -0
- package/dist/templates/identity-service.d.ts.map +1 -0
- package/dist/templates/identity-service.js +62 -0
- package/dist/templates/identity-service.js.map +1 -0
- package/dist/types/contract.d.ts +120 -0
- package/dist/types/contract.d.ts.map +1 -0
- package/dist/types/contract.js +69 -0
- package/dist/types/contract.js.map +1 -0
- package/package.json +79 -20
- package/src/core/DirectMessageBus.js +0 -364
- package/src/core/EndpointResolver.js +0 -259
- package/src/core/ForgeContext.js +0 -2236
- package/src/core/ForgeHost.js +0 -122
- package/src/core/ForgePlatform.js +0 -145
- package/src/core/Ingress.js +0 -768
- package/src/core/Interceptors.js +0 -420
- package/src/core/MessageBus.js +0 -321
- package/src/core/Prometheus.js +0 -305
- package/src/core/RequestContext.js +0 -413
- package/src/core/RoutingStrategy.js +0 -330
- package/src/core/Supervisor.js +0 -1349
- package/src/core/ThreadAllocator.js +0 -196
- package/src/core/WorkerChannelManager.js +0 -879
- package/src/core/config.js +0 -637
- package/src/core/host-config.js +0 -311
- package/src/core/network-utils.js +0 -166
- package/src/core/platform-config.js +0 -308
- package/src/decorators/ServiceProxy.js +0 -904
- package/src/decorators/index.js +0 -571
- package/src/deploy/NginxGenerator.js +0 -865
- package/src/deploy/PlatformManifestGenerator.js +0 -96
- package/src/deploy/RouteManifestGenerator.js +0 -112
- package/src/deploy/index.js +0 -984
- package/src/frontend/FrontendDevLifecycle.js +0 -65
- package/src/frontend/FrontendPluginOrchestrator.js +0 -187
- package/src/frontend/SiteResolver.js +0 -63
- package/src/frontend/StaticMountRegistry.js +0 -90
- package/src/frontend/plugins/viteFrontend.js +0 -79
- package/src/frontend/types.js +0 -35
- package/src/index.js +0 -58
- package/src/plugins/PluginManager.js +0 -537
- package/src/plugins/ScopedPostgres.js +0 -192
- package/src/plugins/ScopedRedis.js +0 -142
- package/src/plugins/index.js +0 -1756
- package/src/registry/ServiceRegistry.js +0 -797
- package/src/scaling/ScaleAdvisor.js +0 -442
- package/src/services/Service.js +0 -195
- package/src/services/worker-bootstrap.js +0 -679
- package/src/templates/auth-service.js +0 -65
- package/src/templates/identity-service.js +0 -75
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ingress Protection
|
|
3
|
+
*
|
|
4
|
+
* Multiple layers of defense between the internet and your services.
|
|
5
|
+
* Each layer catches different failure modes:
|
|
6
|
+
*
|
|
7
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
8
|
+
* │ INTERNET │
|
|
9
|
+
* └───────────────────────────┬─────────────────────────────────┘
|
|
10
|
+
* ▼
|
|
11
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
12
|
+
* │ Layer 1: CONNECTION LIMITER │
|
|
13
|
+
* │ Total open connections capped at N (e.g. 10,000). │
|
|
14
|
+
* │ New connections get TCP RST when full. │
|
|
15
|
+
* │ Prevents file descriptor exhaustion. │
|
|
16
|
+
* └───────────────────────────┬─────────────────────────────────┘
|
|
17
|
+
* ▼
|
|
18
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
19
|
+
* │ Layer 2: RATE LIMITER (per client) │
|
|
20
|
+
* │ Token bucket per IP / API key. Burst-friendly. │
|
|
21
|
+
* │ Returns 429 Too Many Requests when exceeded. │
|
|
22
|
+
* │ Prevents single client from consuming all capacity. │
|
|
23
|
+
* └───────────────────────────┬─────────────────────────────────┘
|
|
24
|
+
* ▼
|
|
25
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
26
|
+
* │ Layer 3: GLOBAL LOAD SHEDDER │
|
|
27
|
+
* │ Monitors gateway CPU + event loop lag. │
|
|
28
|
+
* │ When overloaded, sheds low-priority requests (503). │
|
|
29
|
+
* │ High-priority requests (health checks, auth) pass through. │
|
|
30
|
+
* │ Prevents cascade failure in the gateway itself. │
|
|
31
|
+
* └───────────────────────────┬─────────────────────────────────┘
|
|
32
|
+
* ▼
|
|
33
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
34
|
+
* │ Layer 4: ADAPTIVE CONCURRENCY (per service) │
|
|
35
|
+
* │ Limits in-flight requests to each downstream service. │
|
|
36
|
+
* │ Dynamically adjusts limit based on observed latency. │
|
|
37
|
+
* │ When a service slows down, we send FEWER requests to it. │
|
|
38
|
+
* │ Returns 503 when the service's concurrency window is full. │
|
|
39
|
+
* │ Prevents a slow service from consuming all gateway threads.│
|
|
40
|
+
* └───────────────────────────┬─────────────────────────────────┘
|
|
41
|
+
* ▼
|
|
42
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
43
|
+
* │ SERVICE (users, billing, etc.) │
|
|
44
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
45
|
+
*
|
|
46
|
+
* Usage in a gateway service:
|
|
47
|
+
*
|
|
48
|
+
* import { IngressProtection } from 'threadforge/ingress';
|
|
49
|
+
*
|
|
50
|
+
* export default class GatewayService extends Service {
|
|
51
|
+
* async onStart(ctx) {
|
|
52
|
+
* this.ingress = new IngressProtection({
|
|
53
|
+
* maxConnections: 10000,
|
|
54
|
+
* rateLimit: { windowMs: 60000, maxRequests: 100 },
|
|
55
|
+
* loadShedding: { eventLoopThresholdMs: 100 },
|
|
56
|
+
* services: {
|
|
57
|
+
* users: { maxConcurrent: 200 },
|
|
58
|
+
* billing: { maxConcurrent: 50 },
|
|
59
|
+
* notifications: { maxConcurrent: 100 },
|
|
60
|
+
* },
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* // Apply as middleware
|
|
64
|
+
* ctx.router.use(this.ingress.middleware());
|
|
65
|
+
* }
|
|
66
|
+
* }
|
|
67
|
+
*/
|
|
68
|
+
import { EventEmitter } from "node:events";
|
|
69
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
70
|
+
interface TokenBucket {
|
|
71
|
+
tokens: number;
|
|
72
|
+
lastRefill: number;
|
|
73
|
+
}
|
|
74
|
+
interface RateLimiterOptions {
|
|
75
|
+
maxTokens?: number;
|
|
76
|
+
refillRate?: number;
|
|
77
|
+
maxRequests?: number;
|
|
78
|
+
windowMs?: number;
|
|
79
|
+
keyExtractor?: (req: IncomingMessage) => string;
|
|
80
|
+
}
|
|
81
|
+
interface RateCheckResult {
|
|
82
|
+
allowed: boolean;
|
|
83
|
+
remaining: number;
|
|
84
|
+
retryAfter?: number;
|
|
85
|
+
}
|
|
86
|
+
interface RateLimiterStats {
|
|
87
|
+
activeClients: number;
|
|
88
|
+
maxTokens: number;
|
|
89
|
+
refillRate: number;
|
|
90
|
+
}
|
|
91
|
+
type Priority = "critical" | "high" | "normal" | "low";
|
|
92
|
+
interface PriorityRule {
|
|
93
|
+
pattern: RegExp;
|
|
94
|
+
priority: Priority;
|
|
95
|
+
}
|
|
96
|
+
interface ShedThreshold {
|
|
97
|
+
lagMs: number;
|
|
98
|
+
loadRatio: number;
|
|
99
|
+
}
|
|
100
|
+
interface LoadShedderOptions {
|
|
101
|
+
eventLoopThresholdMs?: number;
|
|
102
|
+
maxActiveRequests?: number;
|
|
103
|
+
checkIntervalMs?: number;
|
|
104
|
+
priorityRules?: PriorityRule[];
|
|
105
|
+
}
|
|
106
|
+
interface ShedCheckResult {
|
|
107
|
+
accept: boolean;
|
|
108
|
+
reason?: string;
|
|
109
|
+
priority: Priority;
|
|
110
|
+
}
|
|
111
|
+
interface LoadShedderStats {
|
|
112
|
+
activeRequests: number;
|
|
113
|
+
maxActiveRequests: number;
|
|
114
|
+
eventLoopLagMs: number;
|
|
115
|
+
loadPercent: string;
|
|
116
|
+
shedding: boolean;
|
|
117
|
+
}
|
|
118
|
+
interface AdaptiveConcurrencyOptions {
|
|
119
|
+
initialLimit?: number;
|
|
120
|
+
minLimit?: number;
|
|
121
|
+
maxLimit?: number;
|
|
122
|
+
smoothing?: number;
|
|
123
|
+
tolerance?: number;
|
|
124
|
+
}
|
|
125
|
+
interface AcquireResult {
|
|
126
|
+
acquired: boolean;
|
|
127
|
+
release?: (success?: boolean) => void;
|
|
128
|
+
}
|
|
129
|
+
interface AdaptiveConcurrencyStats {
|
|
130
|
+
service: string;
|
|
131
|
+
currentLimit: number;
|
|
132
|
+
inFlight: number;
|
|
133
|
+
utilization: string;
|
|
134
|
+
minLatencyMs: string | null;
|
|
135
|
+
smoothedLatencyMs: string;
|
|
136
|
+
p99LatencyMs: string | null;
|
|
137
|
+
totalRequests: number;
|
|
138
|
+
totalRejected: number;
|
|
139
|
+
rejectionRate: string;
|
|
140
|
+
}
|
|
141
|
+
interface IngressOptions {
|
|
142
|
+
maxConnections?: number;
|
|
143
|
+
rateLimit?: RateLimiterOptions;
|
|
144
|
+
loadShedding?: LoadShedderOptions;
|
|
145
|
+
services?: Record<string, AdaptiveConcurrencyOptions>;
|
|
146
|
+
}
|
|
147
|
+
interface IngressStats {
|
|
148
|
+
connections: {
|
|
149
|
+
active: number;
|
|
150
|
+
max: number;
|
|
151
|
+
};
|
|
152
|
+
rateLimiter: RateLimiterStats;
|
|
153
|
+
loadShedder: LoadShedderStats;
|
|
154
|
+
services: Record<string, AdaptiveConcurrencyStats>;
|
|
155
|
+
}
|
|
156
|
+
type MiddlewareFn = (req: IncomingMessage, res: ServerResponse, next?: () => void) => Promise<void>;
|
|
157
|
+
/**
|
|
158
|
+
* Per-client rate limiter using the token bucket algorithm.
|
|
159
|
+
*
|
|
160
|
+
* Token bucket is burst-friendly: a client that hasn't made
|
|
161
|
+
* requests in a while accumulates tokens and can burst.
|
|
162
|
+
* A client that's been hammering the API runs out of tokens
|
|
163
|
+
* and gets 429'd.
|
|
164
|
+
*
|
|
165
|
+
* Why token bucket instead of sliding window:
|
|
166
|
+
* - Allows natural burst patterns (page load = 10 requests at once)
|
|
167
|
+
* - Smoother than fixed windows (no "thundering herd" at window reset)
|
|
168
|
+
* - O(1) per request (no sorted sets or sliding counters)
|
|
169
|
+
*/
|
|
170
|
+
export declare class RateLimiter {
|
|
171
|
+
maxTokens: number;
|
|
172
|
+
refillRate: number;
|
|
173
|
+
windowMs: number;
|
|
174
|
+
keyExtractor: (req: IncomingMessage) => string;
|
|
175
|
+
buckets: Map<string, TokenBucket>;
|
|
176
|
+
private _cleanupTimer;
|
|
177
|
+
constructor(options?: RateLimiterOptions);
|
|
178
|
+
/**
|
|
179
|
+
* Check if a request is allowed.
|
|
180
|
+
*/
|
|
181
|
+
check(req: IncomingMessage): RateCheckResult;
|
|
182
|
+
private _cleanup;
|
|
183
|
+
get stats(): RateLimiterStats;
|
|
184
|
+
stop(): void;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Global load shedder. Monitors the gateway process health and
|
|
188
|
+
* drops requests when overloaded.
|
|
189
|
+
*
|
|
190
|
+
* Monitors two signals:
|
|
191
|
+
* 1. Event loop lag — if the event loop is delayed by > threshold,
|
|
192
|
+
* the process is CPU-starved. Start shedding.
|
|
193
|
+
* 2. Active requests — if we have too many in-flight, shed.
|
|
194
|
+
*
|
|
195
|
+
* Shedding is priority-based:
|
|
196
|
+
* - CRITICAL: health checks, auth — never shed
|
|
197
|
+
* - HIGH: payment webhooks — shed only at extreme load
|
|
198
|
+
* - NORMAL: regular API calls — shed when overloaded
|
|
199
|
+
* - LOW: analytics, logging — shed first
|
|
200
|
+
*/
|
|
201
|
+
export declare class LoadShedder {
|
|
202
|
+
eventLoopThresholdMs: number;
|
|
203
|
+
maxActiveRequests: number;
|
|
204
|
+
checkIntervalMs: number;
|
|
205
|
+
priorityRules: PriorityRule[];
|
|
206
|
+
activeRequests: number;
|
|
207
|
+
eventLoopLag: number;
|
|
208
|
+
shedThresholds: Record<Priority, ShedThreshold>;
|
|
209
|
+
private _lastCheck;
|
|
210
|
+
private _lagTimerActive;
|
|
211
|
+
private _lagTimer;
|
|
212
|
+
constructor(options?: LoadShedderOptions);
|
|
213
|
+
/**
|
|
214
|
+
* Should this request be accepted or shed?
|
|
215
|
+
*/
|
|
216
|
+
shouldAccept(req: IncomingMessage): ShedCheckResult;
|
|
217
|
+
private _getPriority;
|
|
218
|
+
trackRequest(): () => void;
|
|
219
|
+
get stats(): LoadShedderStats;
|
|
220
|
+
stop(): void;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Adaptive Concurrency Limiter (per downstream service)
|
|
224
|
+
*
|
|
225
|
+
* The core problem: how many concurrent requests should we send
|
|
226
|
+
* to the users service? Too few = wasted capacity. Too many =
|
|
227
|
+
* overwhelm the service, latency spikes, cascade failure.
|
|
228
|
+
*
|
|
229
|
+
* Fixed limits are fragile — they're either too conservative
|
|
230
|
+
* (wasting capacity during normal load) or too aggressive
|
|
231
|
+
* (causing failures during peak).
|
|
232
|
+
*
|
|
233
|
+
* Instead, we use the Vegas algorithm (from TCP congestion control):
|
|
234
|
+
*
|
|
235
|
+
* 1. Start with a small concurrency window (e.g., 10)
|
|
236
|
+
* 2. Measure round-trip latency for each request
|
|
237
|
+
* 3. Track the minimum observed latency (the "no-load" baseline)
|
|
238
|
+
* 4. If current latency ≈ baseline → increase the window
|
|
239
|
+
* (service has capacity, give it more)
|
|
240
|
+
* 5. If current latency >> baseline → decrease the window
|
|
241
|
+
* (service is queuing, back off)
|
|
242
|
+
*
|
|
243
|
+
* This automatically adapts to:
|
|
244
|
+
* - Fast services (high window, more concurrent requests)
|
|
245
|
+
* - Slow services (low window, fewer concurrent requests)
|
|
246
|
+
* - Services that degrade under load (window shrinks as latency rises)
|
|
247
|
+
* - Services that recover (window grows as latency drops)
|
|
248
|
+
*
|
|
249
|
+
* Inspired by Netflix's concurrency-limits library.
|
|
250
|
+
*/
|
|
251
|
+
export declare class AdaptiveConcurrencyLimiter {
|
|
252
|
+
serviceName: string;
|
|
253
|
+
limit: number;
|
|
254
|
+
minLimit: number;
|
|
255
|
+
maxLimit: number;
|
|
256
|
+
smoothing: number;
|
|
257
|
+
tolerance: number;
|
|
258
|
+
inFlight: number;
|
|
259
|
+
minLatency: number;
|
|
260
|
+
smoothedLatency: number;
|
|
261
|
+
totalRequests: number;
|
|
262
|
+
totalRejected: number;
|
|
263
|
+
totalSuccesses: number;
|
|
264
|
+
totalFailures: number;
|
|
265
|
+
private _latencies;
|
|
266
|
+
private _latencyIdx;
|
|
267
|
+
private _latencyCount;
|
|
268
|
+
private _minLatencyWindow;
|
|
269
|
+
private _minLatencyWindowIdx;
|
|
270
|
+
private _minLatencyWindowCount;
|
|
271
|
+
private _minLatencyObservations;
|
|
272
|
+
constructor(serviceName: string, options?: AdaptiveConcurrencyOptions);
|
|
273
|
+
/**
|
|
274
|
+
* Try to acquire a concurrency slot.
|
|
275
|
+
*/
|
|
276
|
+
tryAcquire(): AcquireResult;
|
|
277
|
+
private _recordLatency;
|
|
278
|
+
private _adjustLimit;
|
|
279
|
+
get stats(): AdaptiveConcurrencyStats;
|
|
280
|
+
private _getPercentile;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Combined ingress protection middleware.
|
|
284
|
+
*
|
|
285
|
+
* Applies all layers in order: connection limit → rate limit →
|
|
286
|
+
* load shedding → route → adaptive concurrency → service.
|
|
287
|
+
*/
|
|
288
|
+
export declare class IngressProtection extends EventEmitter {
|
|
289
|
+
maxConnections: number;
|
|
290
|
+
activeConnections: number;
|
|
291
|
+
rateLimiter: RateLimiter;
|
|
292
|
+
loadShedder: LoadShedder;
|
|
293
|
+
serviceLimiters: Map<string, AdaptiveConcurrencyLimiter>;
|
|
294
|
+
private _metricsInterval;
|
|
295
|
+
constructor(options?: IngressOptions);
|
|
296
|
+
/**
|
|
297
|
+
* Get or create a concurrency limiter for a service.
|
|
298
|
+
*/
|
|
299
|
+
getServiceLimiter(serviceName: string): AdaptiveConcurrencyLimiter;
|
|
300
|
+
/**
|
|
301
|
+
* Returns a middleware function for the ForgeContext router.
|
|
302
|
+
*
|
|
303
|
+
* Usage:
|
|
304
|
+
* ctx.router.use(this.ingress.middleware());
|
|
305
|
+
*/
|
|
306
|
+
middleware(): MiddlewareFn;
|
|
307
|
+
/**
|
|
308
|
+
* Wrap a proxy call with adaptive concurrency limiting.
|
|
309
|
+
*
|
|
310
|
+
* Usage in the gateway:
|
|
311
|
+
* const user = await this.ingress.withConcurrencyLimit('users', () =>
|
|
312
|
+
* this.users.getUser(id)
|
|
313
|
+
* );
|
|
314
|
+
*
|
|
315
|
+
* Or in the proxy interceptor layer:
|
|
316
|
+
* The ServiceProxy automatically calls this if ingress is configured.
|
|
317
|
+
*/
|
|
318
|
+
withConcurrencyLimit<T>(serviceName: string, fn: () => Promise<T>): Promise<T>;
|
|
319
|
+
get stats(): IngressStats;
|
|
320
|
+
/**
|
|
321
|
+
* HTTP handler for ingress stats endpoint.
|
|
322
|
+
* Mount on the metrics server:
|
|
323
|
+
* GET /ingress → full stats
|
|
324
|
+
*/
|
|
325
|
+
httpHandler(req: IncomingMessage, res: ServerResponse): boolean;
|
|
326
|
+
stop(): void;
|
|
327
|
+
}
|
|
328
|
+
export {};
|
|
329
|
+
//# sourceMappingURL=Ingress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Ingress.d.ts","sourceRoot":"","sources":["../../src/core/Ingress.ts"],"names":[],"mappings":"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"}
|