(url, timeout)
| 7 | * is implemented using https://github.com/sindresorhus/got |
| 8 | */ |
| 9 | const ping = (url, timeout) => { |
| 10 | if (!timeout) { |
| 11 | throw new Error('Expected timeout in ms') |
| 12 | } |
| 13 | |
| 14 | // make copy of the error codes that "got" retries on |
| 15 | const errorCodes = [...got.defaults.options.retry.errorCodes] |
| 16 | errorCodes.push('ESOCKETTIMEDOUT') |
| 17 | |
| 18 | // we expect the server to respond within a time limit |
| 19 | // and if it does not - retry up to total "timeout" duration |
| 20 | const individualPingTimeout = Math.min(timeout, 30000) |
| 21 | |
| 22 | // add to the timeout max individual ping timeout |
| 23 | // to avoid long-waiting ping from "rolling" over the end |
| 24 | // and preventing pinging the last time |
| 25 | timeout += individualPingTimeout |
| 26 | const limit = Math.ceil(timeout / individualPingTimeout) |
| 27 | |
| 28 | debug(`total ping timeout ${timeout}`) |
| 29 | debug(`individual ping timeout ${individualPingTimeout}ms`) |
| 30 | debug(`retries limit ${limit}`) |
| 31 | |
| 32 | const start = +new Date() |
| 33 | return got(url, { |
| 34 | headers: { |
| 35 | Accept: 'text/html, application/json, text/plain, */*' |
| 36 | }, |
| 37 | timeout: individualPingTimeout, |
| 38 | errorCodes, |
| 39 | retry: { |
| 40 | limit, |
| 41 | calculateDelay({ error, attemptCount }) { |
| 42 | if (error) { |
| 43 | debug(`got error ${JSON.stringify(error)}`) |
| 44 | } |
| 45 | const now = +new Date() |
| 46 | const elapsed = now - start |
| 47 | debug( |
| 48 | `${elapsed}ms ${error.method} ${error.host} ${error.code} attempt ${attemptCount}` |
| 49 | ) |
| 50 | if (elapsed > timeout) { |
| 51 | console.error( |
| 52 | '%s timed out on retry %d of %d, elapsed %dms, limit %dms', |
| 53 | url, |
| 54 | attemptCount, |
| 55 | limit, |
| 56 | elapsed, |
| 57 | timeout |
| 58 | ) |
| 59 | return 0 |
| 60 | } |
| 61 | |
| 62 | // if the error code is ECONNREFUSED use shorter timeout |
| 63 | // because the server is probably starting |
| 64 | if (error.code === 'ECONNREFUSED') { |
| 65 | return 1000 |
| 66 | } |
no outgoing calls
no test coverage detected