-
Notifications
You must be signed in to change notification settings - Fork 15
Retry operation when network connection is down. #31
Changes from 1 commit
df07d7e
82d4476
69587f6
515702d
5d185f5
a284ddf
3d9a597
9b4a8e4
f8dd7f3
e192582
4ffe13c
f4e61ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -91,6 +91,20 @@ function validateRetryConfig<T>(config: RetryConfig<T>): void { | |
| } | ||
| } | ||
|
|
||
|
|
||
| async function checkInternet(): Promise<boolean> { | ||
| return new Promise((resolve) => { | ||
| require("dns").lookup("ms.portal.azure.com", function (err: any): void { | ||
|
ShivangiReja marked this conversation as resolved.
Outdated
|
||
| if (err && err.code === "ENOTFOUND") { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be possible that the this dns query resolves even when the connection is not there? For instance, if there is a dns cache it might be possible that the value is returned from the cache without doing a network call.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch!
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's still possible to "resolve" without having "internet" FWIW. This occurs often on our wifi network - DNS queries work as the DNS server is within our LAN (still a few hops away), but access to the outside world is broken. I think this feature should be understood as a 90% sort of solution for "ethernet unplugged" and "switching to/from wifi" scenarios. |
||
| resolve(false); | ||
| } else { | ||
| resolve(true); | ||
| } | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * It will attempt to linearly retry an operation specified number of times with a specified | ||
| * delay in between each retry. The retries will only happen if the error is retryable. | ||
|
|
@@ -122,6 +136,11 @@ export async function retry<T>(config: RetryConfig<T>): Promise<T> { | |
| if (!err.translated) { | ||
| err = translate(err); | ||
| } | ||
| const isConnected = await checkInternet(); | ||
| if (!isConnected) { | ||
| err.name = "ConnectionDetachError"; | ||
| err.retryable = true; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We make this check for every error seen by every Also, maybe we should only add this check when we see the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Also, I believe that if the error is not retryable and if the network connection is down, we should anyways retry the operation. What do you think ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the network was down, then we wouldn't be getting any error from the service in the first place isn't it?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So you mean that we always get the same Also, what I am proposing above is that it doesn't matter whether we always get the ServiceCommunicationError or not, we should retry if the error is not retryable and we are not connected to the internet.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the network is down and we make a network request, Nodejs will always give ENOTFOUND error and amqp-common translates that to ENOTFOUND can happen due to multiple reasons, network being down is one of them.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just one more concern about this :)
This case is specific for our Event Hub and Service bus SDK. If other user will use the same retry method of Amqp-common, will they get the same ENOTFOUND error?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Re: ENOTFOUND, neither Node docs, errno docs, or getaddrinfo docs say anything about this error. However, a search of GitHub code shows we are not the only ones responding to this kind of error, so I find it extremely unlikely Node would change this error in the future. I've sent some tweets on the topic, will get back here if I hear anything different.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ENOTFOUND is indeed not a real posix error and that explains why it's hard to find any info on it. It's actually a node-specific error that isn't documented. The source of the error is here. While the comment implies the error will go away, on twitter, Anna (Node core member) suggests the error won't change and agrees that the comment should be removed and the error documented. I can push on that if we find it important, but personally I'm satisfied that this behavior won't change because of all the things that would break.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Are you saying that we should rename
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Closing the loop here based on offline conversation
amqp-common is tightly coupled with rhea-promise and rhea. So, all users of amqp-common will get the Also, lets rename |
||
| } | ||
| lastError = err; | ||
| log.error("[%s] Error occured for '%s' in attempt number %d: %O", config.connectionId, | ||
| config.operationType, j, err); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.