bullmq
bullmq copied to clipboard
Custom backoff strategies are now too restrictive/limited
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 examplecappedExponential:200:1000
. This approach just feels more like a hack or a workaround.
Additional context None.
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
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;
}
}
}
}
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');
}
}
},
},
});