tywrap 0.8.0 → 0.9.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.
Files changed (157) hide show
  1. package/README.md +22 -7
  2. package/SECURITY.md +39 -0
  3. package/dist/config/index.d.ts.map +1 -1
  4. package/dist/config/index.js +8 -0
  5. package/dist/config/index.js.map +1 -1
  6. package/dist/core/annotation-parser.d.ts +2 -1
  7. package/dist/core/annotation-parser.d.ts.map +1 -1
  8. package/dist/core/annotation-parser.js +6 -3
  9. package/dist/core/annotation-parser.js.map +1 -1
  10. package/dist/core/generator.d.ts +23 -4
  11. package/dist/core/generator.d.ts.map +1 -1
  12. package/dist/core/generator.js +243 -170
  13. package/dist/core/generator.js.map +1 -1
  14. package/dist/core/mapper.d.ts +3 -2
  15. package/dist/core/mapper.d.ts.map +1 -1
  16. package/dist/core/mapper.js +5 -5
  17. package/dist/core/mapper.js.map +1 -1
  18. package/dist/index.d.ts +7 -5
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +6 -4
  21. package/dist/index.js.map +1 -1
  22. package/dist/runtime/base-bridge.d.ts +3 -7
  23. package/dist/runtime/base-bridge.d.ts.map +1 -1
  24. package/dist/runtime/base-bridge.js +4 -17
  25. package/dist/runtime/base-bridge.js.map +1 -1
  26. package/dist/runtime/bounded-context.d.ts +3 -22
  27. package/dist/runtime/bounded-context.d.ts.map +1 -1
  28. package/dist/runtime/bounded-context.js +13 -53
  29. package/dist/runtime/bounded-context.js.map +1 -1
  30. package/dist/runtime/bridge-codec.d.ts +1 -1
  31. package/dist/runtime/bridge-codec.d.ts.map +1 -1
  32. package/dist/runtime/bridge-codec.js +78 -55
  33. package/dist/runtime/bridge-codec.js.map +1 -1
  34. package/dist/runtime/errors.d.ts +16 -0
  35. package/dist/runtime/errors.d.ts.map +1 -1
  36. package/dist/runtime/errors.js +17 -0
  37. package/dist/runtime/errors.js.map +1 -1
  38. package/dist/runtime/http-transport.d.ts +1 -1
  39. package/dist/runtime/http-transport.d.ts.map +1 -1
  40. package/dist/runtime/http-transport.js +1 -1
  41. package/dist/runtime/http-transport.js.map +1 -1
  42. package/dist/runtime/index.d.ts +1 -0
  43. package/dist/runtime/index.d.ts.map +1 -1
  44. package/dist/runtime/index.js +1 -0
  45. package/dist/runtime/index.js.map +1 -1
  46. package/dist/runtime/node.d.ts +7 -36
  47. package/dist/runtime/node.d.ts.map +1 -1
  48. package/dist/runtime/node.js +2 -80
  49. package/dist/runtime/node.js.map +1 -1
  50. package/dist/runtime/pooled-transport.d.ts +120 -59
  51. package/dist/runtime/pooled-transport.d.ts.map +1 -1
  52. package/dist/runtime/pooled-transport.js +345 -78
  53. package/dist/runtime/pooled-transport.js.map +1 -1
  54. package/dist/runtime/pyodide-bootstrap-core.generated.d.ts.map +1 -1
  55. package/dist/runtime/pyodide-bootstrap-core.generated.js +1 -1
  56. package/dist/runtime/pyodide-bootstrap-core.generated.js.map +1 -1
  57. package/dist/runtime/pyodide-transport.d.ts +1 -1
  58. package/dist/runtime/pyodide-transport.d.ts.map +1 -1
  59. package/dist/runtime/pyodide-transport.js +2 -3
  60. package/dist/runtime/pyodide-transport.js.map +1 -1
  61. package/dist/runtime/rpc-client.d.ts +7 -36
  62. package/dist/runtime/rpc-client.d.ts.map +1 -1
  63. package/dist/runtime/rpc-client.js +20 -102
  64. package/dist/runtime/rpc-client.js.map +1 -1
  65. package/dist/runtime/subprocess-transport.d.ts +30 -69
  66. package/dist/runtime/subprocess-transport.d.ts.map +1 -1
  67. package/dist/runtime/subprocess-transport.js +179 -236
  68. package/dist/runtime/subprocess-transport.js.map +1 -1
  69. package/dist/runtime/timed-out-request-tracker.d.ts +2 -1
  70. package/dist/runtime/timed-out-request-tracker.d.ts.map +1 -1
  71. package/dist/runtime/transport.d.ts +9 -19
  72. package/dist/runtime/transport.d.ts.map +1 -1
  73. package/dist/runtime/transport.js +1 -1
  74. package/dist/runtime/transport.js.map +1 -1
  75. package/dist/runtime/validators.d.ts +49 -0
  76. package/dist/runtime/validators.d.ts.map +1 -1
  77. package/dist/runtime/validators.js +152 -0
  78. package/dist/runtime/validators.js.map +1 -1
  79. package/dist/types/index.d.ts +14 -39
  80. package/dist/types/index.d.ts.map +1 -1
  81. package/dist/tywrap.d.ts +3 -2
  82. package/dist/tywrap.d.ts.map +1 -1
  83. package/dist/tywrap.js +140 -13
  84. package/dist/tywrap.js.map +1 -1
  85. package/dist/utils/cache.d.ts +3 -16
  86. package/dist/utils/cache.d.ts.map +1 -1
  87. package/dist/utils/codec.d.ts +1 -0
  88. package/dist/utils/codec.d.ts.map +1 -1
  89. package/dist/utils/codec.js +13 -13
  90. package/dist/utils/codec.js.map +1 -1
  91. package/dist/utils/ir-cache.d.ts +2 -1
  92. package/dist/utils/ir-cache.d.ts.map +1 -1
  93. package/dist/utils/runtime.d.ts +0 -29
  94. package/dist/utils/runtime.d.ts.map +1 -1
  95. package/dist/utils/runtime.js +16 -107
  96. package/dist/utils/runtime.js.map +1 -1
  97. package/dist/version.js +1 -1
  98. package/package.json +7 -6
  99. package/runtime/frame_codec.py +7 -1
  100. package/runtime/python_bridge.py +85 -125
  101. package/runtime/tywrap_bridge_core.py +133 -150
  102. package/src/config/index.ts +11 -0
  103. package/src/core/annotation-parser.ts +7 -4
  104. package/src/core/generator.ts +315 -205
  105. package/src/core/mapper.ts +8 -8
  106. package/src/index.ts +7 -4
  107. package/src/runtime/base-bridge.ts +5 -30
  108. package/src/runtime/bounded-context.ts +12 -67
  109. package/src/runtime/bridge-codec.ts +94 -65
  110. package/src/runtime/errors.ts +21 -0
  111. package/src/runtime/http-transport.ts +6 -1
  112. package/src/runtime/index.ts +6 -0
  113. package/src/runtime/node.ts +9 -120
  114. package/src/runtime/pooled-transport.ts +424 -90
  115. package/src/runtime/pyodide-bootstrap-core.generated.ts +1 -1
  116. package/src/runtime/pyodide-transport.ts +7 -3
  117. package/src/runtime/rpc-client.ts +37 -139
  118. package/src/runtime/subprocess-transport.ts +210 -285
  119. package/src/runtime/timed-out-request-tracker.ts +1 -1
  120. package/src/runtime/transport.ts +15 -23
  121. package/src/runtime/validators.ts +204 -0
  122. package/src/types/index.ts +21 -60
  123. package/src/tywrap.ts +157 -22
  124. package/src/utils/cache.ts +3 -3
  125. package/src/utils/codec.ts +21 -13
  126. package/src/utils/ir-cache.ts +1 -1
  127. package/src/utils/runtime.ts +17 -128
  128. package/src/version.ts +1 -1
  129. package/dist/core/discovery.d.ts +0 -103
  130. package/dist/core/discovery.d.ts.map +0 -1
  131. package/dist/core/discovery.js +0 -380
  132. package/dist/core/discovery.js.map +0 -1
  133. package/dist/core/validation.d.ts +0 -102
  134. package/dist/core/validation.d.ts.map +0 -1
  135. package/dist/core/validation.js +0 -490
  136. package/dist/core/validation.js.map +0 -1
  137. package/dist/runtime/base.d.ts +0 -22
  138. package/dist/runtime/base.d.ts.map +0 -1
  139. package/dist/runtime/base.js +0 -23
  140. package/dist/runtime/base.js.map +0 -1
  141. package/dist/runtime/transport-pool.d.ts +0 -196
  142. package/dist/runtime/transport-pool.d.ts.map +0 -1
  143. package/dist/runtime/transport-pool.js +0 -418
  144. package/dist/runtime/transport-pool.js.map +0 -1
  145. package/runtime/__pycache__/_tywrap_conformance_chunking_fixtures.cpython-311.pyc +0 -0
  146. package/runtime/__pycache__/_tywrap_member_fixtures.cpython-311.pyc +0 -0
  147. package/runtime/__pycache__/_tywrap_w4_chunking_fixture.cpython-311.pyc +0 -0
  148. package/runtime/__pycache__/_tywrap_w5_request_chunking_fixture.cpython-311.pyc +0 -0
  149. package/runtime/__pycache__/_tywrap_w6_pool_chunking_fixture.cpython-311.pyc +0 -0
  150. package/runtime/__pycache__/frame_codec.cpython-311.pyc +0 -0
  151. package/runtime/__pycache__/safe_codec.cpython-311.pyc +0 -0
  152. package/runtime/__pycache__/tywrap_bridge_core.cpython-311.pyc +0 -0
  153. package/runtime/safe_codec.py +0 -352
  154. package/src/core/discovery.ts +0 -477
  155. package/src/core/validation.ts +0 -729
  156. package/src/runtime/base.ts +0 -24
  157. package/src/runtime/transport-pool.ts +0 -538
