@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.
@@ -0,0 +1,324 @@
1
+ /**
2
+ * Request Coalescer
3
+ * Batches and deduplicates operations to reduce S3 API calls
4
+ * Automatically flushes based on size, time, or pressure
5
+ */
6
+ import { createModuleLogger } from './logger.js';
7
+ /**
8
+ * Coalesces multiple operations into efficient batches
9
+ */
10
+ export class RequestCoalescer {
11
+ constructor(processor, options) {
12
+ this.logger = createModuleLogger('RequestCoalescer');
13
+ // Operation queues by type
14
+ this.writeQueue = new Map();
15
+ this.readQueue = new Map();
16
+ this.deleteQueue = new Map();
17
+ // Batch configuration
18
+ this.maxBatchSize = 100;
19
+ this.maxBatchAge = 100; // ms - flush quickly under load
20
+ this.minBatchSize = 10; // Don't flush until we have enough
21
+ // Flush timers
22
+ this.flushTimer = null;
23
+ this.lastFlush = Date.now();
24
+ // Statistics
25
+ this.stats = {
26
+ totalOperations: 0,
27
+ coalescedOperations: 0,
28
+ deduplicated: 0,
29
+ batchesProcessed: 0,
30
+ averageBatchSize: 0
31
+ };
32
+ this.processor = processor;
33
+ if (options) {
34
+ this.maxBatchSize = options.maxBatchSize || this.maxBatchSize;
35
+ this.maxBatchAge = options.maxBatchAge || this.maxBatchAge;
36
+ this.minBatchSize = options.minBatchSize || this.minBatchSize;
37
+ }
38
+ }
39
+ /**
40
+ * Add a write operation to be coalesced
41
+ */
42
+ async write(key, data) {
43
+ return new Promise((resolve, reject) => {
44
+ // Check if we already have a pending write for this key
45
+ const existing = this.writeQueue.get(key);
46
+ if (existing && existing.length > 0) {
47
+ // Replace the data but resolve all promises
48
+ const last = existing[existing.length - 1];
49
+ last.data = data; // Use latest data
50
+ // Add this promise to be resolved
51
+ existing.push({
52
+ type: 'write',
53
+ key,
54
+ data,
55
+ resolve,
56
+ reject,
57
+ timestamp: Date.now()
58
+ });
59
+ this.stats.deduplicated++;
60
+ }
61
+ else {
62
+ // New write operation
63
+ this.writeQueue.set(key, [{
64
+ type: 'write',
65
+ key,
66
+ data,
67
+ resolve,
68
+ reject,
69
+ timestamp: Date.now()
70
+ }]);
71
+ }
72
+ this.stats.totalOperations++;
73
+ this.checkFlush();
74
+ });
75
+ }
76
+ /**
77
+ * Add a read operation to be coalesced
78
+ */
79
+ async read(key) {
80
+ return new Promise((resolve, reject) => {
81
+ // Check if we already have a pending read for this key
82
+ const existing = this.readQueue.get(key);
83
+ if (existing && existing.length > 0) {
84
+ // Coalesce with existing read
85
+ existing.push({
86
+ type: 'read',
87
+ key,
88
+ resolve,
89
+ reject,
90
+ timestamp: Date.now()
91
+ });
92
+ this.stats.deduplicated++;
93
+ }
94
+ else {
95
+ // New read operation
96
+ this.readQueue.set(key, [{
97
+ type: 'read',
98
+ key,
99
+ resolve,
100
+ reject,
101
+ timestamp: Date.now()
102
+ }]);
103
+ }
104
+ this.stats.totalOperations++;
105
+ this.checkFlush();
106
+ });
107
+ }
108
+ /**
109
+ * Add a delete operation to be coalesced
110
+ */
111
+ async delete(key) {
112
+ return new Promise((resolve, reject) => {
113
+ // Cancel any pending writes for this key
114
+ if (this.writeQueue.has(key)) {
115
+ const writes = this.writeQueue.get(key);
116
+ writes.forEach(op => op.reject(new Error('Cancelled by delete')));
117
+ this.writeQueue.delete(key);
118
+ this.stats.deduplicated += writes.length;
119
+ }
120
+ // Cancel any pending reads for this key
121
+ if (this.readQueue.has(key)) {
122
+ const reads = this.readQueue.get(key);
123
+ reads.forEach(op => op.resolve(null)); // Return null for deleted items
124
+ this.readQueue.delete(key);
125
+ this.stats.deduplicated += reads.length;
126
+ }
127
+ // Check if we already have a pending delete
128
+ const existing = this.deleteQueue.get(key);
129
+ if (existing && existing.length > 0) {
130
+ // Coalesce with existing delete
131
+ existing.push({
132
+ type: 'delete',
133
+ key,
134
+ resolve,
135
+ reject,
136
+ timestamp: Date.now()
137
+ });
138
+ this.stats.deduplicated++;
139
+ }
140
+ else {
141
+ // New delete operation
142
+ this.deleteQueue.set(key, [{
143
+ type: 'delete',
144
+ key,
145
+ resolve,
146
+ reject,
147
+ timestamp: Date.now()
148
+ }]);
149
+ }
150
+ this.stats.totalOperations++;
151
+ this.checkFlush();
152
+ });
153
+ }
154
+ /**
155
+ * Check if we should flush the queues
156
+ */
157
+ checkFlush() {
158
+ const totalSize = this.writeQueue.size + this.readQueue.size + this.deleteQueue.size;
159
+ const now = Date.now();
160
+ const age = now - this.lastFlush;
161
+ // Immediate flush conditions
162
+ if (totalSize >= this.maxBatchSize) {
163
+ this.flush('size_limit');
164
+ return;
165
+ }
166
+ // Age-based flush
167
+ if (age >= this.maxBatchAge && totalSize >= this.minBatchSize) {
168
+ this.flush('age_limit');
169
+ return;
170
+ }
171
+ // Schedule a flush if not already scheduled
172
+ if (!this.flushTimer && totalSize > 0) {
173
+ const delay = Math.max(10, this.maxBatchAge - age);
174
+ this.flushTimer = setTimeout(() => {
175
+ this.flush('timer');
176
+ }, delay);
177
+ }
178
+ }
179
+ /**
180
+ * Flush all queued operations
181
+ */
182
+ async flush(reason = 'manual') {
183
+ // Clear timer
184
+ if (this.flushTimer) {
185
+ clearTimeout(this.flushTimer);
186
+ this.flushTimer = null;
187
+ }
188
+ // Collect all operations into a single batch
189
+ const batch = [];
190
+ // Process deletes first (highest priority)
191
+ this.deleteQueue.forEach((ops) => {
192
+ // Only take the first operation per key (others are duplicates)
193
+ if (ops.length > 0) {
194
+ batch.push(ops[0]);
195
+ this.stats.coalescedOperations += ops.length;
196
+ }
197
+ });
198
+ // Then writes
199
+ this.writeQueue.forEach((ops) => {
200
+ if (ops.length > 0) {
201
+ // Use the last write (most recent data)
202
+ const lastWrite = ops[ops.length - 1];
203
+ batch.push(lastWrite);
204
+ this.stats.coalescedOperations += ops.length;
205
+ }
206
+ });
207
+ // Then reads
208
+ this.readQueue.forEach((ops) => {
209
+ if (ops.length > 0) {
210
+ batch.push(ops[0]);
211
+ this.stats.coalescedOperations += ops.length;
212
+ }
213
+ });
214
+ // Clear queues
215
+ const allOps = [
216
+ ...Array.from(this.deleteQueue.values()).flat(),
217
+ ...Array.from(this.writeQueue.values()).flat(),
218
+ ...Array.from(this.readQueue.values()).flat()
219
+ ];
220
+ this.deleteQueue.clear();
221
+ this.writeQueue.clear();
222
+ this.readQueue.clear();
223
+ if (batch.length === 0) {
224
+ return;
225
+ }
226
+ // Update stats
227
+ this.stats.batchesProcessed++;
228
+ this.stats.averageBatchSize =
229
+ (this.stats.averageBatchSize * (this.stats.batchesProcessed - 1) + batch.length) /
230
+ this.stats.batchesProcessed;
231
+ this.logger.debug(`Flushing batch of ${batch.length} operations (${allOps.length} total) - reason: ${reason}`);
232
+ // Process the batch
233
+ try {
234
+ await this.processor(batch);
235
+ // Resolve all promises
236
+ allOps.forEach(op => {
237
+ if (op.type === 'read') {
238
+ // Find the result for this read
239
+ const result = batch.find(b => b.key === op.key && b.type === 'read');
240
+ op.resolve(result?.data || null);
241
+ }
242
+ else {
243
+ op.resolve(undefined);
244
+ }
245
+ });
246
+ }
247
+ catch (error) {
248
+ // Reject all promises
249
+ allOps.forEach(op => op.reject(error));
250
+ this.logger.error('Batch processing failed:', error);
251
+ }
252
+ this.lastFlush = Date.now();
253
+ }
254
+ /**
255
+ * Get current statistics
256
+ */
257
+ getStats() {
258
+ return { ...this.stats };
259
+ }
260
+ /**
261
+ * Get current queue sizes
262
+ */
263
+ getQueueSizes() {
264
+ return {
265
+ writes: this.writeQueue.size,
266
+ reads: this.readQueue.size,
267
+ deletes: this.deleteQueue.size,
268
+ total: this.writeQueue.size + this.readQueue.size + this.deleteQueue.size
269
+ };
270
+ }
271
+ /**
272
+ * Adjust batch parameters based on load
273
+ */
274
+ adjustParameters(pending) {
275
+ if (pending > 10000) {
276
+ // Extreme load - batch aggressively
277
+ this.maxBatchSize = 500;
278
+ this.maxBatchAge = 50;
279
+ this.minBatchSize = 50;
280
+ }
281
+ else if (pending > 1000) {
282
+ // High load - larger batches
283
+ this.maxBatchSize = 200;
284
+ this.maxBatchAge = 100;
285
+ this.minBatchSize = 20;
286
+ }
287
+ else if (pending > 100) {
288
+ // Moderate load
289
+ this.maxBatchSize = 100;
290
+ this.maxBatchAge = 200;
291
+ this.minBatchSize = 10;
292
+ }
293
+ else {
294
+ // Low load - optimize for latency
295
+ this.maxBatchSize = 50;
296
+ this.maxBatchAge = 500;
297
+ this.minBatchSize = 5;
298
+ }
299
+ }
300
+ /**
301
+ * Force immediate flush of all operations
302
+ */
303
+ async forceFlush() {
304
+ await this.flush('force');
305
+ }
306
+ }
307
+ // Global coalescer instances by storage type
308
+ const coalescers = new Map();
309
+ /**
310
+ * Get or create a coalescer for a storage instance
311
+ */
312
+ export function getCoalescer(storageId, processor) {
313
+ if (!coalescers.has(storageId)) {
314
+ coalescers.set(storageId, new RequestCoalescer(processor));
315
+ }
316
+ return coalescers.get(storageId);
317
+ }
318
+ /**
319
+ * Clear all coalescers
320
+ */
321
+ export function clearCoalescers() {
322
+ coalescers.clear();
323
+ }
324
+ //# sourceMappingURL=requestCoalescer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestCoalescer.js","sourceRoot":"","sources":["../../src/utils/requestCoalescer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Write Buffer
3
+ * Accumulates writes and flushes them in bulk to reduce S3 operations
4
+ * Implements intelligent deduplication and compression
5
+ */
6
+ interface FlushResult {
7
+ successful: number;
8
+ failed: number;
9
+ duration: number;
10
+ }
11
+ /**
12
+ * High-performance write buffer for bulk operations
13
+ */
14
+ export declare class WriteBuffer<T> {
15
+ private logger;
16
+ private buffer;
17
+ private maxBufferSize;
18
+ private flushInterval;
19
+ private minFlushSize;
20
+ private maxRetries;
21
+ private flushTimer;
22
+ private isFlushing;
23
+ private lastFlush;
24
+ private pendingFlush;
25
+ private totalWrites;
26
+ private totalFlushes;
27
+ private failedWrites;
28
+ private duplicatesRemoved;
29
+ private writeFunction;
30
+ private type;
31
+ private backpressure;
32
+ constructor(type: 'noun' | 'verb' | 'metadata', writeFunction: (items: Map<string, T>) => Promise<void>, options?: {
33
+ maxBufferSize?: number;
34
+ flushInterval?: number;
35
+ minFlushSize?: number;
36
+ });
37
+ /**
38
+ * Add item to buffer
39
+ */
40
+ add(id: string, data: T): Promise<void>;
41
+ /**
42
+ * Check if we should flush
43
+ */
44
+ private checkFlush;
45
+ /**
46
+ * Flush buffer to storage
47
+ */
48
+ flush(reason?: string): Promise<FlushResult>;
49
+ /**
50
+ * Perform the actual flush
51
+ */
52
+ private doFlush;
53
+ /**
54
+ * Start periodic flush timer
55
+ */
56
+ private startPeriodicFlush;
57
+ /**
58
+ * Stop periodic flush timer
59
+ */
60
+ stop(): void;
61
+ /**
62
+ * Force flush all pending writes
63
+ */
64
+ forceFlush(): Promise<FlushResult>;
65
+ /**
66
+ * Get buffer statistics
67
+ */
68
+ getStats(): {
69
+ bufferSize: number;
70
+ totalWrites: number;
71
+ totalFlushes: number;
72
+ failedWrites: number;
73
+ duplicatesRemoved: number;
74
+ avgFlushSize: number;
75
+ };
76
+ /**
77
+ * Adjust parameters based on load
78
+ */
79
+ adjustForLoad(pendingRequests: number): void;
80
+ }
81
+ /**
82
+ * Get or create a write buffer
83
+ */
84
+ export declare function getWriteBuffer<T>(id: string, type: 'noun' | 'verb' | 'metadata', writeFunction: (items: Map<string, T>) => Promise<void>): WriteBuffer<T>;
85
+ /**
86
+ * Flush all write buffers
87
+ */
88
+ export declare function flushAllBuffers(): Promise<void>;
89
+ /**
90
+ * Clear all write buffers
91
+ */
92
+ export declare function clearWriteBuffers(): void;
93
+ export {};