|
1 | | -import { deepStrictEqual, ok, strictEqual } from 'node:assert'; |
| 1 | +import { deepStrictEqual, ok, rejects, strictEqual } from 'node:assert'; |
2 | 2 | import { describe, it } from 'node:test'; |
3 | 3 |
|
4 | 4 | import { loadGenerator } from '../../generators/loader.mjs'; |
@@ -106,7 +106,7 @@ describe('createParallelWorker', () => { |
106 | 106 | await pool.destroy(); |
107 | 107 | }); |
108 | 108 |
|
109 | | - it('should yield results as chunks complete', async () => { |
| 109 | + it('should yield one result per input chunk', async () => { |
110 | 110 | const pool = createWorkerPool(2); |
111 | 111 | const worker = createParallelWorker('metadata', metadataGenerator, pool, { |
112 | 112 | threads: 2, |
@@ -177,4 +177,56 @@ describe('createParallelWorker', () => { |
177 | 177 |
|
178 | 178 | await pool.destroy(); |
179 | 179 | }); |
| 180 | + |
| 181 | + it('yields concurrent worker results in submission order', async () => { |
| 182 | + const resolvers = []; |
| 183 | + const pool = { |
| 184 | + run: task => |
| 185 | + new Promise(resolve => { |
| 186 | + resolvers.push(() => resolve(task.input)); |
| 187 | + }), |
| 188 | + }; |
| 189 | + const worker = createParallelWorker('ast-js', astJsGenerator, pool, { |
| 190 | + threads: 2, |
| 191 | + chunkSize: 1, |
| 192 | + }); |
| 193 | + |
| 194 | + const result = collectStream(worker.stream([0, 1, 2, 3, 4], {})); |
| 195 | + await Promise.resolve(); |
| 196 | + |
| 197 | + // All five tasks start before any result is yielded, but finish in reverse. |
| 198 | + strictEqual(resolvers.length, 5); |
| 199 | + for (const resolve of resolvers.toReversed()) { |
| 200 | + resolve(); |
| 201 | + } |
| 202 | + |
| 203 | + deepStrictEqual(await result, [0, 1, 2, 3, 4]); |
| 204 | + }); |
| 205 | + |
| 206 | + it('propagates a later worker failure without an unhandled rejection', async () => { |
| 207 | + const tasks = []; |
| 208 | + const pool = { |
| 209 | + run: task => |
| 210 | + new Promise((resolve, reject) => { |
| 211 | + tasks.push({ resolve, reject, input: task.input }); |
| 212 | + }), |
| 213 | + }; |
| 214 | + const worker = createParallelWorker('ast-js', astJsGenerator, pool, { |
| 215 | + threads: 2, |
| 216 | + chunkSize: 1, |
| 217 | + }); |
| 218 | + |
| 219 | + const result = collectStream(worker.stream([0, 1, 2, 3], {})); |
| 220 | + await Promise.resolve(); |
| 221 | + strictEqual(tasks.length, 4); |
| 222 | + |
| 223 | + tasks[2].reject(new Error('chunk failed')); |
| 224 | + for (const [index, task] of tasks.entries()) { |
| 225 | + if (index !== 2) { |
| 226 | + task.resolve(task.input); |
| 227 | + } |
| 228 | + } |
| 229 | + |
| 230 | + await rejects(result, /chunk failed/); |
| 231 | + }); |
180 | 232 | }); |
0 commit comments