@@ -1,196 +0,0 @@
1
- /**
2
- * TransportPool - Manages multiple Transport instances for concurrent request handling.
3
- *
4
- * Provides semaphore-based concurrency control with configurable limits per worker
5
- * and a wait queue for callers when all workers are at capacity.
6
- *
7
- * @see https://github.com/bbopen/tywrap/issues/149
8
- */
9
- import { DisposableBase } from './bounded-context.js';
10
- import type { Transport } from './transport.js';
11
- /**
12
- * Configuration options for the TransportPool.
13
- */
14
- export interface TransportPoolOptions {
15
- /** Factory function to create transports */
16
- createTransport: () => Transport;
17
- /** Maximum number of workers in the pool */
18
- maxWorkers: number;
19
- /** Minimum number of workers to pre-spawn during init. Default: 0 (lazy) */
20
- minWorkers?: number;
21
- /** Timeout for waiting in queue (ms). Default: 30000 */
22
- queueTimeoutMs?: number;
23
- /** Maximum concurrent requests per worker. Default: 1 */
24
- maxConcurrentPerWorker?: number;
25
- /**
26
- * Callback invoked after each worker is created and initialized.
27
- * Use this for per-worker warmup (e.g., importing modules, running setup).
28
- */
29
- onWorkerReady?: (worker: TransportLease) => Promise<void>;
30
- /**
31
- * Optional callback used only for background replacement workers after a
32
- * fatal timeout/crash. This lets callers publish a replacement only after it
33
- * is proven ready, without charging hidden work to normal request startup.
34
- */
35
- onReplacementWorkerReady?: (worker: TransportLease) => Promise<void>;
36
- }
37
- /**
38
- * A pooled worker with its transport and current in-flight request count.
39
- */
40
- export interface TransportLease {
41
- /** The underlying transport instance */
42
- transport: Transport;
43
- /** Number of requests currently being processed by this worker */
44
- inFlightCount: number;
45
- }
46
- /**
47
- * Pool of Transport workers with semaphore-based concurrency control.
48
- *
49
- * Features:
50
- * - Lazy worker creation (workers created on demand)
51
- * - Configurable concurrency per worker
52
- * - Wait queue with timeout for callers when pool is at capacity
53
- * - Automatic cleanup of timers and workers on disposal
54
- *
55
- * @example
56
- * ```typescript
57
- * const pool = new TransportPool({
58
- * createTransport: () => new SubprocessTransport({ pythonPath: 'python3' }),
59
- * maxWorkers: 4,
60
- * maxConcurrentPerWorker: 2,
61
- * queueTimeoutMs: 5000,
62
- * });
63
- *
64
- * await pool.init();
65
- *
66
- * // Use withWorker for automatic acquire/release
67
- * const result = await pool.withWorker(async (worker) => {
68
- * return worker.transport.send(message, timeout);
69
- * });
70
- *
71
- * await pool.dispose();
72
- * ```
73
- */
74
- export declare class TransportPool extends DisposableBase {
75
- private readonly options;
76
- private readonly workers;
77
- private readonly waitQueue;
78
- /** Tracks workers being created to prevent race condition in acquire() */
79
- private pendingCreations;
80
- /**
81
- * Create a new TransportPool.
82
- *
83
- * @param options - Pool configuration options
84
- */
85
- constructor(options: TransportPoolOptions);
86
- /**
87
- * Initialize the pool.
88
- *
89
- * If minWorkers > 0, pre-spawns workers during initialization.
90
- * Otherwise, workers are created lazily on demand.
91
- */
92
- protected doInit(): Promise<void>;
93
- /**
94
- * Dispose the pool and all workers.
95
- *
96
- * - Rejects all waiters in the queue
97
- * - Disposes all transport instances
98
- * - Clears internal state
99
- */
100
- protected doDispose(): Promise<void>;
101
- /**
102
- * Acquire a worker from the pool.
103
- *
104
- * This method:
105
- * - Returns an available worker if one exists (inFlightCount < maxConcurrentPerWorker)
106
- * - Creates a new worker if under the maxWorkers limit
107
- * - Waits in queue if all workers are at capacity
108
- *
109
- * @returns Promise resolving to a pooled worker
110
- * @throws BridgeTimeoutError if queue timeout expires
111
- * @throws BridgeExecutionError if pool is disposed while waiting
112
- */
113
- acquire(): Promise<TransportLease>;
114
- /**
115
- * Release a worker back to the pool.
116
- *
117
- * Decrements the worker's in-flight count and notifies any waiters
118
- * that a worker may be available.
119
- *
120
- * @param worker - The worker to release
121
- */
122
- release(worker: TransportLease): void;
123
- /**
124
- * Execute a function with an acquired worker, automatically releasing afterward.
125
- *
126
- * This is the recommended way to use the pool, as it ensures proper cleanup
127
- * even if the function throws an error.
128
- *
129
- * @param fn - Async function to execute with the worker
130
- * @returns Promise resolving to the function's return value
131
- *
132
- * @example
133
- * ```typescript
134
- * const result = await pool.withWorker(async (worker) => {
135
- * return worker.transport.send(message, timeout);
136
- * });
137
- * ```
138
- */
139
- withWorker<T>(fn: (worker: TransportLease) => Promise<T>): Promise<T>;
140
- /**
141
- * Check if an error indicates the worker is dead and should be removed.
142
- *
143
- * Fatal errors include:
144
- * - Process not running
145
- * - Process exited unexpectedly
146
- * - Pipe errors (EPIPE)
147
- * - Connection reset errors (ECONNRESET)
148
- */
149
- private isFatalWorkerError;
150
- /**
151
- * Remove a worker from the pool.
152
- *
153
- * This is called when a worker is detected as dead (crashed, pipe error, etc.).
154
- * The worker's transport is disposed in the background.
155
- */
156
- private removeWorker;
157
- /**
158
- * Current number of workers in the pool.
159
- */
160
- get workerCount(): number;
161
- /**
162
- * Number of callers waiting in the queue.
163
- */
164
- get queueLength(): number;
165
- /**
166
- * Total number of in-flight requests across all workers.
167
- */
168
- get totalInFlight(): number;
169
- /**
170
- * Find an available worker with capacity for another request.
171
- */
172
- private findAvailableWorker;
173
- private getMinimumWorkerDeficit;
174
- private isShuttingDown;
175
- private fillToMinimumWorkers;
176
- private spawnWorkers;
177
- /**
178
- * Replace a removed worker in the background so the next caller does not pay
179
- * the full worker cold-start penalty after a timeout or crash.
180
- */
181
- private scheduleReplacementWorker;
182
- private spawnWorkerToPool;
183
- private publishAvailableWorker;
184
- /**
185
- * Create a new worker and add it to the pool.
186
- *
187
- * If onWorkerReady is configured, calls it after the transport is initialized.
188
- * This is useful for per-worker warmup (importing modules, running setup).
189
- */
190
- private createWorker;
191
- /**
192
- * Wait in queue for a worker to become available.
193
- */
194
- private waitForWorker;
195
- }
196
- //# sourceMappingURL=transport-pool.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transport-pool.d.ts","sourceRoot":"","sources":["../../src/runtime/transport-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAMhD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,4CAA4C;IAC5C,eAAe,EAAE,MAAM,SAAS,CAAC;IAEjC,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IAEnB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,yDAAyD;IACzD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1D;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,SAAS,EAAE,SAAS,CAAC;IAErB,kEAAkE;IAClE,aAAa,EAAE,MAAM,CAAC;CACvB;AAoBD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,aAAc,SAAQ,cAAc;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAMtB;IACF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,0EAA0E;IAC1E,OAAO,CAAC,gBAAgB,CAAK;IAE7B;;;;OAIG;gBACS,OAAO,EAAE,oBAAoB;IA+BzC;;;;;OAKG;cACa,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAKvC;;;;;;OAMG;cACa,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC1C;;;;;;;;;;;OAWG;IACG,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC;IAqCxC;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAWrC;;;;;;;;;;;;;;;OAeG;IACG,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAyB3E;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAkBpB;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAMD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,cAAc;YAIR,oBAAoB;YAIpB,YAAY;IAY1B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;YAmBnB,iBAAiB;IAc/B,OAAO,CAAC,sBAAsB;IAe9B;;;;;OAKG;YACW,YAAY;IAoC1B;;OAEG;IACH,OAAO,CAAC,aAAa;CAuBtB"}
@@ -1,418 +0,0 @@
1
- /**
2
- * TransportPool - Manages multiple Transport instances for concurrent request handling.
3
- *
4
- * Provides semaphore-based concurrency control with configurable limits per worker
5
- * and a wait queue for callers when all workers are at capacity.
6
- *
7
- * @see https://github.com/bbopen/tywrap/issues/149
8
- */
9
- import { DisposableBase } from './bounded-context.js';
10
- import { BridgeTimeoutError, BridgeExecutionError, BridgeProtocolError } from './errors.js';
11
- // =============================================================================
12
- // WORKER POOL
13
- // =============================================================================
14
- /**
15
- * Pool of Transport workers with semaphore-based concurrency control.
16
- *
17
- * Features:
18
- * - Lazy worker creation (workers created on demand)
19
- * - Configurable concurrency per worker
20
- * - Wait queue with timeout for callers when pool is at capacity
21
- * - Automatic cleanup of timers and workers on disposal
22
- *
23
- * @example
24
- * ```typescript
25
- * const pool = new TransportPool({
26
- * createTransport: () => new SubprocessTransport({ pythonPath: 'python3' }),
27
- * maxWorkers: 4,
28
- * maxConcurrentPerWorker: 2,
29
- * queueTimeoutMs: 5000,
30
- * });
31
- *
32
- * await pool.init();
33
- *
34
- * // Use withWorker for automatic acquire/release
35
- * const result = await pool.withWorker(async (worker) => {
36
- * return worker.transport.send(message, timeout);
37
- * });
38
- *
39
- * await pool.dispose();
40
- * ```
41
- */
42
- export class TransportPool extends DisposableBase {
43
- options;
44
- workers = [];
45
- waitQueue = [];
46
- /** Tracks workers being created to prevent race condition in acquire() */
47
- pendingCreations = 0;
48
- /**
49
- * Create a new TransportPool.
50
- *
51
- * @param options - Pool configuration options
52
- */
53
- constructor(options) {
54
- super();
55
- // Validate required options
56
- if (typeof options.createTransport !== 'function') {
57
- throw new BridgeExecutionError('createTransport must be a function');
58
- }
59
- if (typeof options.maxWorkers !== 'number' || options.maxWorkers < 1) {
60
- throw new BridgeExecutionError('maxWorkers must be a positive number');
61
- }
62
- const minWorkers = options.minWorkers ?? 0;
63
- if (minWorkers > options.maxWorkers) {
64
- throw new BridgeExecutionError('minWorkers cannot exceed maxWorkers');
65
- }
66
- this.options = {
67
- createTransport: options.createTransport,
68
- maxWorkers: options.maxWorkers,
69
- minWorkers,
70
- queueTimeoutMs: options.queueTimeoutMs ?? 30000,
71
- maxConcurrentPerWorker: options.maxConcurrentPerWorker ?? 1,
72
- onWorkerReady: options.onWorkerReady,
73
- onReplacementWorkerReady: options.onReplacementWorkerReady,
74
- };
75
- }
76
- // ===========================================================================
77
- // LIFECYCLE
78
- // ===========================================================================
79
- /**
80
- * Initialize the pool.
81
- *
82
- * If minWorkers > 0, pre-spawns workers during initialization.
83
- * Otherwise, workers are created lazily on demand.
84
- */
85
- async doInit() {
86
- // Pre-spawn minimum workers if configured
87
- await this.fillToMinimumWorkers();
88
- }
89
- /**
90
- * Dispose the pool and all workers.
91
- *
92
- * - Rejects all waiters in the queue
93
- * - Disposes all transport instances
94
- * - Clears internal state
95
- */
96
- async doDispose() {
97
- // Reject all waiters in the queue
98
- for (const waiter of this.waitQueue) {
99
- clearTimeout(waiter.timer);
100
- waiter.reject(new BridgeExecutionError('Pool disposed'));
101
- }
102
- this.waitQueue.length = 0;
103
- // Dispose all workers
104
- const errors = [];
105
- for (const worker of this.workers) {
106
- try {
107
- await worker.transport.dispose();
108
- }
109
- catch (e) {
110
- errors.push(e instanceof Error ? e : new Error(String(e)));
111
- }
112
- }
113
- this.workers.length = 0;
114
- // Report errors if any
115
- if (errors.length === 1) {
116
- throw errors[0];
117
- }
118
- if (errors.length > 1) {
119
- throw new AggregateError(errors, 'Multiple errors during worker disposal');
120
- }
121
- }
122
- // ===========================================================================
123
- // WORKER MANAGEMENT
124
- // ===========================================================================
125
- /**
126
- * Acquire a worker from the pool.
127
- *
128
- * This method:
129
- * - Returns an available worker if one exists (inFlightCount < maxConcurrentPerWorker)
130
- * - Creates a new worker if under the maxWorkers limit
131
- * - Waits in queue if all workers are at capacity
132
- *
133
- * @returns Promise resolving to a pooled worker
134
- * @throws BridgeTimeoutError if queue timeout expires
135
- * @throws BridgeExecutionError if pool is disposed while waiting
136
- */
137
- async acquire() {
138
- // Check for disposed state
139
- if (this.isDisposed || this.state === 'disposing') {
140
- throw new BridgeExecutionError('Pool has been disposed');
141
- }
142
- // Find an available worker (one with capacity)
143
- const availableWorker = this.findAvailableWorker();
144
- if (availableWorker) {
145
- availableWorker.inFlightCount++;
146
- return availableWorker;
147
- }
148
- // Create a new worker if under the limit
149
- // Include pendingCreations to prevent race condition where multiple
150
- // concurrent acquire() calls all pass the length check before any
151
- // worker is actually added to the array
152
- if (this.workers.length + this.pendingCreations < this.options.maxWorkers) {
153
- this.pendingCreations++;
154
- try {
155
- const newWorker = await this.createWorker();
156
- if (this.isShuttingDown()) {
157
- this.removeWorker(newWorker);
158
- throw new BridgeExecutionError('Pool has been disposed');
159
- }
160
- newWorker.inFlightCount++;
161
- this.publishAvailableWorker(newWorker);
162
- return newWorker;
163
- }
164
- finally {
165
- this.pendingCreations--;
166
- }
167
- }
168
- // All workers at capacity - wait in queue
169
- return this.waitForWorker();
170
- }
171
- /**
172
- * Release a worker back to the pool.
173
- *
174
- * Decrements the worker's in-flight count and notifies any waiters
175
- * that a worker may be available.
176
- *
177
- * @param worker - The worker to release
178
- */
179
- release(worker) {
180
- // Validate the worker belongs to this pool
181
- if (!this.workers.includes(worker)) {
182
- return;
183
- }
184
- // Decrement in-flight count (minimum 0)
185
- worker.inFlightCount = Math.max(0, worker.inFlightCount - 1);
186
- this.publishAvailableWorker(worker);
187
- }
188
- /**
189
- * Execute a function with an acquired worker, automatically releasing afterward.
190
- *
191
- * This is the recommended way to use the pool, as it ensures proper cleanup
192
- * even if the function throws an error.
193
- *
194
- * @param fn - Async function to execute with the worker
195
- * @returns Promise resolving to the function's return value
196
- *
197
- * @example
198
- * ```typescript
199
- * const result = await pool.withWorker(async (worker) => {
200
- * return worker.transport.send(message, timeout);
201
- * });
202
- * ```
203
- */
204
- async withWorker(fn) {
205
- const worker = await this.acquire();
206
- let workerRemoved = false;
207
- try {
208
- return await fn(worker);
209
- }
210
- catch (error) {
211
- // If this is a fatal error indicating the worker is dead, remove it from the pool
212
- if (this.isFatalWorkerError(error)) {
213
- this.removeWorker(worker);
214
- workerRemoved = true;
215
- }
216
- throw error;
217
- }
218
- finally {
219
- // Only release if worker wasn't removed due to fatal error
220
- if (!workerRemoved) {
221
- this.release(worker);
222
- }
223
- }
224
- }
225
- // ===========================================================================
226
- // WORKER HEALTH
227
- // ===========================================================================
228
- /**
229
- * Check if an error indicates the worker is dead and should be removed.
230
- *
231
- * Fatal errors include:
232
- * - Process not running
233
- * - Process exited unexpectedly
234
- * - Pipe errors (EPIPE)
235
- * - Connection reset errors (ECONNRESET)
236
- */
237
- isFatalWorkerError(error) {
238
- if (error instanceof BridgeProtocolError) {
239
- const msg = error.message.toLowerCase();
240
- return (msg.includes('not running') ||
241
- msg.includes('process exited') ||
242
- msg.includes('epipe') ||
243
- msg.includes('econnreset'));
244
- }
245
- return false;
246
- }
247
- /**
248
- * Remove a worker from the pool.
249
- *
250
- * This is called when a worker is detected as dead (crashed, pipe error, etc.).
251
- * The worker's transport is disposed in the background.
252
- */
253
- removeWorker(worker) {
254
- const index = this.workers.indexOf(worker);
255
- if (index !== -1) {
256
- this.workers.splice(index, 1);
257
- // Dispose transport in background - don't await to avoid blocking
258
- worker.transport.dispose().catch(() => {
259
- // Ignore disposal errors for dead workers
260
- });
261
- if (this.state === 'ready') {
262
- this.scheduleReplacementWorker();
263
- }
264
- }
265
- }
266
- // ===========================================================================
267
- // POOL STATISTICS
268
- // ===========================================================================
269
- /**
270
- * Current number of workers in the pool.
271
- */
272
- get workerCount() {
273
- return this.workers.length;
274
- }
275
- /**
276
- * Number of callers waiting in the queue.
277
- */
278
- get queueLength() {
279
- return this.waitQueue.length;
280
- }
281
- /**
282
- * Total number of in-flight requests across all workers.
283
- */
284
- get totalInFlight() {
285
- return this.workers.reduce((sum, w) => sum + w.inFlightCount, 0);
286
- }
287
- // ===========================================================================
288
- // PRIVATE HELPERS
289
- // ===========================================================================
290
- /**
291
- * Find an available worker with capacity for another request.
292
- */
293
- findAvailableWorker() {
294
- return this.workers.find(w => w.inFlightCount < this.options.maxConcurrentPerWorker);
295
- }
296
- getMinimumWorkerDeficit() {
297
- return Math.max(0, this.options.minWorkers - (this.workers.length + this.pendingCreations));
298
- }
299
- isShuttingDown() {
300
- return this.isDisposed || this.state === 'disposing';
301
- }
302
- async fillToMinimumWorkers() {
303
- await this.spawnWorkers(this.getMinimumWorkerDeficit());
304
- }
305
- async spawnWorkers(count) {
306
- if (count === 0) {
307
- return;
308
- }
309
- this.pendingCreations += count;
310
- try {
311
- await Promise.all(Array.from({ length: count }, () => this.spawnWorkerToPool()));
312
- }
313
- finally {
314
- this.pendingCreations = Math.max(0, this.pendingCreations - count);
315
- }
316
- }
317
- /**
318
- * Replace a removed worker in the background so the next caller does not pay
319
- * the full worker cold-start penalty after a timeout or crash.
320
- */
321
- scheduleReplacementWorker() {
322
- if (this.state !== 'ready') {
323
- return;
324
- }
325
- if (this.workers.length + this.pendingCreations >= this.options.maxWorkers) {
326
- return;
327
- }
328
- this.pendingCreations++;
329
- const replacementReady = this.options.onReplacementWorkerReady ?? this.options.onWorkerReady;
330
- this.spawnWorkerToPool(replacementReady)
331
- .catch(() => {
332
- // Ignore background replacement failures. A later acquire() can retry.
333
- })
334
- .finally(() => {
335
- this.pendingCreations = Math.max(0, this.pendingCreations - 1);
336
- });
337
- }
338
- async spawnWorkerToPool(onWorkerReady = this.options.onWorkerReady) {
339
- if (this.isShuttingDown()) {
340
- return;
341
- }
342
- const worker = await this.createWorker(onWorkerReady);
343
- if (this.isShuttingDown()) {
344
- this.removeWorker(worker);
345
- return;
346
- }
347
- this.publishAvailableWorker(worker);
348
- }
349
- publishAvailableWorker(worker) {
350
- while (this.waitQueue.length > 0 &&
351
- worker.inFlightCount < this.options.maxConcurrentPerWorker) {
352
- const waiter = this.waitQueue.shift();
353
- if (!waiter) {
354
- return;
355
- }
356
- clearTimeout(waiter.timer);
357
- worker.inFlightCount++;
358
- waiter.resolve(worker);
359
- }
360
- }
361
- /**
362
- * Create a new worker and add it to the pool.
363
- *
364
- * If onWorkerReady is configured, calls it after the transport is initialized.
365
- * This is useful for per-worker warmup (importing modules, running setup).
366
- */
367
- async createWorker(onWorkerReady = this.options.onWorkerReady) {
368
- const transport = this.options.createTransport();
369
- // Initialize the transport
370
- await transport.init();
371
- const worker = {
372
- transport,
373
- inFlightCount: 0,
374
- };
375
- try {
376
- // Call onWorkerReady callback if provided
377
- if (onWorkerReady) {
378
- await onWorkerReady(worker);
379
- }
380
- }
381
- catch (error) {
382
- // Ensure partially initialized workers do not leak when warmup fails.
383
- await transport.dispose().catch(() => {
384
- // Ignore disposal failures during warmup failure handling.
385
- });
386
- throw error;
387
- }
388
- if (this.state === 'disposing' || this.state === 'disposed') {
389
- await transport.dispose().catch(() => {
390
- // Ignore disposal failures if the pool was torn down mid-creation.
391
- });
392
- throw new BridgeExecutionError('Pool disposed during worker creation');
393
- }
394
- this.workers.push(worker);
395
- return worker;
396
- }
397
- /**
398
- * Wait in queue for a worker to become available.
399
- */
400
- waitForWorker() {
401
- return new Promise((resolve, reject) => {
402
- const timer = setTimeout(() => {
403
- // Remove this waiter from the queue
404
- const index = this.waitQueue.findIndex(w => w.timer === timer);
405
- if (index !== -1) {
406
- this.waitQueue.splice(index, 1);
407
- }
408
- reject(new BridgeTimeoutError(`Timed out waiting for available worker after ${this.options.queueTimeoutMs}ms`));
409
- }, this.options.queueTimeoutMs);
410
- // Unref the timer so it doesn't keep the Node.js process alive
411
- if (typeof timer.unref === 'function') {
412
- timer.unref();
413
- }
414
- this.waitQueue.push({ resolve, reject, timer });
415
- });
416
- }
417
- }
418
- //# sourceMappingURL=transport-pool.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transport-pool.js","sourceRoot":"","sources":["../../src/runtime/transport-pool.ts"],"names":[],"mappings":"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"}