@tstdl/base 0.93.140 → 0.93.141
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/application/application.d.ts +1 -1
- package/application/application.js +1 -1
- package/application/providers.d.ts +20 -2
- package/application/providers.js +34 -7
- package/audit/module.d.ts +5 -0
- package/audit/module.js +9 -1
- package/authentication/server/module.d.ts +5 -0
- package/authentication/server/module.js +9 -1
- package/authentication/tests/authentication.api-controller.test.js +1 -1
- package/authentication/tests/authentication.api-request-token.provider.test.js +1 -1
- package/authentication/tests/authentication.client-service.test.js +1 -1
- package/circuit-breaker/postgres/module.d.ts +1 -0
- package/circuit-breaker/postgres/module.js +5 -1
- package/document-management/server/configure.js +5 -1
- package/document-management/server/module.d.ts +1 -1
- package/document-management/server/module.js +1 -1
- package/document-management/server/services/document-management-ancillary.service.js +1 -1
- package/document-management/tests/ai-config-hierarchy.test.js +0 -5
- package/document-management/tests/document-management-ai-overrides.test.js +0 -1
- package/document-management/tests/document-validation-ai-overrides.test.js +0 -1
- package/examples/document-management/main.d.ts +1 -0
- package/examples/document-management/main.js +14 -11
- package/key-value-store/postgres/module.d.ts +1 -0
- package/key-value-store/postgres/module.js +5 -1
- package/lock/postgres/module.d.ts +1 -0
- package/lock/postgres/module.js +5 -1
- package/mail/module.d.ts +5 -1
- package/mail/module.js +11 -6
- package/module/modules/web-server.module.js +2 -3
- package/notification/server/module.d.ts +1 -0
- package/notification/server/module.js +5 -1
- package/notification/tests/notification-flow.test.js +2 -2
- package/orm/decorators.d.ts +5 -1
- package/orm/decorators.js +1 -1
- package/orm/server/drizzle/schema-converter.js +17 -30
- package/orm/server/encryption.d.ts +0 -1
- package/orm/server/encryption.js +1 -4
- package/orm/server/index.d.ts +1 -6
- package/orm/server/index.js +1 -6
- package/orm/server/migration.d.ts +19 -0
- package/orm/server/migration.js +72 -0
- package/orm/server/repository.d.ts +1 -1
- package/orm/server/transaction.d.ts +5 -10
- package/orm/server/transaction.js +22 -26
- package/orm/server/transactional.js +3 -3
- package/orm/tests/database-migration.test.d.ts +1 -0
- package/orm/tests/database-migration.test.js +82 -0
- package/orm/tests/encryption.test.js +3 -4
- package/orm/utils.d.ts +17 -2
- package/orm/utils.js +49 -1
- package/package.json +4 -3
- package/rate-limit/postgres/module.d.ts +1 -0
- package/rate-limit/postgres/module.js +5 -1
- package/reflection/decorator-data.js +11 -12
- package/task-queue/README.md +2 -9
- package/task-queue/postgres/drizzle/{0000_simple_invisible_woman.sql → 0000_wakeful_sunspot.sql} +22 -14
- package/task-queue/postgres/drizzle/meta/0000_snapshot.json +160 -82
- package/task-queue/postgres/drizzle/meta/_journal.json +2 -2
- package/task-queue/postgres/module.d.ts +1 -0
- package/task-queue/postgres/module.js +5 -1
- package/task-queue/postgres/schemas.d.ts +9 -6
- package/task-queue/postgres/schemas.js +4 -3
- package/task-queue/postgres/task-queue.d.ts +2 -12
- package/task-queue/postgres/task-queue.js +431 -354
- package/task-queue/postgres/task.model.d.ts +12 -5
- package/task-queue/postgres/task.model.js +51 -25
- package/task-queue/task-context.d.ts +2 -2
- package/task-queue/task-context.js +7 -7
- package/task-queue/task-queue.d.ts +36 -19
- package/task-queue/task-queue.js +18 -10
- package/task-queue/tests/cascading-cancellations.test.d.ts +1 -0
- package/task-queue/tests/cascading-cancellations.test.js +38 -0
- package/task-queue/tests/complex.test.js +44 -228
- package/task-queue/tests/coverage-branch.test.d.ts +1 -0
- package/task-queue/tests/coverage-branch.test.js +407 -0
- package/task-queue/tests/coverage-enhancement.test.d.ts +1 -0
- package/task-queue/tests/coverage-enhancement.test.js +144 -0
- package/task-queue/tests/dag-dependencies.test.d.ts +1 -0
- package/task-queue/tests/dag-dependencies.test.js +41 -0
- package/task-queue/tests/dependencies.test.js +26 -26
- package/task-queue/tests/extensive-dependencies.test.js +64 -139
- package/task-queue/tests/fan-out-spawning.test.d.ts +1 -0
- package/task-queue/tests/fan-out-spawning.test.js +53 -0
- package/task-queue/tests/idempotent-replacement.test.d.ts +1 -0
- package/task-queue/tests/idempotent-replacement.test.js +61 -0
- package/task-queue/tests/missing-idempotent-tasks.test.d.ts +1 -0
- package/task-queue/tests/missing-idempotent-tasks.test.js +38 -0
- package/task-queue/tests/queue.test.js +33 -24
- package/task-queue/tests/worker.test.js +20 -5
- package/task-queue/tests/zombie-parent.test.d.ts +1 -0
- package/task-queue/tests/zombie-parent.test.js +45 -0
- package/task-queue/tests/zombie-recovery.test.d.ts +1 -0
- package/task-queue/tests/zombie-recovery.test.js +51 -0
- package/test5.js +5 -5
- package/testing/integration-setup.d.ts +4 -4
- package/testing/integration-setup.js +54 -29
- package/text/localization.service.js +2 -2
- package/utils/file-reader.js +1 -2
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { TaskQueueProvider, TaskStatus } from '../../task-queue/index.js';
|
|
3
3
|
import { setupIntegrationTest } from '../../testing/index.js';
|
|
4
|
-
import { currentTimestamp } from '../../utils/date-time.js';
|
|
5
4
|
import { timeout } from '../../utils/timing.js';
|
|
6
5
|
describe('Complex Queue Scenarios', () => {
|
|
7
6
|
let injector;
|
|
@@ -37,19 +36,15 @@ describe('Complex Queue Scenarios', () => {
|
|
|
37
36
|
const task = await queue.getTask(id);
|
|
38
37
|
if (task?.status === status)
|
|
39
38
|
return;
|
|
40
|
-
await queue.processPendingFanIn();
|
|
41
39
|
await timeout(10);
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
describe('Complex Dependencies', () => {
|
|
45
43
|
it('should handle Diamond Dependency (A -> B, A -> C, (B&C) -> D)', async () => {
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
const taskC = await queue.enqueue('C', {}, { tags: ['tag-c'], scheduleAfterTags: ['tag-a'] });
|
|
51
|
-
// A runs first
|
|
52
|
-
const taskA = await queue.enqueue('A', {}, { tags: ['tag-a'] });
|
|
44
|
+
const taskA = await queue.enqueue('A', {});
|
|
45
|
+
const taskB = await queue.enqueue('B', {}, { scheduleAfter: [taskA.id] });
|
|
46
|
+
const taskC = await queue.enqueue('C', {}, { scheduleAfter: [taskA.id] });
|
|
47
|
+
const taskD = await queue.enqueue('D', {}, { scheduleAfter: [taskB.id, taskC.id] });
|
|
53
48
|
expect(taskD.status).toBe(TaskStatus.Waiting);
|
|
54
49
|
expect(taskB.status).toBe(TaskStatus.Waiting);
|
|
55
50
|
expect(taskC.status).toBe(TaskStatus.Waiting);
|
|
@@ -62,8 +57,6 @@ describe('Complex Queue Scenarios', () => {
|
|
|
62
57
|
// Process B
|
|
63
58
|
const dB = await queue.dequeue({ types: ['B'] });
|
|
64
59
|
await queue.complete(dB);
|
|
65
|
-
await timeout(20);
|
|
66
|
-
await queue.processPendingFanIn();
|
|
67
60
|
// D still waiting (needs C)
|
|
68
61
|
const uD2 = await queue.getTask(taskD.id);
|
|
69
62
|
expect(uD2?.status).toBe(TaskStatus.Waiting);
|
|
@@ -76,231 +69,54 @@ describe('Complex Queue Scenarios', () => {
|
|
|
76
69
|
expect(uD3?.status).toBe(TaskStatus.Pending);
|
|
77
70
|
});
|
|
78
71
|
it('should handle Deep Chain (A -> B -> C -> D)', async () => {
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
// Run A
|
|
72
|
+
const taskA = await queue.enqueue('A', {});
|
|
73
|
+
const taskB = await queue.enqueue('B', {}, { scheduleAfter: [taskA.id] });
|
|
74
|
+
const taskC = await queue.enqueue('C', {}, { scheduleAfter: [taskB.id] });
|
|
75
|
+
const taskD = await queue.enqueue('D', {}, { scheduleAfter: [taskC.id] });
|
|
84
76
|
await queue.complete((await queue.dequeue({ types: ['A'] })));
|
|
85
|
-
await waitForStatus(
|
|
86
|
-
// Run B
|
|
77
|
+
await waitForStatus(taskB.id, TaskStatus.Pending);
|
|
87
78
|
await queue.complete((await queue.dequeue({ types: ['B'] })));
|
|
88
|
-
await waitForStatus(
|
|
89
|
-
// Run C
|
|
79
|
+
await waitForStatus(taskC.id, TaskStatus.Pending);
|
|
90
80
|
await queue.complete((await queue.dequeue({ types: ['C'] })));
|
|
91
|
-
await waitForStatus(
|
|
92
|
-
expect((await queue.getTask(D.id))?.status).toBe(TaskStatus.Pending);
|
|
81
|
+
await waitForStatus(taskD.id, TaskStatus.Pending);
|
|
93
82
|
});
|
|
94
|
-
it('should
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
await queue.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
83
|
+
it('should respect failFast = false (continue other branches)', async () => {
|
|
84
|
+
const taskA = await queue.enqueue('A', {});
|
|
85
|
+
const taskB = await queue.enqueue('B', {}, { scheduleAfter: [taskA.id], failFast: false });
|
|
86
|
+
const taskC = await queue.enqueue('C', {}); // Independent
|
|
87
|
+
const dA = await queue.dequeue({ types: ['A'] });
|
|
88
|
+
await queue.fail(dA, new Error('fatal'), { fatal: true });
|
|
89
|
+
// taskB should stay Waiting (default requiredStatus is Completed)
|
|
90
|
+
// If failFast is false, it should transition to Pending once the dependency is terminal, even if it failed.
|
|
91
|
+
await timeout(100);
|
|
92
|
+
const uB = await queue.getTask(taskB.id);
|
|
93
|
+
expect(uB?.status).toBe(TaskStatus.Pending);
|
|
94
|
+
const dC = await queue.dequeue({ types: ['C'] });
|
|
95
|
+
expect(dC?.id).toBe(taskC.id);
|
|
103
96
|
});
|
|
104
97
|
});
|
|
105
|
-
describe('
|
|
106
|
-
it('should
|
|
98
|
+
describe('Other Scenarios', () => {
|
|
99
|
+
it('should handle priority aging', async () => {
|
|
107
100
|
const t1 = await queue.enqueue('low', {}, { priority: 2000 });
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
await
|
|
111
|
-
const updated = await queue.getTask(t1.id);
|
|
112
|
-
// Default step is 10. 2000 - 10 = 1990
|
|
113
|
-
expect(updated?.priority).toBe(1990);
|
|
114
|
-
});
|
|
115
|
-
it('should respect exponential backoff on failure', async () => {
|
|
116
|
-
const task = await queue.enqueue('fail-test', {});
|
|
117
|
-
// Try 1
|
|
118
|
-
const d1 = await queue.dequeue();
|
|
119
|
-
await queue.fail(d1, new Error('fail 1'));
|
|
120
|
-
const u1 = await queue.getTask(task.id);
|
|
121
|
-
expect(u1?.tries).toBe(1);
|
|
122
|
-
const delay1 = u1.scheduleTimestamp - currentTimestamp();
|
|
123
|
-
expect(delay1).toBeGreaterThan(20); // Approx check
|
|
124
|
-
// Force reschedule to now
|
|
125
|
-
await queue.reschedule(task.id, currentTimestamp());
|
|
126
|
-
// Try 2
|
|
127
|
-
const d2 = await queue.dequeue();
|
|
128
|
-
await queue.fail(d2, new Error('fail 2'));
|
|
129
|
-
const u2 = await queue.getTask(task.id);
|
|
130
|
-
expect(u2?.tries).toBe(2);
|
|
131
|
-
const now = currentTimestamp();
|
|
132
|
-
expect(u2.scheduleTimestamp > now + 50).toBe(true);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
describe('Rate Limiting & Concurrency', () => {
|
|
136
|
-
it('should limit burst dequeue rate', async () => {
|
|
137
|
-
// Rate limit 5, interval 100ms
|
|
138
|
-
await queue.enqueueMany(Array.from({ length: 10 }, (_, i) => ({ type: 'burst', data: { i } })));
|
|
139
|
-
// Request burstCapacity (5)
|
|
140
|
-
const batch1 = await queue.dequeueMany(5);
|
|
141
|
-
expect(batch1.length).toBe(5);
|
|
142
|
-
// Try immediately again
|
|
143
|
-
const batch2 = await queue.dequeueMany(1);
|
|
144
|
-
expect(batch2.length).toBe(0); // Rate limited
|
|
145
|
-
// Wait for refill
|
|
146
|
-
await timeout(300);
|
|
147
|
-
const batch3 = await queue.dequeueMany(5);
|
|
148
|
-
expect(batch3.length).toBe(5); // Refilled
|
|
149
|
-
});
|
|
150
|
-
it('should respect global concurrency limit', async () => {
|
|
151
|
-
const queueProvider = injector.resolve(TaskQueueProvider);
|
|
152
|
-
const limitQueue = queueProvider.get(`limit-${Date.now()}`, { globalConcurrency: 2 });
|
|
153
|
-
await limitQueue.enqueueMany([
|
|
154
|
-
{ type: 'c', data: {} },
|
|
155
|
-
{ type: 'c', data: {} },
|
|
156
|
-
{ type: 'c', data: {} },
|
|
157
|
-
]);
|
|
158
|
-
const t1 = await limitQueue.dequeue();
|
|
159
|
-
const t2 = await limitQueue.dequeue();
|
|
160
|
-
const t3 = await limitQueue.dequeue();
|
|
161
|
-
expect(t1).toBeDefined();
|
|
162
|
-
expect(t2).toBeDefined();
|
|
163
|
-
expect(t3).toBeUndefined(); // Max concurrency reached
|
|
164
|
-
await limitQueue.complete(t1);
|
|
165
|
-
const t3_retry = await limitQueue.dequeue();
|
|
166
|
-
expect(t3_retry).toBeDefined();
|
|
167
|
-
await limitQueue.clear();
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
describe('Archival & Maintenance', () => {
|
|
171
|
-
it('should archive completed tasks after retention period', async () => {
|
|
172
|
-
const qProvider = injector.resolve(TaskQueueProvider);
|
|
173
|
-
const archiveQueue = qProvider.get(`archive-${Date.now()}-${Math.random()}`, { retention: 100 });
|
|
174
|
-
const task = await archiveQueue.enqueue('archive-me', {});
|
|
175
|
-
const d = await archiveQueue.dequeue();
|
|
176
|
-
await archiveQueue.complete(d);
|
|
177
|
-
// Verify it is in main table
|
|
178
|
-
const before = await archiveQueue.getTask(task.id);
|
|
179
|
-
expect(before).toBeDefined();
|
|
180
|
-
expect(before?.status).toBe(TaskStatus.Completed);
|
|
181
|
-
expect(before.completeTimestamp > 0).toBe(true);
|
|
182
|
-
// Wait for retention (50ms).
|
|
183
|
-
await timeout(60);
|
|
184
|
-
await archiveQueue.maintenance();
|
|
185
|
-
// Should move from main table to archive
|
|
186
|
-
const loaded = await archiveQueue.getTask(task.id);
|
|
187
|
-
expect(loaded).toBeDefined();
|
|
188
|
-
expect(loaded?.status).toBe(TaskStatus.Completed);
|
|
189
|
-
await archiveQueue.clear();
|
|
190
|
-
});
|
|
191
|
-
it('should prune expired pending tasks', async () => {
|
|
192
|
-
// Time to live: 50ms
|
|
193
|
-
const task = await queue.enqueue('expire-me', {}, { timeToLive: currentTimestamp() + 50 });
|
|
194
|
-
await timeout(60);
|
|
195
|
-
await queue.maintenance();
|
|
196
|
-
const updated = await queue.getTask(task.id);
|
|
197
|
-
expect(updated?.status).toBe(TaskStatus.Dead);
|
|
198
|
-
expect((updated?.error)['code']).toBe('Expired');
|
|
199
|
-
});
|
|
200
|
-
it('should retrieve task from archive', async () => {
|
|
201
|
-
// Manually insert into archive? We can't access archiveRepository directly.
|
|
202
|
-
// But we can use maintenance to force it.
|
|
203
|
-
// Wait, if the previous test failed, this might also fail.
|
|
204
|
-
// But let's try with a VERY clear scenario.
|
|
205
|
-
const task = await queue.enqueue('archive-retrieval-test', {});
|
|
206
|
-
const d = await queue.dequeue();
|
|
207
|
-
await queue.complete(d);
|
|
208
|
-
// Force move
|
|
209
|
-
await timeout(60);
|
|
101
|
+
const t2 = await queue.enqueue('high', {}, { priority: 1000 });
|
|
102
|
+
// Wait for aging to trigger
|
|
103
|
+
await timeout(100);
|
|
210
104
|
await queue.maintenance();
|
|
211
|
-
|
|
212
|
-
const
|
|
213
|
-
expect(
|
|
214
|
-
expect(
|
|
215
|
-
});
|
|
216
|
-
it('should
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const child = await treeQueue.enqueue('child', {}, { parentId: parent.id });
|
|
221
|
-
const d1 = await treeQueue.dequeue();
|
|
222
|
-
const d2 = await treeQueue.dequeue();
|
|
223
|
-
await treeQueue.complete(d1);
|
|
224
|
-
await treeQueue.complete(d2);
|
|
225
|
-
// Wait for retention
|
|
226
|
-
await timeout(60);
|
|
227
|
-
// First maintenance: should archive child, but parent stays because child is still in main table (until it's deleted in the same tx maybe? No, loadMany happens before delete)
|
|
228
|
-
await treeQueue.maintenance();
|
|
229
|
-
const parentStillActive = await treeQueue.getTask(parent.id);
|
|
230
|
-
const childInArchive = await treeQueue.getTask(child.id);
|
|
231
|
-
// Verify child moved
|
|
232
|
-
expect(childInArchive).toBeDefined();
|
|
233
|
-
// Parent MUST still be in main table because child was present when archival query ran
|
|
234
|
-
expect(parentStillActive).toBeDefined();
|
|
235
|
-
// Second maintenance: should now archive parent because child is gone from main table
|
|
236
|
-
await treeQueue.maintenance();
|
|
237
|
-
const finalParent = await treeQueue.getTask(parent.id);
|
|
238
|
-
expect(finalParent).toBeDefined(); // Still defined (getTask checks both main and archive)
|
|
239
|
-
// We need to check if it's REALLY archived.
|
|
240
|
-
// We can use the #repository directly if we were in the class, but here we can check if it moved by checking against the main table?
|
|
241
|
-
// Actually getTask is implemented as:
|
|
242
|
-
/*
|
|
243
|
-
const active = await this.#repository.tryLoadByQuery({ namespace: this.#namespace, id });
|
|
244
|
-
if (isDefined(active)) return active;
|
|
245
|
-
return await this.#archiveRepository.tryLoadByQuery({ namespace: this.#namespace, id });
|
|
246
|
-
*/
|
|
247
|
-
await treeQueue.clear();
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
describe('Batch & Bulk Operations', () => {
|
|
251
|
-
it('should enqueue and dequeue large batches', async () => {
|
|
252
|
-
const items = Array.from({ length: 50 }, (_, i) => ({ type: 'bulk', data: { i } }));
|
|
253
|
-
const queueProvider = injector.resolve(TaskQueueProvider);
|
|
254
|
-
const bulkQueue = queueProvider.get(`bulk-${Date.now()}`, { rateLimit: 100 });
|
|
255
|
-
await bulkQueue.enqueueMany(items);
|
|
256
|
-
const count = await bulkQueue.countByTags([]); // All -> 0 because empty intersection
|
|
257
|
-
expect(count).toBe(0);
|
|
258
|
-
const batch = await bulkQueue.dequeueMany(50);
|
|
259
|
-
expect(batch.length).toBe(50);
|
|
260
|
-
await bulkQueue.completeMany(batch);
|
|
261
|
-
await bulkQueue.clear();
|
|
262
|
-
});
|
|
263
|
-
it('should handle idempotency window', async () => {
|
|
264
|
-
const key = 'idem-test';
|
|
265
|
-
const t1 = await queue.enqueue('t', { v: 1 }, { idempotencyKey: key });
|
|
266
|
-
const t2 = await queue.enqueue('t', { v: 2 }, { idempotencyKey: key });
|
|
267
|
-
expect(t1.id).toBe(t2.id); // Deduplicated
|
|
268
|
-
const t3 = await queue.enqueue('t', { v: 3 }, { idempotencyKey: key, replace: true });
|
|
269
|
-
expect(t3.id).not.toBe(t1.id); // Replaced
|
|
270
|
-
expect(t3.data['v']).toBe(3);
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
describe('Edge Cases', () => {
|
|
274
|
-
it('should not fan-in if dependency fails and failFast=false', async () => {
|
|
275
|
-
const dependent = await queue.enqueue('dep', {}, { scheduleAfterTags: ['fail-tag'], failFast: false });
|
|
276
|
-
const prereq = await queue.enqueue('pre', {}, { tags: ['fail-tag'] });
|
|
277
|
-
const d = await queue.dequeue({ types: ['pre'] });
|
|
278
|
-
await queue.fail(d, new Error('fail'));
|
|
279
|
-
await queue.processPendingFanIn();
|
|
280
|
-
// Retry check because fan-in might be processed by background worker asynchronously
|
|
281
|
-
let u = await queue.getTask(dependent.id);
|
|
282
|
-
for (let i = 0; i < 5; i++) {
|
|
283
|
-
if (u?.status == TaskStatus.Waiting)
|
|
284
|
-
break;
|
|
285
|
-
await timeout(10);
|
|
286
|
-
u = await queue.getTask(dependent.id);
|
|
105
|
+
const u1 = await queue.getTask(t1.id);
|
|
106
|
+
const u2 = await queue.getTask(t2.id);
|
|
107
|
+
expect(u1.priority).toBeLessThan(2000);
|
|
108
|
+
expect(u2.priority).toBeLessThan(1000);
|
|
109
|
+
});
|
|
110
|
+
it('should handle rate limiting', async () => {
|
|
111
|
+
// Limit is 5 per 200ms
|
|
112
|
+
for (let i = 0; i < 10; i++) {
|
|
113
|
+
await queue.enqueue('task', { i });
|
|
287
114
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
dependencyJoinMode: DependencyJoinMode.Or,
|
|
294
|
-
});
|
|
295
|
-
const A = await queue.enqueue('A', {}, { tags: ['A'] });
|
|
296
|
-
await queue.complete((await queue.dequeue({ types: ['A'] })));
|
|
297
|
-
await waitForStatus(dep.id, TaskStatus.Pending);
|
|
298
|
-
expect((await queue.getTask(dep.id))?.status).toBe(TaskStatus.Pending);
|
|
299
|
-
});
|
|
300
|
-
it('should not reschedule if task is not running', async () => {
|
|
301
|
-
const task = await queue.enqueue('t', {});
|
|
302
|
-
const res = await queue.touch(task);
|
|
303
|
-
expect(res).toBeUndefined();
|
|
115
|
+
const batch1 = await queue.dequeueMany(10);
|
|
116
|
+
expect(batch1.length).toBe(5);
|
|
117
|
+
await timeout(500); // Increased from 250
|
|
118
|
+
const batch2 = await queue.dequeueMany(10);
|
|
119
|
+
expect(batch2.length).toBe(5);
|
|
304
120
|
});
|
|
305
121
|
});
|
|
306
122
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|