agent-web-interface 4.1.1 → 4.2.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/dist/src/browser/session-manager.d.ts +28 -1
- package/dist/src/browser/session-manager.d.ts.map +1 -1
- package/dist/src/browser/session-manager.js +73 -0
- package/dist/src/browser/session-manager.js.map +1 -1
- package/dist/src/index.d.ts +10 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +47 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/server/mcp-server.d.ts +14 -1
- package/dist/src/server/mcp-server.d.ts.map +1 -1
- package/dist/src/server/mcp-server.js +21 -6
- package/dist/src/server/mcp-server.js.map +1 -1
- package/dist/src/server/session-store.d.ts +18 -3
- package/dist/src/server/session-store.d.ts.map +1 -1
- package/dist/src/server/session-store.js +27 -3
- package/dist/src/server/session-store.js.map +1 -1
- package/dist/src/session/session-worker-binding.d.ts +57 -0
- package/dist/src/session/session-worker-binding.d.ts.map +1 -0
- package/dist/src/session/session-worker-binding.js +109 -0
- package/dist/src/session/session-worker-binding.js.map +1 -0
- package/dist/src/shared/services/logging.service.d.ts +8 -0
- package/dist/src/shared/services/logging.service.d.ts.map +1 -1
- package/dist/src/shared/services/logging.service.js +10 -0
- package/dist/src/shared/services/logging.service.js.map +1 -1
- package/dist/src/snapshot/snapshot-compiler.d.ts.map +1 -1
- package/dist/src/snapshot/snapshot-compiler.js +68 -1
- package/dist/src/snapshot/snapshot-compiler.js.map +1 -1
- package/dist/src/tools/tool-schemas.d.ts +22 -22
- package/dist/src/tools/tool-schemas.d.ts.map +1 -1
- package/dist/src/tools/tool-schemas.js.map +1 -1
- package/dist/src/worker/chrome-worker-process.d.ts +123 -0
- package/dist/src/worker/chrome-worker-process.d.ts.map +1 -0
- package/dist/src/worker/chrome-worker-process.js +294 -0
- package/dist/src/worker/chrome-worker-process.js.map +1 -0
- package/dist/src/worker/errors/index.d.ts +5 -0
- package/dist/src/worker/errors/index.d.ts.map +1 -0
- package/dist/src/worker/errors/index.js +5 -0
- package/dist/src/worker/errors/index.js.map +1 -0
- package/dist/src/worker/errors/worker.error.d.ts +122 -0
- package/dist/src/worker/errors/worker.error.d.ts.map +1 -0
- package/dist/src/worker/errors/worker.error.js +199 -0
- package/dist/src/worker/errors/worker.error.js.map +1 -0
- package/dist/src/worker/health-monitor.d.ts +141 -0
- package/dist/src/worker/health-monitor.d.ts.map +1 -0
- package/dist/src/worker/health-monitor.js +260 -0
- package/dist/src/worker/health-monitor.js.map +1 -0
- package/dist/src/worker/index.d.ts +16 -0
- package/dist/src/worker/index.d.ts.map +1 -0
- package/dist/src/worker/index.js +19 -0
- package/dist/src/worker/index.js.map +1 -0
- package/dist/src/worker/lease-manager.d.ts +137 -0
- package/dist/src/worker/lease-manager.d.ts.map +1 -0
- package/dist/src/worker/lease-manager.js +334 -0
- package/dist/src/worker/lease-manager.js.map +1 -0
- package/dist/src/worker/multi-tenant-config.d.ts +46 -0
- package/dist/src/worker/multi-tenant-config.d.ts.map +1 -0
- package/dist/src/worker/multi-tenant-config.js +94 -0
- package/dist/src/worker/multi-tenant-config.js.map +1 -0
- package/dist/src/worker/port-allocator.d.ts +96 -0
- package/dist/src/worker/port-allocator.d.ts.map +1 -0
- package/dist/src/worker/port-allocator.js +153 -0
- package/dist/src/worker/port-allocator.js.map +1 -0
- package/dist/src/worker/types.d.ts +218 -0
- package/dist/src/worker/types.d.ts.map +1 -0
- package/dist/src/worker/types.js +38 -0
- package/dist/src/worker/types.js.map +1 -0
- package/dist/src/worker/worker-manager.d.ts +157 -0
- package/dist/src/worker/worker-manager.d.ts.map +1 -0
- package/dist/src/worker/worker-manager.js +500 -0
- package/dist/src/worker/worker-manager.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lease Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages exclusive leases for worker access.
|
|
5
|
+
* Each tenant can hold at most one lease at a time.
|
|
6
|
+
*/
|
|
7
|
+
import { randomUUID } from 'crypto';
|
|
8
|
+
import { WorkerError } from './errors/index.js';
|
|
9
|
+
import { createLogger } from '../shared/services/logging.service.js';
|
|
10
|
+
const logger = createLogger('LeaseManager');
|
|
11
|
+
/**
|
|
12
|
+
* Manages exclusive leases for tenant workers.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const leaseManager = new LeaseManager({ defaultTtlMs: 300000 });
|
|
17
|
+
*
|
|
18
|
+
* // Acquire a lease
|
|
19
|
+
* const result = leaseManager.acquire('tenant-a', 'controller-1', 'w-123');
|
|
20
|
+
* if (result.success) {
|
|
21
|
+
* console.log(`Lease acquired: ${result.lease.leaseId}`);
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* // Refresh the lease before it expires
|
|
25
|
+
* leaseManager.refresh('tenant-a');
|
|
26
|
+
*
|
|
27
|
+
* // Release when done
|
|
28
|
+
* leaseManager.release('tenant-a');
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export class LeaseManager {
|
|
32
|
+
defaultTtlMs;
|
|
33
|
+
leases = new Map();
|
|
34
|
+
cleanupIntervalId = null;
|
|
35
|
+
/** Callbacks for lease expiration */
|
|
36
|
+
onLeaseExpiredCallbacks = [];
|
|
37
|
+
/** Callbacks for lease revocation */
|
|
38
|
+
onLeaseRevokedCallbacks = [];
|
|
39
|
+
constructor(config) {
|
|
40
|
+
this.defaultTtlMs = config.defaultTtlMs;
|
|
41
|
+
// Start cleanup interval if specified
|
|
42
|
+
if (config.cleanupIntervalMs && config.cleanupIntervalMs > 0) {
|
|
43
|
+
this.startCleanupInterval(config.cleanupIntervalMs);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get number of active leases
|
|
48
|
+
*/
|
|
49
|
+
get leaseCount() {
|
|
50
|
+
return this.leases.size;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Acquire a lease for a tenant
|
|
54
|
+
*
|
|
55
|
+
* @param tenantId - Tenant identifier
|
|
56
|
+
* @param controllerId - Controller/session identifier
|
|
57
|
+
* @param workerId - Worker to lease
|
|
58
|
+
* @param ttlMs - Optional custom TTL (uses default if not specified)
|
|
59
|
+
* @returns Lease acquisition result
|
|
60
|
+
*/
|
|
61
|
+
acquire(tenantId, controllerId, workerId, ttlMs) {
|
|
62
|
+
const existingLease = this.leases.get(tenantId);
|
|
63
|
+
// Check if lease already exists
|
|
64
|
+
if (existingLease) {
|
|
65
|
+
// If same controller, just refresh
|
|
66
|
+
if (existingLease.controllerId === controllerId) {
|
|
67
|
+
this.refreshLease(existingLease, ttlMs);
|
|
68
|
+
return {
|
|
69
|
+
success: true,
|
|
70
|
+
lease: existingLease,
|
|
71
|
+
workerId: existingLease.workerId,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// Different controller - check if lease is still active
|
|
75
|
+
if (existingLease.status === 'active' && existingLease.expiresAt > Date.now()) {
|
|
76
|
+
logger.debug('Lease acquisition blocked - held by different controller', {
|
|
77
|
+
tenantId,
|
|
78
|
+
controllerId,
|
|
79
|
+
heldBy: existingLease.controllerId,
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
error: 'Lease is held by another controller',
|
|
84
|
+
errorCode: 'LEASE_ALREADY_HELD',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// Lease expired - clean it up and allow new acquisition
|
|
88
|
+
this.leases.delete(tenantId);
|
|
89
|
+
}
|
|
90
|
+
// Create new lease
|
|
91
|
+
const now = Date.now();
|
|
92
|
+
const lease = {
|
|
93
|
+
leaseId: randomUUID(),
|
|
94
|
+
tenantId,
|
|
95
|
+
workerId,
|
|
96
|
+
controllerId,
|
|
97
|
+
acquiredAt: now,
|
|
98
|
+
expiresAt: now + (ttlMs ?? this.defaultTtlMs),
|
|
99
|
+
status: 'active',
|
|
100
|
+
};
|
|
101
|
+
this.leases.set(tenantId, lease);
|
|
102
|
+
logger.info('Lease acquired', {
|
|
103
|
+
leaseId: lease.leaseId,
|
|
104
|
+
tenantId,
|
|
105
|
+
controllerId,
|
|
106
|
+
workerId,
|
|
107
|
+
ttlMs: ttlMs ?? this.defaultTtlMs,
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
success: true,
|
|
111
|
+
lease,
|
|
112
|
+
workerId,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Release a lease
|
|
117
|
+
*
|
|
118
|
+
* @param tenantId - Tenant identifier
|
|
119
|
+
* @param controllerId - Optional controller ID to validate ownership
|
|
120
|
+
* @returns true if lease was released
|
|
121
|
+
*/
|
|
122
|
+
release(tenantId, controllerId) {
|
|
123
|
+
const lease = this.leases.get(tenantId);
|
|
124
|
+
if (!lease) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
// Validate controller ownership if specified
|
|
128
|
+
if (controllerId && lease.controllerId !== controllerId) {
|
|
129
|
+
logger.debug('Lease release rejected - wrong controller', {
|
|
130
|
+
tenantId,
|
|
131
|
+
controllerId,
|
|
132
|
+
actualController: lease.controllerId,
|
|
133
|
+
});
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
this.leases.delete(tenantId);
|
|
137
|
+
logger.info('Lease released', {
|
|
138
|
+
leaseId: lease.leaseId,
|
|
139
|
+
tenantId,
|
|
140
|
+
controllerId: lease.controllerId,
|
|
141
|
+
});
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Refresh a lease to extend its TTL
|
|
146
|
+
*
|
|
147
|
+
* @param tenantId - Tenant identifier
|
|
148
|
+
* @param ttlMs - Optional new TTL (uses default if not specified)
|
|
149
|
+
* @returns true if lease was refreshed
|
|
150
|
+
* @throws WorkerError if lease not found or expired
|
|
151
|
+
*/
|
|
152
|
+
refresh(tenantId, ttlMs) {
|
|
153
|
+
const lease = this.leases.get(tenantId);
|
|
154
|
+
if (!lease) {
|
|
155
|
+
throw WorkerError.leaseNotFound(tenantId);
|
|
156
|
+
}
|
|
157
|
+
if (lease.status !== 'active') {
|
|
158
|
+
throw WorkerError.leaseExpired(tenantId, lease.expiresAt);
|
|
159
|
+
}
|
|
160
|
+
if (lease.expiresAt <= Date.now()) {
|
|
161
|
+
lease.status = 'expired';
|
|
162
|
+
throw WorkerError.leaseExpired(tenantId, lease.expiresAt);
|
|
163
|
+
}
|
|
164
|
+
this.refreshLease(lease, ttlMs);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Revoke a lease (typically on worker crash)
|
|
169
|
+
*
|
|
170
|
+
* @param tenantId - Tenant identifier
|
|
171
|
+
* @param reason - Reason for revocation
|
|
172
|
+
*/
|
|
173
|
+
revoke(tenantId, reason) {
|
|
174
|
+
const lease = this.leases.get(tenantId);
|
|
175
|
+
if (!lease) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
lease.status = 'revoked';
|
|
179
|
+
this.leases.delete(tenantId);
|
|
180
|
+
logger.info('Lease revoked', {
|
|
181
|
+
leaseId: lease.leaseId,
|
|
182
|
+
tenantId,
|
|
183
|
+
reason,
|
|
184
|
+
});
|
|
185
|
+
// Notify callbacks
|
|
186
|
+
for (const callback of this.onLeaseRevokedCallbacks) {
|
|
187
|
+
try {
|
|
188
|
+
callback(lease, reason);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
logger.error('Error in lease revoked callback', err instanceof Error ? err : undefined, {
|
|
192
|
+
errorMessage: String(err),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Check if a tenant has an active lease
|
|
199
|
+
*/
|
|
200
|
+
hasLease(tenantId) {
|
|
201
|
+
const lease = this.leases.get(tenantId);
|
|
202
|
+
if (!lease)
|
|
203
|
+
return false;
|
|
204
|
+
// Check if expired
|
|
205
|
+
if (lease.expiresAt <= Date.now()) {
|
|
206
|
+
lease.status = 'expired';
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
return lease.status === 'active';
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get the lease for a tenant (if any)
|
|
213
|
+
*/
|
|
214
|
+
getLease(tenantId) {
|
|
215
|
+
return this.leases.get(tenantId);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Get the lease holder (controller) for a tenant
|
|
219
|
+
*/
|
|
220
|
+
getLeaseHolder(tenantId) {
|
|
221
|
+
const lease = this.leases.get(tenantId);
|
|
222
|
+
return lease?.controllerId;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Check if a specific controller holds the lease for a tenant
|
|
226
|
+
*/
|
|
227
|
+
isLeaseHeldBy(tenantId, controllerId) {
|
|
228
|
+
const lease = this.leases.get(tenantId);
|
|
229
|
+
if (!lease)
|
|
230
|
+
return false;
|
|
231
|
+
if (lease.expiresAt <= Date.now()) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
return lease.status === 'active' && lease.controllerId === controllerId;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Get the worker ID for a tenant's lease
|
|
238
|
+
*/
|
|
239
|
+
getWorkerIdForTenant(tenantId) {
|
|
240
|
+
const lease = this.leases.get(tenantId);
|
|
241
|
+
if (lease?.status !== 'active' || lease.expiresAt <= Date.now()) {
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
return lease.workerId;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Register a callback for lease expiration
|
|
248
|
+
*/
|
|
249
|
+
onLeaseExpired(callback) {
|
|
250
|
+
this.onLeaseExpiredCallbacks.push(callback);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Register a callback for lease revocation
|
|
254
|
+
*/
|
|
255
|
+
onLeaseRevoked(callback) {
|
|
256
|
+
this.onLeaseRevokedCallbacks.push(callback);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Clean up expired leases
|
|
260
|
+
*/
|
|
261
|
+
cleanupExpired() {
|
|
262
|
+
const now = Date.now();
|
|
263
|
+
let cleaned = 0;
|
|
264
|
+
for (const [tenantId, lease] of this.leases.entries()) {
|
|
265
|
+
if (lease.status === 'active' && lease.expiresAt <= now) {
|
|
266
|
+
lease.status = 'expired';
|
|
267
|
+
this.leases.delete(tenantId);
|
|
268
|
+
cleaned++;
|
|
269
|
+
logger.info('Lease expired', {
|
|
270
|
+
leaseId: lease.leaseId,
|
|
271
|
+
tenantId,
|
|
272
|
+
controllerId: lease.controllerId,
|
|
273
|
+
});
|
|
274
|
+
// Notify callbacks
|
|
275
|
+
for (const callback of this.onLeaseExpiredCallbacks) {
|
|
276
|
+
try {
|
|
277
|
+
callback(lease);
|
|
278
|
+
}
|
|
279
|
+
catch (err) {
|
|
280
|
+
logger.error('Error in lease expired callback', err instanceof Error ? err : undefined, {
|
|
281
|
+
errorMessage: String(err),
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return cleaned;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Get all active leases
|
|
291
|
+
*/
|
|
292
|
+
getAllLeases() {
|
|
293
|
+
return Array.from(this.leases.values());
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Clear all leases
|
|
297
|
+
*/
|
|
298
|
+
clear() {
|
|
299
|
+
this.leases.clear();
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Stop the cleanup interval
|
|
303
|
+
*/
|
|
304
|
+
stop() {
|
|
305
|
+
if (this.cleanupIntervalId) {
|
|
306
|
+
clearInterval(this.cleanupIntervalId);
|
|
307
|
+
this.cleanupIntervalId = null;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Internal: refresh lease TTL
|
|
312
|
+
*/
|
|
313
|
+
refreshLease(lease, ttlMs) {
|
|
314
|
+
const now = Date.now();
|
|
315
|
+
lease.expiresAt = now + (ttlMs ?? this.defaultTtlMs);
|
|
316
|
+
logger.debug('Lease refreshed', {
|
|
317
|
+
leaseId: lease.leaseId,
|
|
318
|
+
tenantId: lease.tenantId,
|
|
319
|
+
newExpiresAt: lease.expiresAt,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Internal: start cleanup interval
|
|
324
|
+
*/
|
|
325
|
+
startCleanupInterval(intervalMs) {
|
|
326
|
+
this.cleanupIntervalId = setInterval(() => {
|
|
327
|
+
const cleaned = this.cleanupExpired();
|
|
328
|
+
if (cleaned > 0) {
|
|
329
|
+
logger.debug('Cleaned up expired leases', { count: cleaned });
|
|
330
|
+
}
|
|
331
|
+
}, intervalMs);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
//# sourceMappingURL=lease-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease-manager.js","sourceRoot":"","sources":["../../../src/worker/lease-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Tenant Configuration
|
|
3
|
+
*
|
|
4
|
+
* Parses and validates environment variables for multi-tenant mode.
|
|
5
|
+
*/
|
|
6
|
+
import { type WorkerManagerConfig } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Multi-tenant mode configuration
|
|
9
|
+
*/
|
|
10
|
+
export interface MultiTenantConfig {
|
|
11
|
+
/** Whether multi-tenant mode is enabled */
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
/** Tenant identifier (required when enabled) */
|
|
14
|
+
tenantId: string;
|
|
15
|
+
/** Controller/session identifier (auto-generated if not provided) */
|
|
16
|
+
controllerId: string;
|
|
17
|
+
/** WorkerManager configuration */
|
|
18
|
+
workerConfig: WorkerManagerConfig;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Parse and validate multi-tenant configuration from environment variables.
|
|
22
|
+
*
|
|
23
|
+
* Environment variables:
|
|
24
|
+
* - MULTI_TENANT_MODE: Enable multi-tenant mode (true/false)
|
|
25
|
+
* - TENANT_ID: Unique tenant identifier (required when enabled)
|
|
26
|
+
* - CONTROLLER_ID: Session/controller ID (auto-generated if not provided)
|
|
27
|
+
* - WORKER_PROFILE_DIR: Base directory for Chrome profiles (default: /tmp/athena-workers)
|
|
28
|
+
* - WORKER_IDLE_TIMEOUT_MS: Idle worker timeout (default: 300000 = 5 min)
|
|
29
|
+
* - WORKER_HARD_TTL_MS: Max worker runtime (default: 7200000 = 2 hrs)
|
|
30
|
+
* - WORKER_LEASE_TTL_MS: Lease TTL (default: 300000 = 5 min)
|
|
31
|
+
* - WORKER_HEALTH_CHECK_INTERVAL_MS: Health check interval (default: 30000 = 30 sec)
|
|
32
|
+
* - WORKER_PORT_MIN: Minimum CDP port (default: 9300)
|
|
33
|
+
* - WORKER_PORT_MAX: Maximum CDP port (default: 9399)
|
|
34
|
+
* - WORKER_MAX_COUNT: Maximum concurrent workers (default: 100)
|
|
35
|
+
* - CHROME_PATH: Path to Chrome executable (auto-detected if not set)
|
|
36
|
+
*
|
|
37
|
+
* @returns Multi-tenant configuration
|
|
38
|
+
* @throws Error if MULTI_TENANT_MODE is true but TENANT_ID is not provided
|
|
39
|
+
*/
|
|
40
|
+
export declare function getMultiTenantConfig(): MultiTenantConfig;
|
|
41
|
+
/**
|
|
42
|
+
* Validate that multi-tenant config is properly set up.
|
|
43
|
+
* Logs warnings for common misconfigurations.
|
|
44
|
+
*/
|
|
45
|
+
export declare function validateMultiTenantConfig(config: MultiTenantConfig): void;
|
|
46
|
+
//# sourceMappingURL=multi-tenant-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-tenant-config.d.ts","sourceRoot":"","sources":["../../../src/worker/multi-tenant-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAyB,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,YAAY,EAAE,mBAAmB,CAAC;CACnC;AAYD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,IAAI,iBAAiB,CA8CxD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAiBzE"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Tenant Configuration
|
|
3
|
+
*
|
|
4
|
+
* Parses and validates environment variables for multi-tenant mode.
|
|
5
|
+
*/
|
|
6
|
+
import { randomUUID } from 'crypto';
|
|
7
|
+
import { DEFAULT_WORKER_CONFIG } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Parse integer from environment variable with default
|
|
10
|
+
*/
|
|
11
|
+
function parseIntEnv(name, defaultValue) {
|
|
12
|
+
const value = process.env[name];
|
|
13
|
+
if (!value)
|
|
14
|
+
return defaultValue;
|
|
15
|
+
const parsed = parseInt(value, 10);
|
|
16
|
+
return isNaN(parsed) ? defaultValue : parsed;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse and validate multi-tenant configuration from environment variables.
|
|
20
|
+
*
|
|
21
|
+
* Environment variables:
|
|
22
|
+
* - MULTI_TENANT_MODE: Enable multi-tenant mode (true/false)
|
|
23
|
+
* - TENANT_ID: Unique tenant identifier (required when enabled)
|
|
24
|
+
* - CONTROLLER_ID: Session/controller ID (auto-generated if not provided)
|
|
25
|
+
* - WORKER_PROFILE_DIR: Base directory for Chrome profiles (default: /tmp/athena-workers)
|
|
26
|
+
* - WORKER_IDLE_TIMEOUT_MS: Idle worker timeout (default: 300000 = 5 min)
|
|
27
|
+
* - WORKER_HARD_TTL_MS: Max worker runtime (default: 7200000 = 2 hrs)
|
|
28
|
+
* - WORKER_LEASE_TTL_MS: Lease TTL (default: 300000 = 5 min)
|
|
29
|
+
* - WORKER_HEALTH_CHECK_INTERVAL_MS: Health check interval (default: 30000 = 30 sec)
|
|
30
|
+
* - WORKER_PORT_MIN: Minimum CDP port (default: 9300)
|
|
31
|
+
* - WORKER_PORT_MAX: Maximum CDP port (default: 9399)
|
|
32
|
+
* - WORKER_MAX_COUNT: Maximum concurrent workers (default: 100)
|
|
33
|
+
* - CHROME_PATH: Path to Chrome executable (auto-detected if not set)
|
|
34
|
+
*
|
|
35
|
+
* @returns Multi-tenant configuration
|
|
36
|
+
* @throws Error if MULTI_TENANT_MODE is true but TENANT_ID is not provided
|
|
37
|
+
*/
|
|
38
|
+
export function getMultiTenantConfig() {
|
|
39
|
+
const enabled = process.env.MULTI_TENANT_MODE === 'true';
|
|
40
|
+
if (!enabled) {
|
|
41
|
+
return {
|
|
42
|
+
enabled: false,
|
|
43
|
+
tenantId: '',
|
|
44
|
+
controllerId: '',
|
|
45
|
+
workerConfig: {
|
|
46
|
+
profileBaseDir: '/tmp/athena-workers',
|
|
47
|
+
...DEFAULT_WORKER_CONFIG,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const tenantId = process.env.TENANT_ID;
|
|
52
|
+
if (!tenantId) {
|
|
53
|
+
throw new Error('TENANT_ID environment variable is required when MULTI_TENANT_MODE is enabled');
|
|
54
|
+
}
|
|
55
|
+
const controllerId = process.env.CONTROLLER_ID ?? `ctrl-${randomUUID().substring(0, 8)}`;
|
|
56
|
+
const profileBaseDir = process.env.WORKER_PROFILE_DIR ?? '/tmp/athena-workers';
|
|
57
|
+
const workerConfig = {
|
|
58
|
+
profileBaseDir,
|
|
59
|
+
idleTimeoutMs: parseIntEnv('WORKER_IDLE_TIMEOUT_MS', DEFAULT_WORKER_CONFIG.idleTimeoutMs),
|
|
60
|
+
hardTtlMs: parseIntEnv('WORKER_HARD_TTL_MS', DEFAULT_WORKER_CONFIG.hardTtlMs),
|
|
61
|
+
leaseTtlMs: parseIntEnv('WORKER_LEASE_TTL_MS', DEFAULT_WORKER_CONFIG.leaseTtlMs),
|
|
62
|
+
healthCheckIntervalMs: parseIntEnv('WORKER_HEALTH_CHECK_INTERVAL_MS', DEFAULT_WORKER_CONFIG.healthCheckIntervalMs),
|
|
63
|
+
portRange: {
|
|
64
|
+
min: parseIntEnv('WORKER_PORT_MIN', DEFAULT_WORKER_CONFIG.portRange.min),
|
|
65
|
+
max: parseIntEnv('WORKER_PORT_MAX', DEFAULT_WORKER_CONFIG.portRange.max),
|
|
66
|
+
},
|
|
67
|
+
maxWorkers: parseIntEnv('WORKER_MAX_COUNT', DEFAULT_WORKER_CONFIG.maxWorkers),
|
|
68
|
+
chromePath: process.env.CHROME_PATH,
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
enabled,
|
|
72
|
+
tenantId,
|
|
73
|
+
controllerId,
|
|
74
|
+
workerConfig,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Validate that multi-tenant config is properly set up.
|
|
79
|
+
* Logs warnings for common misconfigurations.
|
|
80
|
+
*/
|
|
81
|
+
export function validateMultiTenantConfig(config) {
|
|
82
|
+
if (!config.enabled)
|
|
83
|
+
return;
|
|
84
|
+
// Check port range validity
|
|
85
|
+
if (config.workerConfig.portRange.min > config.workerConfig.portRange.max) {
|
|
86
|
+
throw new Error(`Invalid port range: WORKER_PORT_MIN (${config.workerConfig.portRange.min}) > WORKER_PORT_MAX (${config.workerConfig.portRange.max})`);
|
|
87
|
+
}
|
|
88
|
+
// Check maxWorkers fits in port range
|
|
89
|
+
const portCapacity = config.workerConfig.portRange.max - config.workerConfig.portRange.min + 1;
|
|
90
|
+
if (config.workerConfig.maxWorkers > portCapacity) {
|
|
91
|
+
console.warn(`[WARN] WORKER_MAX_COUNT (${config.workerConfig.maxWorkers}) exceeds port range capacity (${portCapacity}). Effective limit will be ${portCapacity}.`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=multi-tenant-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-tenant-config.js","sourceRoot":"","sources":["../../../src/worker/multi-tenant-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port Allocator
|
|
3
|
+
*
|
|
4
|
+
* Manages allocation and release of ports for Chrome CDP endpoints.
|
|
5
|
+
* Tracks which ports are in use and provides the next available port.
|
|
6
|
+
*/
|
|
7
|
+
import type { PortRange } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for PortAllocator
|
|
10
|
+
*/
|
|
11
|
+
export interface PortAllocatorConfig {
|
|
12
|
+
/** Minimum port number (inclusive) */
|
|
13
|
+
min: number;
|
|
14
|
+
/** Maximum port number (inclusive) */
|
|
15
|
+
max: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Manages port allocation for Chrome CDP endpoints.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const allocator = new PortAllocator({ min: 9300, max: 9399 });
|
|
23
|
+
*
|
|
24
|
+
* const port1 = allocator.allocate(); // 9300
|
|
25
|
+
* const port2 = allocator.allocate(); // 9301
|
|
26
|
+
*
|
|
27
|
+
* allocator.release(port1); // Return 9300 to pool
|
|
28
|
+
* const port3 = allocator.allocate(); // 9300 (reused)
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class PortAllocator {
|
|
32
|
+
private readonly min;
|
|
33
|
+
private readonly max;
|
|
34
|
+
private readonly allocatedPorts;
|
|
35
|
+
constructor(config: PortAllocatorConfig);
|
|
36
|
+
/**
|
|
37
|
+
* Get the port range configuration
|
|
38
|
+
*/
|
|
39
|
+
get portRange(): PortRange;
|
|
40
|
+
/**
|
|
41
|
+
* Get the number of currently allocated ports
|
|
42
|
+
*/
|
|
43
|
+
get allocatedCount(): number;
|
|
44
|
+
/**
|
|
45
|
+
* Get the total capacity (max possible allocations)
|
|
46
|
+
*/
|
|
47
|
+
get capacity(): number;
|
|
48
|
+
/**
|
|
49
|
+
* Allocate the next available port.
|
|
50
|
+
*
|
|
51
|
+
* @returns The allocated port number
|
|
52
|
+
* @throws WorkerError with PORT_EXHAUSTED if no ports are available
|
|
53
|
+
*/
|
|
54
|
+
allocate(): number;
|
|
55
|
+
/**
|
|
56
|
+
* Release a previously allocated port back to the pool.
|
|
57
|
+
*
|
|
58
|
+
* @param port - The port number to release
|
|
59
|
+
* @returns true if the port was released, false if it wasn't allocated
|
|
60
|
+
*/
|
|
61
|
+
release(port: number): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Check if a specific port is currently allocated.
|
|
64
|
+
*
|
|
65
|
+
* @param port - The port number to check
|
|
66
|
+
* @returns true if the port is allocated
|
|
67
|
+
*/
|
|
68
|
+
isAllocated(port: number): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Check if a port is available for use by attempting to bind to it.
|
|
71
|
+
* This verifies that no other process is using the port.
|
|
72
|
+
*
|
|
73
|
+
* @param port - The port number to check
|
|
74
|
+
* @returns Promise that resolves to true if the port is available
|
|
75
|
+
*/
|
|
76
|
+
isPortAvailable(port: number): Promise<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* Allocate a port that is verified to be available on the system.
|
|
79
|
+
* This is slower than allocate() but ensures the port can actually be used.
|
|
80
|
+
*
|
|
81
|
+
* @returns Promise that resolves to the allocated port number
|
|
82
|
+
* @throws WorkerError with PORT_EXHAUSTED if no available ports are found
|
|
83
|
+
*/
|
|
84
|
+
allocateVerified(): Promise<number>;
|
|
85
|
+
/**
|
|
86
|
+
* Get all currently allocated ports.
|
|
87
|
+
*
|
|
88
|
+
* @returns Array of allocated port numbers
|
|
89
|
+
*/
|
|
90
|
+
getAllocatedPorts(): number[];
|
|
91
|
+
/**
|
|
92
|
+
* Reset the allocator, releasing all ports.
|
|
93
|
+
*/
|
|
94
|
+
reset(): void;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=port-allocator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port-allocator.d.ts","sourceRoot":"","sources":["../../../src/worker/port-allocator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;gBAExC,MAAM,EAAE,mBAAmB;IAWvC;;OAEG;IACH,IAAI,SAAS,IAAI,SAAS,CAEzB;IAED;;OAEG;IACH,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;;;;OAKG;IACH,QAAQ,IAAI,MAAM;IAclB;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9B;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIlC;;;;;;OAMG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkBrD;;;;;;OAMG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAqBzC;;;;OAIG;IACH,iBAAiB,IAAI,MAAM,EAAE;IAI7B;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
|