bullmq icon indicating copy to clipboard operation
bullmq copied to clipboard

Custom backoff strategies are now too restrictive/limited

Open yaro90 opened this issue 1 year ago • 3 comments

Is your feature request related to a problem? Please describe. Since version 3.0 custom backoff strategies became far more restrictive/limited and now support a lot less use cases, we cannot even pass a delay value to the custom strategy like it is possible for the builtin strategies... I'm not sure why this logic needed to change, but after looking through bits of source code it seems more like a change for the sake of changing.

Describe the solution you'd like Allow for the options object to be passed to a custom back off like previously:

backoff: {
      type: 'cappedExponential',
      options: { delay: 200, maxDelay: 1000 }
}

Describe alternatives you've considered

  • Create a bunch more duplicate backoff strategy types with hard coded values and a massive switch statement since options cannot be passed now.
  • Add something into the type string and write parse logic for it, for example cappedExponential:200:1000. This approach just feels more like a hack or a workaround.

Additional context None.

yaro90 avatar Oct 06 '23 10:10 yaro90

hey @yaro90, so basically the breaking change is this one https://github.com/taskforcesh/bullmq/pull/1463/files#diff-902c6b7974802c11b853851fbebd1f0d22e35c9469fdb7fb55c4a4d339aefa85R4-R7 and we are adding a type attribute but not deleting params on backoffStrategy function

roggervalf avatar Nov 01 '23 04:11 roggervalf

Hi @roggervalf, I'm not sure if its the right PR of if it was broken with just 1 PR, here is what I was able to do previously in v1.82.2:

defaultJobOptions: {
  backoff: {
    type: 'cappedExponential',
    options: { delay: 200, maxDelay: 1000 }
  }
}

defaultWorkerOptions: {
     settings: {
      backoffStrategies: {
        cappedExponential: (attemptsMade, err, options) => {
          if (!options) options = {};
          const delay = options.delay || 200;
          const maxDelay = options.maxDelay || 1400;
          const backoff = Math.round((Math.pow(2, attemptsMade) - 1) * delay);
          return (backoff < maxDelay) ? backoff : maxDelay;
        }
      }
    }
}

yaro90 avatar Nov 01 '23 18:11 yaro90

hey @yaro90, so in your case you can try:

import { Worker } from 'bullmq';

const worker = new Worker('foo', async job => doSomeProcessing(), {
  settings: {
    backoffStrategy: (
      attemptsMade: number,
      type: string,
      err: Error,
      job: Job,
    ) => {
      switch (type) {
        case 'cappedExponential': {
          const options = job.opts?job.opts:{};
          const delay = options.delay || 200;
          const maxDelay = options.maxDelay || 1400;
          const backoff = Math.round((Math.pow(2, attemptsMade) - 1) * delay);
          return (backoff < maxDelay) ? backoff : maxDelay;
        }
        default: {
          throw new Error('invalid type');
        }
      }
    },
  },
});

roggervalf avatar Nov 14 '23 03:11 roggervalf