question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature: Timeout, Retry, and Queue

See original GitHub issue

I’m writing my thoughts down here, because I do not have the time right now to dedicate to adding this, however hopefully someone in the community might be able to. I’m closing #66, #69, #73 in favor of this single issue.

cc @kasbah @akmjenkins @davidgovea

Retry

We should not retry on all 500 status error codes as every other fetch retry package does - instead we should retry only based off of it isRetryAllowed(err) returns true by using is-retry-allowed OR if the response had a 429, 502, 503, or 504 status code.

We should also only retry on GET, PUT, HEAD, DELETE, OPTIONS, or TRACE methods. Our approach should also respect the Retry-After response header (see https://github.com/sindresorhus/got/blob/6eaa81ba8db87340bbdbd79ef91594803f37b854/source/normalize-arguments.ts#L231-L241 for inspiration.

In general our approach will be very similar to got and ky (e.g. https://github.com/sindresorhus/ky).

It should be up to the application layer to retry if a successful server response status code occurs, and it should not be fetch nor frisbee responsibility to retry based off a server response (which is why we will not use packages like fetch-retry-or-die, make-fetch-happen, nor fetch-retry (because all of these implementations retry on 5xx status codes and none of them respect the actual error code). If a server responds, it’s considered to be successful.

Finally, if someone aborts a Frisbee fetch request using AbortController, then the retries should be aborted as well and it should not retry from an AbortError. This should happen automatically out of the box, but I wanted to write it down. The best way to detect abort errors is probably the same as we do with tests, via err.name === 'AbortError' (see https://github.com/niftylettuce/frisbee/blob/master/test/node.test.js#L334).

I think that we can use the p-retry package and allow a global retry option via new Frisbee({ retry: { ... } }), and for individual API methods such as frisbee.get('/', { retry: { ... } }) as well. If an individual API method specifies a retry object, then p-retry should use that, otherwise if a global option was passed it will use it. There are several other packages that are very similar (most of which use node-retry as well), however I trust @sindresorhus and his dedication to open source maintenance and quality, therefore I would use p-retry above all.

We should also respect the Retry-After header per https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After for 429 status codes.

Timeout

A timeout event should cause a retry, therefore we need to make sure the error we throw on a timeout (namely its code) returns true from isRetryAllowed(err). To properly design this, we should either use an existing AbortController passed, or create a new AbortController for each request. If the timeout is triggered, then it would signal an abort with an error created via const error = new Error('ETIMEDOUT'); error.code = 'ETIMEDOUT'; (similar to how request does it here https://github.com/request/request/blob/df346d8531ac4b8c360df301f228d5767d0e374e/request.js#L848-L849). By using AbortController, we can ensure that the fetch attempted is actually aborted, and will not be completed/return a response after the timeout error occurs.

Unfortunately we cannot use any existing fetch timeout packages because all of them polyfill or have odd implementations of detecting which fetch implementation to use, therefore we have to write this ourselves.

We can most likely use p-timeout for this.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:6
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
niftylettucecommented, Jun 21, 2019

I pushed my work in progress by the way at https://github.com/niftylettuce/frisbee/commit/38d225256f87a1ede5ae616b576da166206dd8a4 if anyone wants to help out with it.

I would love help writing tests for it. Timeouts/retries all need tested.

2reactions
niftylettucecommented, Jun 7, 2019

Just FYI I already implemented timeout and retry locally. Just need to push it up. I definitely need some help with tests.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Will Queue Trigger Auto retry after meet function timeout
1 Answer 1 ... When a function times out, an exception is thrown; however, it shouldn't interrupt other functions currently running. A queue- ......
Read more >
Understanding SQS retries - AWS Lambda
The specific retry behavior for processing SQS messages is determined in the SQS queue configuration. Here you can set the visibility timeout ,...
Read more >
The 4 Types of Activity timeouts - Temporal.io
The Schedule-To-Start Timeout is most useful when you have a concrete plan to reroute an Activity Task to a different Task Queue, if...
Read more >
Retry guidance for Azure services - Microsoft Learn
This guide summarizes the retry mechanism features for most Azure services, and includes information to help you use, adapt, or extend the ...
Read more >
To Retry Queue or to not Retry Queue - Support - PDQ
Purpose The Retry Queue is designed to ensure offline targets receive the patches they deserve. When a target is offline during a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found