@soulcraft/brainy 0.53.0 → 0.54.1

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/index.d.ts CHANGED
@@ -10,8 +10,11 @@ export { euclideanDistance, cosineDistance, manhattanDistance, dotProductDistanc
10
10
  import { UniversalSentenceEncoder, TransformerEmbedding, createEmbeddingFunction, defaultEmbeddingFunction, batchEmbed, embeddingFunctions } from './utils/embedding.js';
11
11
  import { executeInThread, cleanupWorkerPools } from './utils/workerUtils.js';
12
12
  import { logger, LogLevel, configureLogger, createModuleLogger } from './utils/logger.js';
13
+ import { getGlobalSocketManager, AdaptiveSocketManager } from './utils/adaptiveSocketManager.js';
14
+ import { getGlobalBackpressure, AdaptiveBackpressure } from './utils/adaptiveBackpressure.js';
15
+ import { getGlobalPerformanceMonitor, PerformanceMonitor } from './utils/performanceMonitor.js';
13
16
  import { isBrowser, isNode, isWebWorker, areWebWorkersAvailable, areWorkerThreadsAvailable, areWorkerThreadsAvailableSync, isThreadingAvailable, isThreadingAvailableAsync } from './utils/environment.js';
14
- export { UniversalSentenceEncoder, TransformerEmbedding, createEmbeddingFunction, defaultEmbeddingFunction, batchEmbed, embeddingFunctions, executeInThread, cleanupWorkerPools, isBrowser, isNode, isWebWorker, areWebWorkersAvailable, areWorkerThreadsAvailable, areWorkerThreadsAvailableSync, isThreadingAvailable, isThreadingAvailableAsync, logger, LogLevel, configureLogger, createModuleLogger };
17
+ export { UniversalSentenceEncoder, TransformerEmbedding, createEmbeddingFunction, defaultEmbeddingFunction, batchEmbed, embeddingFunctions, executeInThread, cleanupWorkerPools, isBrowser, isNode, isWebWorker, areWebWorkersAvailable, areWorkerThreadsAvailable, areWorkerThreadsAvailableSync, isThreadingAvailable, isThreadingAvailableAsync, logger, LogLevel, configureLogger, createModuleLogger, getGlobalSocketManager, AdaptiveSocketManager, getGlobalBackpressure, AdaptiveBackpressure, getGlobalPerformanceMonitor, PerformanceMonitor };
15
18
  import { OPFSStorage, MemoryStorage, R2Storage, S3CompatibleStorage, createStorage } from './storage/storageFactory.js';
16
19
  export { OPFSStorage, MemoryStorage, R2Storage, S3CompatibleStorage, createStorage };
17
20
  export { FileSystemStorage } from './storage/adapters/fileSystemStorage.js';
package/dist/index.js CHANGED
@@ -15,6 +15,10 @@ import { UniversalSentenceEncoder, TransformerEmbedding, createEmbeddingFunction
15
15
  import { executeInThread, cleanupWorkerPools } from './utils/workerUtils.js';
16
16
  // Export logging utilities
17
17
  import { logger, LogLevel, configureLogger, createModuleLogger } from './utils/logger.js';
18
+ // Export performance and optimization utilities
19
+ import { getGlobalSocketManager, AdaptiveSocketManager } from './utils/adaptiveSocketManager.js';
20
+ import { getGlobalBackpressure, AdaptiveBackpressure } from './utils/adaptiveBackpressure.js';
21
+ import { getGlobalPerformanceMonitor, PerformanceMonitor } from './utils/performanceMonitor.js';
18
22
  // Export environment utilities
19
23
  import { isBrowser, isNode, isWebWorker, areWebWorkersAvailable, areWorkerThreadsAvailable, areWorkerThreadsAvailableSync, isThreadingAvailable, isThreadingAvailableAsync } from './utils/environment.js';
20
24
  export { UniversalSentenceEncoder, TransformerEmbedding, createEmbeddingFunction, defaultEmbeddingFunction, batchEmbed, embeddingFunctions,
@@ -23,7 +27,9 @@ executeInThread, cleanupWorkerPools,
23
27
  // Environment utilities
24
28
  isBrowser, isNode, isWebWorker, areWebWorkersAvailable, areWorkerThreadsAvailable, areWorkerThreadsAvailableSync, isThreadingAvailable, isThreadingAvailableAsync,
25
29
  // Logging utilities
26
- logger, LogLevel, configureLogger, createModuleLogger };
30
+ logger, LogLevel, configureLogger, createModuleLogger,
31
+ // Performance and optimization utilities
32
+ getGlobalSocketManager, AdaptiveSocketManager, getGlobalBackpressure, AdaptiveBackpressure, getGlobalPerformanceMonitor, PerformanceMonitor };
27
33
  // Export storage adapters
28
34
  import { OPFSStorage, MemoryStorage, R2Storage, S3CompatibleStorage, createStorage } from './storage/storageFactory.js';
29
35
  export { OPFSStorage, MemoryStorage, R2Storage, S3CompatibleStorage, createStorage };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -68,6 +68,14 @@ export declare class S3CompatibleStorage extends BaseStorage {
68
68
  private memoryCheckInterval;
69
69
  private consecutiveErrors;
70
70
  private lastErrorReset;
71
+ private socketManager;
72
+ private backpressure;
73
+ private nounWriteBuffer;
74
+ private verbWriteBuffer;
75
+ private requestCoalescer;
76
+ private highVolumeMode;
77
+ private lastVolumeCheck;
78
+ private volumeCheckInterval;
71
79
  private operationExecutors;
72
80
  private nounCacheManager;
73
81
  private verbCacheManager;
@@ -97,6 +105,42 @@ export declare class S3CompatibleStorage extends BaseStorage {
97
105
  * Initialize the storage adapter
98
106
  */
99
107
  init(): Promise<void>;
108
+ /**
109
+ * Initialize write buffers for high-volume scenarios
110
+ */
111
+ private initializeBuffers;
112
+ /**
113
+ * Initialize request coalescer
114
+ */
115
+ private initializeCoalescer;
116
+ /**
117
+ * Check if we should enable high-volume mode
118
+ */
119
+ private checkVolumeMode;
120
+ /**
121
+ * Bulk write nouns to S3
122
+ */
123
+ private bulkWriteNouns;
124
+ /**
125
+ * Bulk write verbs to S3
126
+ */
127
+ private bulkWriteVerbs;
128
+ /**
129
+ * Process coalesced batch of operations
130
+ */
131
+ private processCoalescedBatch;
132
+ /**
133
+ * Process bulk deletes
134
+ */
135
+ private processBulkDeletes;
136
+ /**
137
+ * Process bulk writes
138
+ */
139
+ private processBulkWrites;
140
+ /**
141
+ * Process bulk reads
142
+ */
143
+ private processBulkReads;
100
144
  /**
101
145
  * Dynamically adjust batch size based on memory pressure and error rates
102
146
  */
@@ -9,6 +9,10 @@ import { StorageOperationExecutors } from '../../utils/operationUtils.js';
9
9
  import { BrainyError } from '../../errors/brainyError.js';
10
10
  import { CacheManager } from '../cacheManager.js';
11
11
  import { createModuleLogger } from '../../utils/logger.js';
12
+ import { getGlobalSocketManager } from '../../utils/adaptiveSocketManager.js';
13
+ import { getGlobalBackpressure } from '../../utils/adaptiveBackpressure.js';
14
+ import { getWriteBuffer } from '../../utils/writeBuffer.js';
15
+ import { getCoalescer } from '../../utils/requestCoalescer.js';
12
16
  // Export R2Storage as an alias for S3CompatibleStorage
13
17
  export { S3CompatibleStorage as R2Storage };
14
18
  /**
@@ -58,6 +62,19 @@ export class S3CompatibleStorage extends BaseStorage {
58
62
  this.memoryCheckInterval = 5000; // Check every 5 seconds
59
63
  this.consecutiveErrors = 0;
60
64
  this.lastErrorReset = Date.now();
65
+ // Adaptive socket manager for automatic optimization
66
+ this.socketManager = getGlobalSocketManager();
67
+ // Adaptive backpressure for automatic flow control
68
+ this.backpressure = getGlobalBackpressure();
69
+ // Write buffers for bulk operations
70
+ this.nounWriteBuffer = null;
71
+ this.verbWriteBuffer = null;
72
+ // Request coalescer for deduplication
73
+ this.requestCoalescer = null;
74
+ // High-volume mode detection
75
+ this.highVolumeMode = false;
76
+ this.lastVolumeCheck = 0;
77
+ this.volumeCheckInterval = 5000;
61
78
  // Module logger
62
79
  this.logger = createModuleLogger('S3Storage');
63
80
  // Node cache to avoid redundant API calls
@@ -104,16 +121,6 @@ export class S3CompatibleStorage extends BaseStorage {
104
121
  try {
105
122
  // Import AWS SDK modules only when needed
106
123
  const { S3Client } = await import('@aws-sdk/client-s3');
107
- const { NodeHttpHandler } = await import('@smithy/node-http-handler');
108
- const https = await import('https');
109
- // Configure HTTP agent with high socket limits for high-volume scenarios
110
- // This prevents socket exhaustion without requiring user configuration
111
- const httpAgent = new https.Agent({
112
- keepAlive: true,
113
- maxSockets: 500, // Increased from default 50 to handle high volume
114
- maxFreeSockets: 100, // Keep more sockets alive for reuse
115
- timeout: 60000 // 60 second timeout
116
- });
117
124
  // Configure the S3 client based on the service type
118
125
  const clientConfig = {
119
126
  region: this.region,
@@ -121,12 +128,8 @@ export class S3CompatibleStorage extends BaseStorage {
121
128
  accessKeyId: this.accessKeyId,
122
129
  secretAccessKey: this.secretAccessKey
123
130
  },
124
- // Use custom HTTP handler with optimized socket management
125
- requestHandler: new NodeHttpHandler({
126
- httpsAgent: httpAgent,
127
- connectionTimeout: 10000, // 10 second connection timeout
128
- socketTimeout: 60000 // 60 second socket timeout
129
- }),
131
+ // Use adaptive socket manager for automatic optimization
132
+ requestHandler: this.socketManager.getHttpHandler(),
130
133
  // Retry configuration for resilience
131
134
  maxAttempts: 5, // Retry up to 5 times
132
135
  retryMode: 'adaptive' // Use adaptive retry with backoff
@@ -222,6 +225,10 @@ export class S3CompatibleStorage extends BaseStorage {
222
225
  // Set storage adapters for cache managers
223
226
  this.nounCacheManager.setStorageAdapters(nounStorageAdapter, nounStorageAdapter);
224
227
  this.verbCacheManager.setStorageAdapters(verbStorageAdapter, verbStorageAdapter);
228
+ // Initialize write buffers for high-volume scenarios
229
+ this.initializeBuffers();
230
+ // Initialize request coalescer
231
+ this.initializeCoalescer();
225
232
  this.isInitialized = true;
226
233
  this.logger.info(`Initialized ${this.serviceType} storage with bucket ${this.bucketName}`);
227
234
  }
@@ -231,64 +238,248 @@ export class S3CompatibleStorage extends BaseStorage {
231
238
  }
232
239
  }
233
240
  /**
234
- * Dynamically adjust batch size based on memory pressure and error rates
241
+ * Initialize write buffers for high-volume scenarios
235
242
  */
236
- adjustBatchSize() {
243
+ initializeBuffers() {
244
+ const storageId = `${this.serviceType}-${this.bucketName}`;
245
+ // Create noun write buffer
246
+ this.nounWriteBuffer = getWriteBuffer(`${storageId}-nouns`, 'noun', async (items) => {
247
+ // Bulk write nouns to S3
248
+ await this.bulkWriteNouns(items);
249
+ });
250
+ // Create verb write buffer
251
+ this.verbWriteBuffer = getWriteBuffer(`${storageId}-verbs`, 'verb', async (items) => {
252
+ // Bulk write verbs to S3
253
+ await this.bulkWriteVerbs(items);
254
+ });
255
+ }
256
+ /**
257
+ * Initialize request coalescer
258
+ */
259
+ initializeCoalescer() {
260
+ const storageId = `${this.serviceType}-${this.bucketName}`;
261
+ this.requestCoalescer = getCoalescer(storageId, async (batch) => {
262
+ // Process coalesced operations
263
+ await this.processCoalescedBatch(batch);
264
+ });
265
+ }
266
+ /**
267
+ * Check if we should enable high-volume mode
268
+ */
269
+ checkVolumeMode() {
237
270
  const now = Date.now();
238
- // Check memory pressure periodically
239
- if (now - this.lastMemoryCheck > this.memoryCheckInterval) {
240
- this.lastMemoryCheck = now;
241
- const memUsage = process.memoryUsage();
242
- const heapUsedPercent = (memUsage.heapUsed / memUsage.heapTotal) * 100;
243
- // Adjust batch size based on memory pressure
244
- if (heapUsedPercent > 80) {
245
- // High memory pressure - reduce batch size
246
- this.currentBatchSize = Math.max(1, Math.floor(this.currentBatchSize * 0.5));
247
- this.maxConcurrentOperations = Math.max(10, Math.floor(this.maxConcurrentOperations * 0.5));
248
- this.logger.warn(`High memory pressure (${heapUsedPercent.toFixed(1)}%), reducing batch size to ${this.currentBatchSize}`);
249
- }
250
- else if (heapUsedPercent < 50 && this.consecutiveErrors === 0) {
251
- // Low memory pressure and no errors - gradually increase batch size
252
- this.currentBatchSize = Math.min(this.baseBatchSize * 2, this.currentBatchSize + 1);
253
- this.maxConcurrentOperations = Math.min(200, this.maxConcurrentOperations + 10);
271
+ if (now - this.lastVolumeCheck < this.volumeCheckInterval) {
272
+ return;
273
+ }
274
+ this.lastVolumeCheck = now;
275
+ // Check pending operations
276
+ const backpressureStatus = this.backpressure.getStatus();
277
+ const socketMetrics = this.socketManager.getMetrics();
278
+ const shouldEnableHighVolume = backpressureStatus.queueLength > 100 ||
279
+ socketMetrics.pendingRequests > 50 ||
280
+ this.pendingOperations > 20;
281
+ if (shouldEnableHighVolume && !this.highVolumeMode) {
282
+ this.highVolumeMode = true;
283
+ this.logger.info('Enabling high-volume mode for optimized batching');
284
+ // Adjust buffer parameters for high volume
285
+ if (this.nounWriteBuffer) {
286
+ this.nounWriteBuffer.adjustForLoad(backpressureStatus.queueLength);
287
+ }
288
+ if (this.verbWriteBuffer) {
289
+ this.verbWriteBuffer.adjustForLoad(backpressureStatus.queueLength);
290
+ }
291
+ if (this.requestCoalescer) {
292
+ this.requestCoalescer.adjustParameters(backpressureStatus.queueLength);
293
+ }
294
+ }
295
+ else if (!shouldEnableHighVolume && this.highVolumeMode) {
296
+ this.highVolumeMode = false;
297
+ this.logger.info('Disabling high-volume mode');
298
+ }
299
+ }
300
+ /**
301
+ * Bulk write nouns to S3
302
+ */
303
+ async bulkWriteNouns(items) {
304
+ const { PutObjectCommand } = await import('@aws-sdk/client-s3');
305
+ // Process in parallel with limited concurrency
306
+ const promises = [];
307
+ const batchSize = 10; // Process 10 at a time
308
+ const entries = Array.from(items.entries());
309
+ for (let i = 0; i < entries.length; i += batchSize) {
310
+ const batch = entries.slice(i, i + batchSize);
311
+ const batchPromise = Promise.all(batch.map(async ([id, node]) => {
312
+ const serializableNode = {
313
+ ...node,
314
+ connections: this.mapToObject(node.connections, (set) => Array.from(set))
315
+ };
316
+ const key = `${this.nounPrefix}${id}.json`;
317
+ const body = JSON.stringify(serializableNode, null, 2);
318
+ await this.s3Client.send(new PutObjectCommand({
319
+ Bucket: this.bucketName,
320
+ Key: key,
321
+ Body: body,
322
+ ContentType: 'application/json'
323
+ }));
324
+ })).then(() => { }); // Convert Promise<void[]> to Promise<void>
325
+ promises.push(batchPromise);
326
+ }
327
+ await Promise.all(promises);
328
+ }
329
+ /**
330
+ * Bulk write verbs to S3
331
+ */
332
+ async bulkWriteVerbs(items) {
333
+ const { PutObjectCommand } = await import('@aws-sdk/client-s3');
334
+ // Process in parallel with limited concurrency
335
+ const promises = [];
336
+ const batchSize = 10;
337
+ const entries = Array.from(items.entries());
338
+ for (let i = 0; i < entries.length; i += batchSize) {
339
+ const batch = entries.slice(i, i + batchSize);
340
+ const batchPromise = Promise.all(batch.map(async ([id, edge]) => {
341
+ const serializableEdge = {
342
+ ...edge,
343
+ connections: this.mapToObject(edge.connections, (set) => Array.from(set))
344
+ };
345
+ const key = `${this.verbPrefix}${id}.json`;
346
+ const body = JSON.stringify(serializableEdge, null, 2);
347
+ await this.s3Client.send(new PutObjectCommand({
348
+ Bucket: this.bucketName,
349
+ Key: key,
350
+ Body: body,
351
+ ContentType: 'application/json'
352
+ }));
353
+ })).then(() => { }); // Convert Promise<void[]> to Promise<void>
354
+ promises.push(batchPromise);
355
+ }
356
+ await Promise.all(promises);
357
+ }
358
+ /**
359
+ * Process coalesced batch of operations
360
+ */
361
+ async processCoalescedBatch(batch) {
362
+ // Group operations by type
363
+ const writes = [];
364
+ const reads = [];
365
+ const deletes = [];
366
+ for (const op of batch) {
367
+ if (op.type === 'write') {
368
+ writes.push(op);
369
+ }
370
+ else if (op.type === 'read') {
371
+ reads.push(op);
254
372
  }
373
+ else if (op.type === 'delete') {
374
+ deletes.push(op);
375
+ }
376
+ }
377
+ // Process in order: deletes, writes, reads
378
+ if (deletes.length > 0) {
379
+ await this.processBulkDeletes(deletes);
380
+ }
381
+ if (writes.length > 0) {
382
+ await this.processBulkWrites(writes);
255
383
  }
384
+ if (reads.length > 0) {
385
+ await this.processBulkReads(reads);
386
+ }
387
+ }
388
+ /**
389
+ * Process bulk deletes
390
+ */
391
+ async processBulkDeletes(deletes) {
392
+ const { DeleteObjectCommand } = await import('@aws-sdk/client-s3');
393
+ await Promise.all(deletes.map(async (op) => {
394
+ await this.s3Client.send(new DeleteObjectCommand({
395
+ Bucket: this.bucketName,
396
+ Key: op.key
397
+ }));
398
+ }));
399
+ }
400
+ /**
401
+ * Process bulk writes
402
+ */
403
+ async processBulkWrites(writes) {
404
+ const { PutObjectCommand } = await import('@aws-sdk/client-s3');
405
+ await Promise.all(writes.map(async (op) => {
406
+ await this.s3Client.send(new PutObjectCommand({
407
+ Bucket: this.bucketName,
408
+ Key: op.key,
409
+ Body: JSON.stringify(op.data),
410
+ ContentType: 'application/json'
411
+ }));
412
+ }));
413
+ }
414
+ /**
415
+ * Process bulk reads
416
+ */
417
+ async processBulkReads(reads) {
418
+ const { GetObjectCommand } = await import('@aws-sdk/client-s3');
419
+ await Promise.all(reads.map(async (op) => {
420
+ try {
421
+ const response = await this.s3Client.send(new GetObjectCommand({
422
+ Bucket: this.bucketName,
423
+ Key: op.key
424
+ }));
425
+ if (response.Body) {
426
+ const data = await response.Body.transformToString();
427
+ op.data = JSON.parse(data);
428
+ }
429
+ }
430
+ catch (error) {
431
+ op.data = null;
432
+ }
433
+ }));
434
+ }
435
+ /**
436
+ * Dynamically adjust batch size based on memory pressure and error rates
437
+ */
438
+ adjustBatchSize() {
439
+ // Let the adaptive socket manager handle batch size optimization
440
+ this.currentBatchSize = this.socketManager.getBatchSize();
441
+ // Get adaptive configuration for concurrent operations
442
+ const config = this.socketManager.getConfig();
443
+ this.maxConcurrentOperations = Math.min(config.maxSockets * 2, 500);
444
+ // Track metrics for the socket manager
445
+ const now = Date.now();
256
446
  // Reset error counter periodically if no recent errors
257
447
  if (now - this.lastErrorReset > 60000 && this.consecutiveErrors > 0) {
258
448
  this.consecutiveErrors = Math.max(0, this.consecutiveErrors - 1);
259
449
  this.lastErrorReset = now;
260
450
  }
261
- // Adjust based on error rate
262
- if (this.consecutiveErrors > 5) {
263
- this.currentBatchSize = Math.max(1, Math.floor(this.currentBatchSize * 0.7));
264
- this.maxConcurrentOperations = Math.max(10, Math.floor(this.maxConcurrentOperations * 0.7));
265
- this.logger.warn(`High error rate, reducing batch size to ${this.currentBatchSize}`);
266
- }
267
451
  }
268
452
  /**
269
453
  * Apply backpressure when system is under load
270
454
  */
271
455
  async applyBackpressure() {
272
- // Wait if too many operations are pending
273
- while (this.pendingOperations >= this.maxConcurrentOperations) {
274
- const memUsage = process.memoryUsage();
275
- const heapUsedPercent = (memUsage.heapUsed / memUsage.heapTotal) * 100;
276
- if (heapUsedPercent > 85) {
277
- // Critical memory pressure - wait longer
278
- await new Promise(resolve => setTimeout(resolve, 100));
279
- }
280
- else {
281
- // Normal backpressure - short wait
282
- await new Promise(resolve => setImmediate(resolve));
283
- }
456
+ // Generate unique request ID for tracking
457
+ const requestId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
458
+ try {
459
+ // Use adaptive backpressure system
460
+ await this.backpressure.requestPermission(requestId, 1);
461
+ // Track with socket manager
462
+ this.socketManager.trackRequestStart(requestId);
463
+ this.pendingOperations++;
464
+ return requestId;
465
+ }
466
+ catch (error) {
467
+ // If backpressure rejects, throw a more informative error
468
+ const message = error instanceof Error ? error.message : String(error);
469
+ throw new Error(`System overloaded: ${message}`);
284
470
  }
285
- this.pendingOperations++;
286
471
  }
287
472
  /**
288
473
  * Release backpressure after operation completes
289
474
  */
290
- releaseBackpressure(success = true) {
475
+ releaseBackpressure(success = true, requestId) {
291
476
  this.pendingOperations = Math.max(0, this.pendingOperations - 1);
477
+ if (requestId) {
478
+ // Track with socket manager
479
+ this.socketManager.trackRequestComplete(requestId, success);
480
+ // Release from backpressure system
481
+ this.backpressure.releasePermission(requestId, success);
482
+ }
292
483
  if (!success) {
293
484
  this.consecutiveErrors++;
294
485
  }
@@ -303,8 +494,8 @@ export class S3CompatibleStorage extends BaseStorage {
303
494
  * Get current batch size for operations
304
495
  */
305
496
  getBatchSize() {
306
- this.adjustBatchSize();
307
- return this.currentBatchSize;
497
+ // Use adaptive socket manager's batch size
498
+ return this.socketManager.getBatchSize();
308
499
  }
309
500
  /**
310
501
  * Save a noun to storage (internal implementation)
@@ -317,8 +508,15 @@ export class S3CompatibleStorage extends BaseStorage {
317
508
  */
318
509
  async saveNode(node) {
319
510
  await this.ensureInitialized();
511
+ // Check if we should use high-volume mode
512
+ this.checkVolumeMode();
513
+ // Use write buffer in high-volume mode
514
+ if (this.highVolumeMode && this.nounWriteBuffer) {
515
+ await this.nounWriteBuffer.add(node.id, node);
516
+ return;
517
+ }
320
518
  // Apply backpressure before starting operation
321
- await this.applyBackpressure();
519
+ const requestId = await this.applyBackpressure();
322
520
  try {
323
521
  this.logger.trace(`Saving node ${node.id}`);
324
522
  // Convert connections Map to a serializable format
@@ -368,11 +566,11 @@ export class S3CompatibleStorage extends BaseStorage {
368
566
  this.logger.warn(`Failed to verify node ${node.id} was saved correctly:`, verifyError);
369
567
  }
370
568
  // Release backpressure on success
371
- this.releaseBackpressure(true);
569
+ this.releaseBackpressure(true, requestId);
372
570
  }
373
571
  catch (error) {
374
572
  // Release backpressure on error
375
- this.releaseBackpressure(false);
573
+ this.releaseBackpressure(false, requestId);
376
574
  this.logger.error(`Failed to save node ${node.id}:`, error);
377
575
  throw new Error(`Failed to save node ${node.id}: ${error}`);
378
576
  }
@@ -652,8 +850,15 @@ export class S3CompatibleStorage extends BaseStorage {
652
850
  */
653
851
  async saveEdge(edge) {
654
852
  await this.ensureInitialized();
853
+ // Check if we should use high-volume mode
854
+ this.checkVolumeMode();
855
+ // Use write buffer in high-volume mode
856
+ if (this.highVolumeMode && this.verbWriteBuffer) {
857
+ await this.verbWriteBuffer.add(edge.id, edge);
858
+ return;
859
+ }
655
860
  // Apply backpressure before starting operation
656
- await this.applyBackpressure();
861
+ const requestId = await this.applyBackpressure();
657
862
  try {
658
863
  // Convert connections Map to a serializable format
659
864
  const serializableEdge = {
@@ -680,11 +885,11 @@ export class S3CompatibleStorage extends BaseStorage {
680
885
  }
681
886
  });
682
887
  // Release backpressure on success
683
- this.releaseBackpressure(true);
888
+ this.releaseBackpressure(true, requestId);
684
889
  }
685
890
  catch (error) {
686
891
  // Release backpressure on error
687
- this.releaseBackpressure(false);
892
+ this.releaseBackpressure(false, requestId);
688
893
  this.logger.error(`Failed to save edge ${edge.id}:`, error);
689
894
  throw new Error(`Failed to save edge ${edge.id}: ${error}`);
690
895
  }
@@ -1024,7 +1229,7 @@ export class S3CompatibleStorage extends BaseStorage {
1024
1229
  async saveMetadata(id, metadata) {
1025
1230
  await this.ensureInitialized();
1026
1231
  // Apply backpressure before starting operation
1027
- await this.applyBackpressure();
1232
+ const requestId = await this.applyBackpressure();
1028
1233
  try {
1029
1234
  // Import the PutObjectCommand only when needed
1030
1235
  const { PutObjectCommand } = await import('@aws-sdk/client-s3');
@@ -1065,11 +1270,11 @@ export class S3CompatibleStorage extends BaseStorage {
1065
1270
  this.logger.warn(`Failed to verify metadata for ${id} was saved correctly:`, verifyError);
1066
1271
  }
1067
1272
  // Release backpressure on success
1068
- this.releaseBackpressure(true);
1273
+ this.releaseBackpressure(true, requestId);
1069
1274
  }
1070
1275
  catch (error) {
1071
1276
  // Release backpressure on error
1072
- this.releaseBackpressure(false);
1277
+ this.releaseBackpressure(false, requestId);
1073
1278
  this.logger.error(`Failed to save metadata for ${id}:`, error);
1074
1279
  throw new Error(`Failed to save metadata for ${id}: ${error}`);
1075
1280
  }