film42 / sidekiq-rs

A port of sidekiq to rust using tokio
MIT License
95 stars 10 forks source link

Add support for unique jobs via some ttl #18

Closed film42 closed 1 year ago

film42 commented 1 year ago

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?;
    }