Project

placate

0.0
The project is in a healthy, maintained state
Prevents duplicate job execution using Redis locks for any Redis-based job processing system
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 7.0
~> 5.16
~> 13.0
~> 1.21
 Project Readme

Placate

Placate is a lightweight Redis-based solution designed to prevent duplicate jobs in Rails ActiveJob.

Installation

Add this line to your application's Gemfile:

gem 'placate'

And then execute:

bundle install

Usage

Basic Setup

First, configure Placate with your Redis connection:

# config/initializers/placate.rb
Placate.configure do |config|
  config.redis = Redis.new

  # time-to-live in seconds
  # default is nil, which only allows 1 job to be queued at a time
  # config.default_lock_ttl = 30 
end

In Your Jobs

Include the UniqueJob module in any job you want to prevent duplicates:

class ProcessOrderJob < ApplicationJob
  include Placate::UniqueJob
  
  def perform(order_id)
    # Your job code here
  end
end

Now if you try to enqueue the same job with the same arguments within the TTL window, the duplicate will be prevented:

ProcessOrderJob.perform_later(order_id: 123) # First job enqueued
ProcessOrderJob.perform_later(order_id: 123) # Blocked as duplicate
ProcessOrderJob.perform_later(order_id: 456) # Different args, will be enqueued

Customization

You can customize the TTL per job class:

class LongRunningJob < ApplicationJob
  include Placate::UniqueJob
  
  self.unique_lock_ttl = 120 # 2 minutes
  
  def perform
    # Your job code here
  end
end

Or use a custom key prefix:

class CustomPrefixJob < ApplicationJob
  include Placate::UniqueJob
  
  self.unique_lock_prefix = 'my_app_jobs'
  
  def perform
    # Your job code here
  end
end

How It Works

Placate uses Redis to maintain a lock based on the job class name and arguments. When a job is enqueued (before_enqueue):

  1. A unique key is generated based on the job class and arguments
  2. The current timestamp is stored in Redis with this key
  3. If a key exists and its timestamp is within the TTL window, the job is not enqueued
  4. If no key exists or the existing timestamp is older than the TTL, the job is enqueued

After the job is performed (after_perform):

  1. The unique key is deleted, to enable the next job.

Requirements

  • Ruby 3.3+
  • Rails 7.0+
  • Redis

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

Contributing

Bug reports and pull requests are welcome on GitHub. This project is intended to be a safe, welcoming space for collaboration.

License

The gem is available as open source under the terms of the MIT License.