Skip to content
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

Merged
merged 5 commits into from
Nov 22, 2024

Conversation

andrewsignori-aot
Copy link
Collaborator

@andrewsignori-aot andrewsignori-aot commented Nov 21, 2024

  • 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.
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.

@andrewsignori-aot andrewsignori-aot self-assigned this Nov 21, 2024
@andrewsignori-aot andrewsignori-aot marked this pull request as ready for review November 21, 2024 00:59
@andrewsignori-aot andrewsignori-aot marked this pull request as draft November 21, 2024 03:06
@andrewsignori-aot andrewsignori-aot changed the title #3667 - Bull Scheduler increments the next scheduled job when manually promoted (Remove duplicated delayed job) #3667 - Bull Scheduler increments the next scheduled job when manually promoted (Ensure Next Delayed Job) Nov 21, 2024
@andrewsignori-aot andrewsignori-aot marked this pull request as ready for review November 21, 2024 22:12
@andrepestana-aot andrepestana-aot self-requested a review November 21, 2024 22:59
@dheepak-aot dheepak-aot self-requested a review November 21, 2024 23:34
const result = cronParser.parseExpression(repeatOptions.cron, {
utc: true,
});
return result.next().toDate();
Copy link
Collaborator

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

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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;
Copy link
Collaborator

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) {
Copy link
Collaborator

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

Copy link
Collaborator Author

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) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@dheepak-aot
Copy link
Collaborator

Great work and analysis. Just 2 minor comments.

Copy link
Collaborator

@andrepestana-aot andrepestana-aot left a 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!

Copy link
Collaborator

@dheepak-aot dheepak-aot left a 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 👍

Copy link

Backend Unit Tests Coverage Report

Totals Coverage
Statements: 22.04% ( 3718 / 16866 )
Methods: 10.17% ( 214 / 2105 )
Lines: 25.38% ( 3226 / 12710 )
Branches: 13.55% ( 278 / 2051 )

Copy link

E2E Workflow Workers Coverage Report

Totals Coverage
Statements: 65.43% ( 583 / 891 )
Methods: 59.26% ( 64 / 108 )
Lines: 68.54% ( 464 / 677 )
Branches: 51.89% ( 55 / 106 )

Copy link

E2E Queue Consumers Coverage Report

Totals Coverage
Statements: 84.63% ( 1233 / 1457 )
Methods: 83.8% ( 119 / 142 )
Lines: 85.98% ( 1049 / 1220 )
Branches: 68.42% ( 65 / 95 )

Copy link

E2E SIMS API Coverage Report

Totals Coverage
Statements: 66.94% ( 5774 / 8625 )
Methods: 64.8% ( 718 / 1108 )
Lines: 70.87% ( 4531 / 6393 )
Branches: 46.71% ( 525 / 1124 )

@andrewsignori-aot andrewsignori-aot added this pull request to the merge queue Nov 22, 2024
Merged via the queue into main with commit 3e8eb73 Nov 22, 2024
20 checks passed
andrewsignori-aot added a commit that referenced this pull request Nov 25, 2024
…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.
andrewsignori-aot added a commit that referenced this pull request Nov 25, 2024
…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.
@andrewsignori-aot andrewsignori-aot deleted the feature/#3667-remove-multiple-delayed-jobs branch November 25, 2024 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants