宝石允许通过下一个策略保护工作独特性:
战略 | 这份工作被锁定 | 这项工作已解锁 |
---|---|---|
until_executing | 当被推到队列时 | 处理开始时 |
until_executed | 当被推到队列时 | 成功处理工作时 |
until_expired | 当被推到队列时 | 当锁定过期时 |
until_and_while_executing | 当被推到队列时 | 处理开始时 获取运行时锁以防止同时工作 有额外的选项: runtime_lock_ttl , on_runtime_conflict |
while_executing | 处理开始时 | 处理工作时 任何结果包括错误 |
受兜帽的启发,在引擎盖下使用redlock。
将activejob-uniqueness
Gem添加到您的Gemfile中。
gem 'activejob-uniqueness'
如果您想为Sidekiq Web UI解锁工作,请明确要求补丁。队列清理变慢了!
gem 'activejob-uniqueness' , require : 'active_job/uniqueness/sidekiq_patch'
并运行bundle install
命令。
ActiveJob ::唯一性可以在没有任何配置的情况下工作。它将使用REDIS_URL
连接到redis实例。要覆盖默认值,请使用以下命令创建一个initializer config/initializers/active_job_uniqueness.rb
:
rails generate active_job:uniqueness:install
class MyJob < ActiveJob :: Base
# new jobs with the same args will raise error until existing one is executed
unique :until_executed
def perform ( args )
# work
end
end
class MyJob < ActiveJob :: Base
# new jobs with the same args will be logged within 3 hours or until existing one is being executing
unique :until_executing , lock_ttl : 3 . hours , on_conflict : :log
def perform ( args )
# work
end
end
您可以使用配置在全球设置默认值
class MyJob < ActiveJob :: Base
# Proc gets the job instance including its arguments
unique :until_executing , on_conflict : -> ( job ) { job . logger . info "Oops: #{ job . arguments } " }
def perform ( args )
# work
end
end
class MyJob < ActiveJob :: Base
unique :until_executed
def perform ( foo , bar , baz )
# work
end
def lock_key_arguments
arguments . first ( 2 ) # baz is ignored
end
end
class MyJob < ActiveJob :: Base
unique :until_executed
def perform ( foo , bar , baz )
# work
end
def lock_key
'qux' # completely custom lock key
end
def runtime_lock_key
'quux' # completely custom runtime lock key for :until_and_while_executing
end
end
所选策略会自动解锁作业,但在某些情况下(例如,清除了队列),手动解锁作业很方便。
# Remove the lock for particular arguments:
MyJob . unlock! ( foo : 'bar' )
# or
ActiveJob :: Uniqueness . unlock! ( job_class_name : 'MyJob' , arguments : [ { foo : 'bar' } ] )
# Remove all locks of MyJob
MyJob . unlock!
# or
ActiveJob :: Uniqueness . unlock! ( job_class_name : 'MyJob' )
# Remove all locks
ActiveJob :: Uniqueness . unlock!
很可能您不希望作业被锁定在测试中。将此行添加到您的测试套件( rails_helper.rb
):
ActiveJob :: Uniqueness . test_mode!
ActiveJob ::独特仪器ActiveSupport::Notifications
:
lock.active_job_uniqueness
runtime_lock.active_job_uniqueness
unlock.active_job_uniqueness
runtime_unlock.active_job_uniqueness
conflict.active_job_uniqueness
runtime_conflict.active_job_uniqueness
然后写入ActiveJob::Base.logger
。
在第6.1
版之前的ActiveJob将始终记录Enqueued MyJob (Job ID) ...
即使回调链被停止。细节
运行Redis服务器(在单独的控制台中):
docker run --rm -p 6379:6379 redis
运行测试:
bundle
rake
ActiveJob ::唯一性支持Sidekiq API在队列清理上解开工作锁(例如,通过Sidekiq Web UI)。起始Sidekiq 5.1工作死亡还会触发清理工作。考虑到大型排队清理的变化要慢得多,因为每个作业都会单独解锁。为了激活sidekiq api补丁,需要在您的gemfile中明确它:
gem 'activejob-uniqueness' , require : 'active_job/uniqueness/sidekiq_patch'
欢迎在https://github.com/veeqo/activejob-iniques上的GitHub上的错误报告和拉动请求。
根据MIT许可证的条款,该宝石可作为开源。
在Veeqo,我们的工程师团队的任务是创建一个世界一流的库存和运输平台,该平台是最佳编码实践中最高标准的。我们是一支成长中的团队,正在寻找其他热情的开发人员加入我们的旅程。如果您正在寻找在电子商务中最激动人心的科技公司之一工作的职业,我们希望收到您的来信。
Veeqo开发人员博客