-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#3667 - Bull Scheduler increments the next scheduled job when manually promoted (Ensure Next Delayed Job) #3978
#3667 - Bull Scheduler increments the next scheduled job when manually promoted (Ensure Next Delayed Job) #3978
Conversation
andrewsignori-aot
commented
Nov 21, 2024
•
edited
Loading
edited
- Ensures a scheduled job will have a delayed job created with the next expected scheduled time based on the configured cron expression.
- DB row used as a lock to ensure the initialization code will not recreate delayed jobs or create them in an unwanted way if two PODs start at the same time. To be clear, the lock approach is the same used in other areas of the application and locks a single row in the table queue-consumers, please not, the table will not be locked. Please see below the sample query executed.
- While the queue is paused, no other delayed jobs will be created.
const result = cronParser.parseExpression(repeatOptions.cron, { | ||
utc: true, | ||
}); | ||
return result.next().toDate(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can return milliseconds here result.next().getMilliseconds()
and do a millisecond comparison between nextSchedulerExecutionDate
and delayedJobExecutionDate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would work but IMO it would be clear to have a proper date.
Is the idea to avoid using the dayjs?
I will give it a try to see if the readability is still good enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The getMilliseconds
does not contain the total milliseconds.
I would prefer to keep the current implementation unless it would be a bloker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested with getDate
(similar to the Date) and it seems all good.
* @returns calculated execution date for the delayed job. | ||
*/ | ||
getDelayedJobExecutionDate(delayedJob: Job): Date { | ||
const totalMilliseconds = delayedJob.opts.delay + delayedJob.timestamp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a great analysis to consider the delay to the job timestamp. ❤️
} | ||
// Remove any non expected delayed job. | ||
for (const delayedJob of delayedJobs) { | ||
if (!expectedDelayedJob || delayedJob !== expectedDelayedJob) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Asking for my understanding, will comparing the job ids alone work ? delayedJob.id !== expectedDelayedJob.id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea here is to compare the object reference, which will be pretty precise.
Is there a benefit using the id?
queueName: QueueNames, | ||
callback: () => Promise<void>, | ||
): Promise<void> { | ||
await this.dataSource.transaction(async (entityManager) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Great work and analysis. Just 2 minor comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great analysis and implementation! Looks good to me!
Quality Gate passedIssues Measures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the changes. Looks good 👍
…y promoted (Ensure Next Delayed Job) (#3978) - Ensures a scheduled job will have a delayed job created with the next expected scheduled time based on the configured cron expression. - DB row used as a lock to ensure the initialization code will not recreate delayed jobs or create them in an unwanted way if two PODs start at the same time. To be clear, the lock approach is the same used in other areas of the application and locks a single row in the table queue-consumers, please not, the table will not be locked. Please see below the sample query executed. ```sql START TRANSACTION select "QueueConfiguration"."id" AS "QueueConfiguration_id" from "sims"."queue_configurations" "QueueConfiguration" where (("QueueConfiguration"."queue_name" = 'archive-applications')) LIMIT 1 FOR UPDATE COMMIT ``` - While the queue is paused, no other delayed jobs will be created.
…y promoted (Ensure Next Delayed Job) (#3978) - Ensures a scheduled job will have a delayed job created with the next expected scheduled time based on the configured cron expression. - DB row used as a lock to ensure the initialization code will not recreate delayed jobs or create them in an unwanted way if two PODs start at the same time. To be clear, the lock approach is the same used in other areas of the application and locks a single row in the table queue-consumers, please not, the table will not be locked. Please see below the sample query executed. ```sql START TRANSACTION select "QueueConfiguration"."id" AS "QueueConfiguration_id" from "sims"."queue_configurations" "QueueConfiguration" where (("QueueConfiguration"."queue_name" = 'archive-applications')) LIMIT 1 FOR UPDATE COMMIT ``` - While the queue is paused, no other delayed jobs will be created.