IBM / cloudant-node-sdk

Cloudant SDK for Node.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for additional retry options

kvv002 opened this issue · comments

Currently the SDK supports 2 options for retry mechanism:
- maxRetries
- maxRetryInterval
We have a requirement where the SDK could explore all the additional options as retry-axios

As I said in #410 (comment) if you want this enhancement it needs to be in the node-sdk-core.

I will transfer this issue there, but _ before_ I do that I would like you to provide some more clarity on your requirement because AIUI the behaviour you asked for:
statusCodesToRetry: ['ENOTFOUND']
will not work in retry-axios anyway.
The list of retry codes are only applied to HTTP status codes on a response when it is present (there is no response in an ENOTFOUND case).

Is that really what you to do, retry onlyENOTFOUND errors? The default retry-axios config of noResponseRetries: 2 will retry those errors twice anyway (in addition to the other errors).

Hi @ricellis ,
We would like sdk to support all the errors or codes the user inputs,
This is how it was working using the cloudant driver:

    this.cloudant = cloudantDriver({
      account: this.username,
      password: this.password,
      plugins: {
        retry: {
          retryErrors: false,
          retryStatusCodes:
        [429, 502, 503, 504, 'ECONNRESET', 'ETIMEDOUT', 'EHOSTUNREACH', 'EAI_AGAIN', 'ECONNREFUSED', 'EAI_AGAIN', 'EPIPE'],
          retryInitialDelayMsecs: constants.retryDelay,
          retryDelayMultiplier: constants.retryDelayMultiplier
        }
      },
      maxAttempt: constants.maxAttempts
    })

We would like SDK to support something like above.
With the axios I have tried the below snippet using shouldRetry to support the possible errors, but now we are stuck at implementing timeout and percall timeout with axios.

const AxiosError  =  [429, 502, 503, 504, 400,'ENOTFOUND', 'ECONNRESET', 'ETIMEDOUT', 'EHOSTUNREACH', 'EAI_AGAIN', 'ECONNREFUSED', 'EAI_AGAIN', 'EPIPE']

service.requestWrapperInstance.axiosInstance.defaults.raxConfig = {
  // ... retry-axios config options
  retry: 5, 
  backoffType: 'exponential',
  retryDelay: 10, 
  // statusCodesToRetry: [[100, 199], [400, 429], [500, 599], [404]],
  shouldRetry: (err) => {
    const errorCode = err.status || err.code || err.response.status
    console.log('----errorCode-----', errorCode)
    const cfg = rax.getConfig(err);
    if (AxiosError.indexOf(errorCode) !== -1 && cfg.currentRetryAttempt < cfg.retry) { //retry codes
      // This delay calculation is adapted from 'retry-axios' index.ts
      const TIME_ELAPSED = (new Date() - start) / 1000
      console.log('---time elapsed---', TIME_ELAPSED)
      if (TIME_ELAPSED < timeout) {
        return true
      } else {
        return false
      }
    } else {
      return false
    }
  },
  onRetryAttempt: err => {
    const cfg = rax.getConfig(err);
    console.log('---err--2--', err.code, err.status)
    console.log(`Retry attempt #${cfg.currentRetryAttempt}`);
  },
  instance: service.requestWrapperInstance.axiosInstance,
};

This is how it was working using the cloudant driver:

Well the @cloudant/cloudant retry plugin documents its retryStatusCodes as:

retryStatusCodes
A list of HTTP status codes that should be retried (default: 429, 500, 501, 502, 503, 504).

So unless you had a custom fork with a different retry plugin you are trying to emulate something that didn't work the way you think. The option to retry ENOTFOUND and friends in @cloudant/cloudant is retryErrors: true.

We would like SDK to support something like above.

service.enableRetries() is like what you show for cloudantDriver above except that:

  • it will additionally retry 500 and 501
  • it won't retry POST requests (retry-axios does not do so by default) - and FWIW I would like to see cloudant-node-sdk change this default given the extent to which POST is used in the Cloudant API.

it won't retry POST requests (retry-axios does not do so by default) - and FWIW I would like to see cloudant-node-sdk change this default given the extent to which POST is used in the Cloudant API.

This part is now merged via #504, so POST requests will also be retried when using service.enableRetries() from the next release.

I see there is IBM/node-sdk-core#163 discussing additional configuration so I'm closing this.