When a job is enqueued its args are hashed and attempts to "lock" those args for some worker for the TTL. Once it expires, a new job will be enqueued.
The interface does not introduce any breaking changes other than a new field that is defined on Job but is not serialized.
#[derive(Clone)]
struct CustomerNotificationWorker;
#[async_trait]
impl Worker<CustomerNotification> for CustomerNotificationWorker {
fn opts() -> sidekiq::WorkerOpts<CustomerNotification, Self> {
// Use default options to set the unique_for option by default.
sidekiq::WorkerOpts::new()
.queue("customers")
.unique_for(std::time::Duration::from_secs(30))
}
async fn perform(&self, _args: CustomerNotification) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
}
Note: It sets default options to declare that this job should be checked for uniqueness at enqueue time.
The following code will then only end up enqueueing a single job since the ttl is 30 seconds.
// Create a bunch of jobs with the default uniqueness options. Only
// one of these should be created within a 30 second period.
for _ in 1..10 {
CustomerNotificationWorker::perform_async(
&mut redis,
CustomerNotification {
customer_guid: "CST-123".to_string(),
},
)
.await?;
}
When a job is enqueued its args are hashed and attempts to "lock" those args for some worker for the TTL. Once it expires, a new job will be enqueued.
The interface does not introduce any breaking changes other than a new field that is defined on
Job
but is not serialized.Note: It sets default options to declare that this job should be checked for uniqueness at enqueue time.
The following code will then only end up enqueueing a single job since the ttl is 30 seconds.