This example demonstrates the that producer is not waiting for the consumer to finish processing before another item is made available. This creates issues where the memory balloons if the consumer is slower then the producer. This seems to be isolated to when a flatMap is used. Despite all concurrent executions being consumed, more values are still produced.
import {from} from "ix/asynciterable";
import {flatMap} from "ix/asynciterable/operators";
let current = 0;
let range = {
[Symbol.asyncIterator]() {
return {
async next() {
await new Promise(resolve => setTimeout(resolve, 1));
return { done: false, value: current++ };
}
};
}
};
export async function example() {
let results = (from(range)).pipe(
flatMap(async (ii) => {
await new Promise(resolve => setTimeout(resolve, 1000));
return ii
}, 1)
);
for await (let message of results) {
// print heap usage
console.log(`Got Message ${message} messages, current: ${current}, diff: ${current - message}`);
}
}
example();
Expected behavior:
If all concurrency is used then no more values should be requested until concurrency is freed for processing, The iterator should only produce values is the consumer is able to consume them.
IxJS version:
7.0.0
Code to reproduce:
This example demonstrates the that producer is not waiting for the consumer to finish processing before another item is made available. This creates issues where the memory balloons if the consumer is slower then the producer. This seems to be isolated to when a
flatMap
is used. Despite all concurrent executions being consumed, more values are still produced.Expected behavior:
If all concurrency is used then no more values should be requested until concurrency is freed for processing, The iterator should only produce values is the consumer is able to consume them.
Expected Output
Actual behavior:
Flatmap doesn't prevent values from being produced.
Additional information: