bull
bull copied to clipboard
Changing repeat cron timer won't be updated in redis
Apparently it's not possible to update/edit the cron timers without manually flushing the database or removing the repeating job. They will always remain the same. Below a code snippet to reproduce the issue on 3.3.0:
const testQueue = new Queue('tests', { redis: config.redisBull })
testQueue .add('buggy job', null, { repeat: { cron: '*/2 * * * *' }, removeOnComplete: true, removeOnFail: true })
testQueue .process('buggy job', lengthyJob)
function lengthyJob(_job) {
logger.info('lengthy job started')
return Promise.delay(30 * 1000).then(() => {
logger.info('Job is done')
return 'done'
})
}
This will run the lengthy job every 2 minutes. If you apply * * * * * as cron in a second run it will still be executed only every 2 minutes.
What I have expected Bull to do instead: I have expected it checking for existing repeating jobs with that name. If one with that name already exists, it would simply always overwrite the cron when it gets added.
yes, I am leaning to the solution where you can only have one cron job per name. The only problem is that it is a breaking change that would require a major release, unless we consider the current behaviour as a bug.
In what case it would be a breaking change? If I change the cron timer it won't update the existing repeating job, nor would it create a new one. Unless this bug is considered a feature, it woudn't be a breaking change I guess :D
In the sense that you can have several cron jobs under the same name, instead of only one cron job per name.
Actually I wonder how this would work, since after the edit of the cron timestamp it wouldn't add a second job with a different cron timer. I am not sure if this feature works at all right now?
Oh mabye that was the bug as mentioned in #748 , however I don't like that I would manually need to edit redis entries to change the cron timings of my jobs. I hope we can find a better design for that purpose.
My opinion is to have repeat jobs have a unique name, and not being unique by cron value. But it all broke for me in v3.3.2 (and v3.3.3) and I'm having to keep back at v3.3.1 for repeat jobs.
I also think that having multilpe repeat jobs per name is kind of useful, since named processors work better with that kind of schema. Otherwise Id have to create a named processor per cronjob?
@Freundschaft yes, you will need to specify one named processor per cronjob, but you could specify the same one several times :).
ah, makes sense thanks.
acutally isnt a solution for the problem described above, to set a custom JobId for a cronTask that needs to be updated, and later check if that crontask exists, and in case it exists, delete it and re-add it, or it could be even reasonable to add an upsert flag
ok I just figured out that a repeat job always gets a custom jobId like this
repeat:9f83cc13f62b7ea58d6c9684a06eab1b:1510773300000
no matter what I set in the jobId option, it gets overwritten. can this behavior be changed?
that is an internal key representation of the job, why would you need to "parse" it?
I was referring to the solution outlined by @ritter and thought giving a unique id to the job by overriding the jobid could be a solution. It seems this is not possible for repeat jobs if I am not mistaken, right?
This is what im trying to do:
jobQueue.add('name', {}, {
repeat: {cron: '15 3 * * *'},
jobId: cronJobId
});
@Freundschaft I do not know which solution you are referring to, can you copy it here or put a link?
its just a theoretical solution. The idea is to give every repeat job a unique name, so we can update it by its unique name later on. e.g. I have 10 shops that need synchronization every hour, so I'd like to add 10 repeat jobs, each having the unique job id of the shop id that the job belongs to. that way I can update the cronjobs or ensure that they are running, on application start, without duplicating them. Basically it would be nice if we could be able to set a handle, e.g. by customizing the jobId, so we can ensure that the repeat job is running
Would it be sufficient to just throw in a jobQueue.empty()
before calling jobQueue.add()
?