From c8b92fa425033c1d65c9ed92901bcd3a48b404ba Mon Sep 17 00:00:00 2001 From: zlrlo Date: Thu, 5 Jan 2023 14:53:46 +0900 Subject: [PATCH] fix: separate timer for each key --- src/link/batch/__tests__/batchLink.ts | 65 +++++++++++++++++++++++++++ src/link/batch/batching.ts | 8 ++-- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/link/batch/__tests__/batchLink.ts b/src/link/batch/__tests__/batchLink.ts index 844ad375dc6..33d31bc39df 100644 --- a/src/link/batch/__tests__/batchLink.ts +++ b/src/link/batch/__tests__/batchLink.ts @@ -314,6 +314,71 @@ describe('OperationBatcher', () => { } }); + itAsync('should be able to consume from a queue containing multiple queries with different batch keys', (resolve, reject) => { + const request2: Operation = createOperation( + {}, + { + query, + }, + ); + + const BH = createMockBatchHandler( + { + request: { query }, + result: { data }, + }, + { + request: { query }, + result: { data }, + }, + ); + + let key = true; + const batchKey = () => { + key = !key; + return '' + !key; + }; + + const myBatcher = new OperationBatcher({ + batchInterval: 10, + batchMax: 10, + batchHandler: BH, + batchKey + }); + + const observable1 = myBatcher.enqueueRequest({ operation }); + const observable2 = myBatcher.enqueueRequest({ operation: request2 }); + + let notify = false; + observable1.subscribe(resultObj1 => { + try { + expect(resultObj1).toEqual({ data }); + } catch (e) { + reject(e); + } + + if (notify) { + resolve(); + } else { + notify = true; + } + }); + + observable2.subscribe(resultObj2 => { + try { + expect(resultObj2).toEqual({ data }); + } catch (e) { + reject(e); + } + + if (notify) { + resolve(); + } else { + notify = true; + } + }); + }); + itAsync('should return a promise when we enqueue a request and resolve it with a result', (resolve, reject) => { const BH = createMockBatchHandler({ request: { query }, diff --git a/src/link/batch/batching.ts b/src/link/batch/batching.ts index 6edee97624c..af93ea49b3c 100644 --- a/src/link/batch/batching.ts +++ b/src/link/batch/batching.ts @@ -32,7 +32,7 @@ export class OperationBatcher { // Queue on which the QueryBatcher will operate on a per-tick basis. private batchesByKey = new Map(); - private scheduledBatchTimer: ReturnType; + private scheduledBatchTimerByKey = new Map>(); private batchDebounce?: boolean; private batchInterval?: number; private batchMax: number; @@ -211,9 +211,9 @@ export class OperationBatcher { } private scheduleQueueConsumption(key: string): void { - clearTimeout(this.scheduledBatchTimer); - this.scheduledBatchTimer = setTimeout(() => { + clearTimeout(this.scheduledBatchTimerByKey.get(key)); + this.scheduledBatchTimerByKey.set(key, setTimeout(() => { this.consumeQueue(key); - }, this.batchInterval); + }, this.batchInterval)); } }