Hi Team,
I propose a new syntax : await[timeoutInMs] to control timeout of a promise.
I have summarized this whole thread here in the proposal.
Original work thread:
Currently we can loop through an async source like this :
let someHeavyData = getBigDataOnRam();
for await (let t of asyncGenratorOrStream){
// collect this async data and do something
}
//once loop finishes/break do something
In such a case we are at mercy of asyncGenratorOrStream that it will send Data on time, but what if it never send any data or take unexpectedly too long amount of time on some values !?! All our resources in RAM are burden on the system.
We should have a control to break it , if the loop does not finishes within a given time.
for await[3000] (let t of asyncGenratorOrStream){
/// collect this async data and do something
}
//code wll continue from here anyway.
Such a code will break at most by 3000ms irrespective even if async source is still delivering values. If loop finishes on time (before 3000ms) well and good continue as normally it would, but if it goes beyond 3000 ms break the loop and continue from then on like a normal loop break.
Context : Why it is required or its application ?
Async loops are left exploitable, the control is in the hands of such an asyncGenratorOrStream, when they want the async loop to end!
I have been working on a consensus algorithm.
Where each participant node needs to send their response before a timeout for a transaction. If all the response is not received before timeout, I should collect whatver response I have got by then and break out of loop.
I get this reponse via websocket channel and its then transformed to a stream (by the framework I use) and looped to make/collect a consensus.
There is no easy way to control this, as participants can always delay their answer and let my RAM be loaded for no reason!
Proposal:
A syntactic sugar like await[timeInMs] would solve many such problems, with great ease.
I think this await[timeInMs]
can be extends to even promise (which is currently done with help of Promise.race).
await[timeInMs] gives a very clear idea (just by reading code), if a particular line be bottle neck of a code flow, and gives a much better control on async code.
The best way would be that such an await would throw an error (when tmeout occurs), which can be later caught to know if the code was transfered to next line by normal flow or timeout problem happened.
try{
for await[3000](let t of asyncGeneratorOrStream){
// blah blah....
}
}catch(e){
//by e we can know if async loop had timed out.
}
Or for a promise:
let someExpectedValue;
try{
someExpectedValue = await[3000] getFromPromise();
}catch(e){
//by e we can know if awaited promise had timed out.
}