Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is async recursion will be safe in Js code for polling fn

As I have heard, and actually know recursion is far not better solution for many cases if talk about sync code. But i would like to ask someone who more experienced than I am about the solution. What do you think about this code? It will work okay (as I suppose now - cause it is not syncronous) or may be it has some significant (or not so) drawbacks? Where? Why?
Guys, I would very appreciate your help, I'm doubtfull about this part of code.

Maybe there is a better solution for this?

I just want to have function which will be able to run promise function (class method) every exact time span + time for resolving this async functon.
If still enough clear.. Step by step it should -
exec target promise fn ->
waiting for resolve ->
waiting for interval ->
exec target promise fn.

And additionally it should stop if promise fn failed

Thanks in advance!

    export function poll(fn: Function, every: number): number {
      let pollId = 0;

      const pollRecursive = async () => {
        try {
          await fn();
        } catch (e) {
          console.error('Polling was interrupted due to the error', e);
          return;
        }
        pollId = window.setTimeout(() => {
          pollRecursive();
        }, every);
      };

      pollRecursive();

      return pollId;

    }
like image 745
Denis Khay Avatar asked Feb 24 '26 09:02

Denis Khay


1 Answers

Although you have a call to pollRecursive within the function definition, what you actually do is pass a new anonymous function that will call pollRecursive when triggered by setTimeout.

The timeout sets when to queue the call to pollRecursive, but depending on the contents of that queue, the actually function will be run slightly later. In any case, it allows all other items in the queue to process in turn, unlike a tight loop / tight recursive calls, which would block the main thread.

The one addition you may want to add is more graceful error handling, as transient faults are common on the Internet (i.e. there are a lot of places where something can go missing, which makes regular failed request part of "normal business" for a TypeScript app that polls).

In your catch block, you could still re-attempt the call after the next timer, rather than stop processing. This would handle transient faults.

To avoid overloading the server after a fault, you can back off exponentially (i.e. double the every value for each contiguous fault). This reduces server load, while still enabling your application to come back online later.

If you are running at scale, you should also add jitter to this back off, otherwise the server will be flooded 2, 4, 8, 16, 32... seconds after a minor fault. This is called a stampede. By adding a little random jitter, the clients don't all come back at once.

like image 159
Fenton Avatar answered Feb 26 '26 03:02

Fenton



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!