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

Add support for unique jobs #108

Merged
merged 3 commits into from
Dec 7, 2022
Merged

Conversation

sheldonreiff
Copy link
Contributor

This adds support for queueing unique jobs. When enabled for a given job, it will be (nearly) guaranteed that no other jobs with the same data will be present on the queue simultaneously.

Sometimes when the same job with the same payload is queued multiple times before other instances of the job are able to be run, it's not useful to run the job multiple times, once is enough, so this aims to address that.

@sheldonreiff sheldonreiff force-pushed the unique-jobs branch 6 times, most recently from e1e9611 to 84324fe Compare November 17, 2022 20:16
// remain on the queue. Otherwise, duplicate jobs may be possible. Defaults to +24 hours.
// See https://book.cakephp.org/4/en/core-libraries/caching.html#configuring-cache-engines.
'uniqueCache' => [
'engine' => 'File',
Copy link
Member

Choose a reason for hiding this comment

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

Should we suggest a safer default? Using files will not ensure uniqueness across multiple servers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I think that makes sense. I wasn't really considering this example a suggestion, I just went with the simplest example. Maybe this should be called out in the comments above?

Copy link
Member

Choose a reason for hiding this comment

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

I think we can mention the File engine as only suitable for local development.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 I added a note

if (!empty($class::$shouldBeUnique)) {
$uniqueId = static::getUniqueId($class, $method, $data);

Cache::write($uniqueId, true, 'Cake/Queue.queueUnique');
Copy link
Member

Choose a reason for hiding this comment

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

Should we use the atomic write method add() instead? While it doesn't do anything special for file storage for memcache/redis it offers better atomicity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I'll defer to you on that, I wasn't immediately able to find documentation on add().

Copy link
Member

Choose a reason for hiding this comment

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

Oh darn, I didn't know we were missing docs for that method. I'll get that fixed.

*
* @var bool
*/
public static $shouldBeUnique = false;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure if this should be in the template or if users should add the property as needed. It doesn't have to be present, absence is assumed false. And really, this applies to maxAttempts as well. Let me know if you have thoughts on this.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think they need to be in the template. Having them only in the docs is fine. If you wanted to get really fancy, you could add CLI options to the bake task.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like the CLI option idea, I threw that in for this. I'll do that for the failed jobs one later and separately.

$this->assertNull(Cache::read($uniqueId, 'Cake/Queue.queueUnique'));
}

protected function setupQeueue($extensionArgs = [])
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
protected function setupQeueue($extensionArgs = [])
protected function setupQueue($extensionArgs = [])

This typo shows up a few times.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oops... fixed.

$uniqueId = static::getUniqueId($class, $method, $data);

if (Cache::read($uniqueId, 'Cake/Queue.queueUnique')) {
return;
Copy link
Member

Choose a reason for hiding this comment

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

Should this have a debug level log message emitted? It could be useful for debugging why messages that are enqueued are dropped.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

makes sense to me, I added logging if a logger is set

@markstory
Copy link
Member

Thank you 🎉

@sheldonreiff sheldonreiff deleted the unique-jobs branch December 7, 2022 16:14
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.

2 participants