Merge pull request #79 from avandeweghe/patch-1

Refactor parseStreaming to use pendingBatches array
This commit is contained in:
Technomancer702
2026-02-04 15:45:56 -08:00
committed by GitHub
+35 -9
View File
@@ -266,9 +266,11 @@ async function* fetchAndParseStreaming(url, batchSize = 1000) {
* @yields {{ channels: Array|null, programmes: Array, isLast: boolean }} * @yields {{ channels: Array|null, programmes: Array, isLast: boolean }}
*/ */
async function* parseStreaming(input, batchSize = 1000) { async function* parseStreaming(input, batchSize = 1000) {
const channels = []; let channels = [];
let programmeBatch = []; let programmeBatch = [];
let channelsYielded = false; let channelsYielded = false;
const maxPenmdingBatches = 4;
let paused = false;
// We need to convert SAX events to an async iterator // We need to convert SAX events to an async iterator
// This requires collecting events and yielding when batch is full // This requires collecting events and yielding when batch is full
@@ -279,7 +281,7 @@ async function* parseStreaming(input, batchSize = 1000) {
let currentObject = null; let currentObject = null;
let textBuffer = ''; let textBuffer = '';
let resolveNext = null; let resolveNext = null;
let pendingBatch = null; const pendingBatches = [];
let ended = false; let ended = false;
let error = null; let error = null;
@@ -345,13 +347,27 @@ async function* parseStreaming(input, batchSize = 1000) {
isLast: false isLast: false
}; };
channelsYielded = true; channelsYielded = true;
// allow channels array to be GC'd after included in first batch
try { if (channels && channels.length) channels = null; } catch (e) {}
programmeBatch = []; programmeBatch = [];
if (resolveNext) { if (resolveNext) {
resolveNext(batch); resolveNext(batch);
resolveNext = null; resolveNext = null;
} else { } else {
pendingBatch = batch; pendingBatches.push(batch);
// Apply backpressure when queue grows too large
try {
if (!paused && pendingBatches.length >= maxPenmdingBatches) {
if (input && typeof input.pause === 'function') {
input.pause();
paused = true;
}
}
} catch (e) {}
} }
} }
} }
@@ -398,7 +414,7 @@ async function* parseStreaming(input, batchSize = 1000) {
resolveNext(batch); resolveNext(batch);
resolveNext = null; resolveNext = null;
} else { } else {
pendingBatch = batch; pendingBatches.push(batch);
} }
}); });
@@ -413,10 +429,21 @@ async function* parseStreaming(input, batchSize = 1000) {
input.pipe(saxStream); input.pipe(saxStream);
// Yield batches as they become available // Yield batches as they become available
while (!ended || pendingBatch) {
if (pendingBatch) { while (!ended || pendingBatches.length > 0) {
const batch = pendingBatch; if (pendingBatches.length > 0) {
pendingBatch = null; const batch = pendingBatches.shift();
// If paused and queue drained below threshold, resume
try {
if (paused && pendingBatches.length < maxPenmdingBatches) {
if (input && typeof input.resume === 'function') {
input.resume();
paused = false;
}
}
} catch (e) {}
yield batch; yield batch;
if (batch.isLast) break; if (batch.isLast) break;
} else if (!ended) { } else if (!ended) {
@@ -445,4 +472,3 @@ module.exports = {
getProgrammesForChannel, getProgrammesForChannel,
getCurrentAndUpcoming getCurrentAndUpcoming
}; };