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

[8.x] Add ability to dispatch unique jobs (Option 1) #35039

Closed
wants to merge 4 commits into from
Closed

[8.x] Add ability to dispatch unique jobs (Option 1) #35039

wants to merge 4 commits into from

Conversation

paras-malhotra
Copy link
Contributor

@paras-malhotra paras-malhotra commented Oct 31, 2020

See also #35042 (alternative)

Motivation:

This PR allows the ability to dispatch unique jobs. So, if a unique job is already dispatched, it will not dispatch another job (with the same key) unless the job has completed processing. See laravel/ideas#2151.
Ping: @themsaid and @royduin

Difference between this PR and WithoutOverlapping:

The difference between WithoutOverlapping and dispatching unique jobs is that the WithoutOverlapping middleware processes jobs uniquely (meaning two jobs with the same key will not be processed in parallel). However, it does not stop jobs (with the same key) from being enqueued if another such job is already in the queue waiting to be processed.

Use Case:

This can be quite useful in scenarios such as search indexing. If a search index job is already enqueued for a resource, you probably don't want another such job to be queued until the previous job has finished processing. Sidekiq Enterprise offers the unique jobs feature as well.

How to Use

It's incredibly easy to use this. If you wish to dispatch a unique job, just chain the unique method like so:

// Unique for the model ID and timeout is set at 1 hour
MyUniqueJob::dispatch($model)->unique($model->id, 3600);

// Can also do this
dispatch(new MyUniqueJob($model))->unique($model->id, 3600);

// Global unique job with a 1 hour timeout
MyUniqueJob::dispatch(...)->unique();

@paras-malhotra
Copy link
Contributor Author

Thanks @driesvints, I've updated the formatting based on your comments. 👍

@themsaid
Copy link
Member

I think it'd be simpler if you set a unique param on the job and use it to create the lock. Also you can release the lock inside CallQueuedHandler when a job succeeds or fails. That way you won't need to use a middleware.

@paras-malhotra
Copy link
Contributor Author

paras-malhotra commented Oct 31, 2020

I think it'd be simpler if you set a unique param on the job and use it to create the lock.

@themsaid, I thought about that but it would be a breaking change if users already have that param set on the job. In that case, we'd have to target master instead of 8x. Definitely seems cleaner though.

you can release the lock inside CallQueuedHandler

I didn't want to mess with the handler code, but if you think that's a better approach, I can update the PR to do that.

@themsaid
Copy link
Member

You may call it something like $JobDeduplicationId so there's less chance it'll conflict with an existing property.

As for the handler, IMO it's fine to modify it for this feature.

@paras-malhotra paras-malhotra changed the title [8.x] Add ability to dispatch unique jobs [8.x] Add ability to dispatch unique jobs (Option 1) Oct 31, 2020
@paras-malhotra
Copy link
Contributor Author

I've opened a new PR with a different implementation/syntax as discussed.

@paras-malhotra paras-malhotra deleted the unique_jobs branch November 2, 2020 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants