API polling and timeout

非 Y 不嫁゛ 提交于 2021-02-11 08:52:06

问题


I have a polling use-case where:

  1. I want to call an API that, based on business logic, returns numbers(1-10) or error (network issue/ exception in API etc..) instantly (1.5-2 sec).
  2. If the API returns an error (network issue/ exception in API etc..) then I want to unsubscribe the polling and display error.
  3. If the API returns success, I want to check the return value and un-subscribe(if the return value is 5) or keep the polling going.
  4. I want to call API every 5 sec.
  5. I want to keep the max time(timeout/threshold) for the polling as 3mins. If I don't get the desired response(number 5) in these 3mins, the polling should error out.

This is how I have implemented it currently:

this.trackSpoke$ = interval(5000)
                .pipe(
                    timeout(250000),
                    startWith(0),
                    switchMap(() =>
                        this.sharedService.pollForAPropertyValue(
                            "newuser"
                        )
                    )
                )
                .subscribe(
                    (data: SpokeProperty) => {
                        this.CheckSpokeStatus(data);
                    },
                    error => {
                        this.trackSpoke$.unsubscribe();
                        this.createSpokeState.CdhResponseTimedOut();
                    }
                );


private CheckSpokeStatus(data) {
        if (data.PropertyValue === "5") {
            this.trackSpoke$.unsubscribe();
            //display success   
        } else {
              //keep the polling going
        }
    }

But, the above implementation is not timing out.

What needs to be done so that it times out and I am able to achieve all mentioned use-case?


回答1:


First of all using interval for API polling is quite an anti-pattern because interval won't "wait" for your http request to finish - potentially triggering multiple requests (if the request takes more then 5s to complete).

I prefer to use defer with repeatWhen and delay (see the code below).

The timeout is not triggering because the interval is ticking every 5s preventing the timeout from ever occurring. The defer/repeatWhen combo should also fix that.

Instead of manually unsubscribing consider using takeWhile to unsubscribe the Observable for you.

Also using this.trackSpoke$.unsubscribe(); in the error handler is not needed because Observable is unsubscribed automatically in case of an error.

this.trackSpoke$ = defer(() => this.sharedService.pollForAPropertyValue("newuser"))
    .pipe(
        timeout(250000),
        repeatWhen(notifications => notifications.delay(5000)),
        takeWhile(data => this.CheckSpokeStatus(data)),
    )
    .subscribe(
        error => {
            this.createSpokeState.CdhResponseTimedOut();
        }
    );


private CheckSpokeStatus(data) {
    return data.PropertyValue !== "5";
}


来源:https://stackoverflow.com/questions/51894239/api-polling-and-timeout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!