Skip to content

Commit

Permalink
Split calculator into two separate (#474)
Browse files Browse the repository at this point in the history
* Split calculator into two separate

Also kills a lot of duplication in using temporary configuration.

* Updates documentation

* Lock down simplecov to last known working version
  • Loading branch information
mhenrixon authored Mar 21, 2020
1 parent 5dbb796 commit 867941d
Show file tree
Hide file tree
Showing 47 changed files with 449 additions and 203 deletions.
12 changes: 7 additions & 5 deletions .reek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ detectors:
exclude:
- Hash#slice
- initialize
- Sidekiq#self.use_options
- SidekiqUniqueJobs#use_config
- SidekiqUniqueJobs::BatchDelete#batch_delete
- SidekiqUniqueJobs::Changelog#entries
- SidekiqUniqueJobs::Changelog#page
Expand All @@ -110,24 +112,24 @@ detectors:
- SidekiqUniqueJobs::Digests#entries
- SidekiqUniqueJobs::Digests#page
- SidekiqUniqueJobs::Lock#lock
- SidekiqUniqueJobs::LockInfo#set
- SidekiqUniqueJobs::Lock::WhileExecuting#execute
- SidekiqUniqueJobs::LockArgs#filtered_args
- SidekiqUniqueJobs::LockInfo#set
- SidekiqUniqueJobs::Locksmith#enqueue
- SidekiqUniqueJobs::Locksmith#lock
- SidekiqUniqueJobs::Locksmith#lock_async
- SidekiqUniqueJobs::Locksmith#lock_sync
- SidekiqUniqueJobs::LockTTL#calculate
- SidekiqUniqueJobs::Logging::Middleware#logging_context
- SidekiqUniqueJobs::Middleware#call
- SidekiqUniqueJobs::Middleware#self.configure_server
- SidekiqUniqueJobs::Profiler#self.stop
- SidekiqUniqueJobs::Orphans::Manager#start
- SidekiqUniqueJobs::Orphans::Reaper#enqueued?
- SidekiqUniqueJobs::Orphans::Reaper#entries
- SidekiqUniqueJobs::SidekiqWorkerMethods#worker_class_constantize
- SidekiqUniqueJobs::Profiler#self.stop
- SidekiqUniqueJobs::Script::Caller#call_script
- SidekiqUniqueJobs::Script::Caller#extract_args
- SidekiqUniqueJobs::TimeCalculator#lock_ttl
- SidekiqUniqueJobs::UniqueArgs#filtered_args
- SidekiqUniqueJobs::SidekiqWorkerMethods#worker_class_constantize
- SidekiqUniqueJobs::UpgradeLocks#call
- SidekiqUniqueJobs::UpgradeLocks#upgrade_v6_lock
- SidekiqUniqueJobs::Web#self.registered
Expand Down
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ RSpec/FilePath:
Enabled: true
Exclude:
- spec/performance/locksmith_spec.rb
- spec/performance/unique_args_spec.rb
- spec/performance/lock_digest_spec.rb

RSpec/InstanceVariable:
Exclude:
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ platforms :mri do
gem "reek", ">= 5.3"
gem "rspec-benchmark"
gem "rubocop-mhenrixon"
gem "simplecov", "< 0.18"
gem "simplecov-material"
gem "simplecov-oj"
gem "travis"
Expand Down
1 change: 1 addition & 0 deletions gemfiles/sidekiq_4.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ platforms :mri do
gem "reek", ">= 5.3"
gem "rspec-benchmark"
gem "rubocop-mhenrixon"
gem "simplecov", "< 0.18"
gem "simplecov-material"
gem "simplecov-oj"
gem "travis"
Expand Down
1 change: 1 addition & 0 deletions gemfiles/sidekiq_4.1.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ platforms :mri do
gem "reek", ">= 5.3"
gem "rspec-benchmark"
gem "rubocop-mhenrixon"
gem "simplecov", "< 0.18"
gem "simplecov-material"
gem "simplecov-oj"
gem "travis"
Expand Down
1 change: 1 addition & 0 deletions gemfiles/sidekiq_4.2.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ platforms :mri do
gem "reek", ">= 5.3"
gem "rspec-benchmark"
gem "rubocop-mhenrixon"
gem "simplecov", "< 0.18"
gem "simplecov-material"
gem "simplecov-oj"
gem "travis"
Expand Down
1 change: 1 addition & 0 deletions gemfiles/sidekiq_5.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ platforms :mri do
gem "reek", ">= 5.3"
gem "rspec-benchmark"
gem "rubocop-mhenrixon"
gem "simplecov", "< 0.18"
gem "simplecov-material"
gem "simplecov-oj"
gem "travis"
Expand Down
1 change: 1 addition & 0 deletions gemfiles/sidekiq_5.1.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ platforms :mri do
gem "reek", ">= 5.3"
gem "rspec-benchmark"
gem "rubocop-mhenrixon"
gem "simplecov", "< 0.18"
gem "simplecov-material"
gem "simplecov-oj"
gem "travis"
Expand Down
1 change: 1 addition & 0 deletions gemfiles/sidekiq_5.2.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ platforms :mri do
gem "reek", ">= 5.3"
gem "rspec-benchmark"
gem "rubocop-mhenrixon"
gem "simplecov", "< 0.18"
gem "simplecov-material"
gem "simplecov-oj"
gem "travis"
Expand Down
1 change: 1 addition & 0 deletions gemfiles/sidekiq_6.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ platforms :mri do
gem "reek", ">= 5.3"
gem "rspec-benchmark"
gem "rubocop-mhenrixon"
gem "simplecov", "< 0.18"
gem "simplecov-material"
gem "simplecov-oj"
gem "travis"
Expand Down
1 change: 1 addition & 0 deletions gemfiles/sidekiq_develop.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ platforms :mri do
gem "reek", ">= 5.3"
gem "rspec-benchmark"
gem "rubocop-mhenrixon"
gem "simplecov", "< 0.18"
gem "simplecov-material"
gem "simplecov-oj"
gem "travis"
Expand Down
7 changes: 4 additions & 3 deletions lib/sidekiq_unique_jobs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@
require "sidekiq_unique_jobs/orphans/manager"
require "sidekiq_unique_jobs/cli"
require "sidekiq_unique_jobs/core_ext"
require "sidekiq_unique_jobs/time_calculator"
require "sidekiq_unique_jobs/unique_args"
require "sidekiq_unique_jobs/unique_digest"
require "sidekiq_unique_jobs/lock_timeout"
require "sidekiq_unique_jobs/lock_ttl"
require "sidekiq_unique_jobs/lock_args"
require "sidekiq_unique_jobs/lock_digest"
require "sidekiq_unique_jobs/unlockable"
require "sidekiq_unique_jobs/key"
require "sidekiq_unique_jobs/locksmith"
Expand Down
2 changes: 2 additions & 0 deletions lib/sidekiq_unique_jobs/batch_delete.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class BatchDelete
# @return [Integer] the default batch size
BATCH_SIZE = 100

#
# @return [Array<String>] Supported key suffixes
SUFFIXES = %w[
QUEUED
PRIMED
Expand Down
6 changes: 6 additions & 0 deletions lib/sidekiq_unique_jobs/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ module SidekiqUniqueJobs
# @author Mikael Henriksson <[email protected]>
#
class Cli < Thor
# :nodoc:
def self.banner(command, _namespace = nil, _subcommand = false)
"jobs #{@package_name} #{command.usage}" # rubocop:disable ThreadSafety/InstanceVariableInClassMethod
end

desc "list PATTERN", "list all unique digests and their expiry time"
option :count, aliases: :c, type: :numeric, default: 1000, desc: "The max number of digests to return"
# :nodoc:
def list(pattern = "*")
entries = digests.entries(pattern: pattern, count: options[:count])
say "Found #{entries.size} digests matching '#{pattern}':"
Expand All @@ -24,6 +26,7 @@ def list(pattern = "*")
desc "del PATTERN", "deletes unique digests from redis by pattern"
option :dry_run, aliases: :d, type: :boolean, desc: "set to false to perform deletion"
option :count, aliases: :c, type: :numeric, default: 1000, desc: "The max number of digests to return"
# :nodoc:
def del(pattern)
max_count = options[:count]
if options[:dry_run]
Expand All @@ -36,6 +39,7 @@ def del(pattern)
end

desc "console", "drop into a console with easy access to helper methods"
# :nodoc:
def console
say "Use `list '*', 1000 to display the first 1000 unique digests matching '*'"
say "Use `del '*', 1000, true (default) to see how many digests would be deleted for the pattern '*'"
Expand All @@ -46,10 +50,12 @@ def console
end

no_commands do
# :nodoc:
def digests
@digests ||= SidekiqUniqueJobs::Digests.new
end

# :nodoc:
def console_class
require "pry"
Pry
Expand Down
50 changes: 47 additions & 3 deletions lib/sidekiq_unique_jobs/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ module SidekiqUniqueJobs
#
# @author Mauro Berlanda <[email protected]>
class Config < ThreadSafeConfig
#
# @return [Hash<Symbol, SidekiqUniqueJobs::Lock::BaseLock] all available queued locks
LOCKS_WHILE_ENQUEUED = {
until_executing: SidekiqUniqueJobs::Lock::UntilExecuting,
while_enqueued: SidekiqUniqueJobs::Lock::UntilExecuting,
}.freeze

#
# @return [Hash<Symbol, SidekiqUniqueJobs::Lock::BaseLock] all available fulltime locks
LOCKS_FROM_PUSH_TO_PROCESSED = {
until_completed: SidekiqUniqueJobs::Lock::UntilExecuted,
until_executed: SidekiqUniqueJobs::Lock::UntilExecuted,
Expand All @@ -39,10 +43,14 @@ class Config < ThreadSafeConfig
until_successfully_completed: SidekiqUniqueJobs::Lock::UntilExecuted,
}.freeze

#
# @return [Hash<Symbol, SidekiqUniqueJobs::Lock::BaseLock] all available locks without unlock
LOCKS_WITHOUT_UNLOCK = {
until_expired: SidekiqUniqueJobs::Lock::UntilExpired,
}.freeze

#
# @return [Hash<Symbol, SidekiqUniqueJobs::Lock::BaseLock] all available runtime/client locks
LOCKS_WHEN_BUSY = {
around_perform: SidekiqUniqueJobs::Lock::WhileExecuting,
while_busy: SidekiqUniqueJobs::Lock::WhileExecuting,
Expand All @@ -51,13 +59,17 @@ class Config < ThreadSafeConfig
while_executing_reject: SidekiqUniqueJobs::Lock::WhileExecutingReject,
}.freeze

#
# @return [Hash<Symbol, SidekiqUniqueJobs::Lock::BaseLock] all available default locks
LOCKS =
LOCKS_WHEN_BUSY.dup
.merge(LOCKS_WHILE_ENQUEUED.dup)
.merge(LOCKS_WITHOUT_UNLOCK.dup)
.merge(LOCKS_FROM_PUSH_TO_PROCESSED.dup)
.freeze

#
# @return [Hash<Symbol, SidekiqUniqueJobs::OnConflict::Strategy] all available default strategies
STRATEGIES = {
log: SidekiqUniqueJobs::OnConflict::Log,
raise: SidekiqUniqueJobs::OnConflict::Raise,
Expand All @@ -66,18 +78,44 @@ class Config < ThreadSafeConfig
reschedule: SidekiqUniqueJobs::OnConflict::Reschedule,
}.freeze

#
# @return ['uniquejobs'] by default we use this prefix
PREFIX = "uniquejobs"
#
# @return [0] by default don't wait for locks
LOCK_TIMEOUT = 0
#
# @return [nil]
LOCK_TTL = nil
#
# @return [true] by default the gem is enabled
ENABLED = true
#
# @return [false] by default we don't debug the lua scripts because it is slow
DEBUG_LUA = false
#
# @return [1_000] use a changelog history of 1_000 entries by default
MAX_HISTORY = 1_000
REAPER = :ruby # The type of cleanup to run. Possible values are [:ruby, :lua]
#
# @return [:ruby] prefer the ruby reaper by default since the lua reaper still has problems
REAPER = :ruby
#
# @return [1_000] reap 1_000 orphaned locks at a time by default
REAPER_COUNT = 1_000
REAPER_INTERVAL = 600 # Every 10 minutes
REAPER_TIMEOUT = 10 # 10 seconds
#
# @return [600] reap locks every 10 minutes
REAPER_INTERVAL = 600
#
# @return [10] stop reaper after 10 seconds
REAPER_TIMEOUT = 10
#
# @return [false] while useful it also adds overhead so disable lock_info by default
USE_LOCK_INFO = false
#
# @return [false] by default we don't raise validation errors for workers
RAISE_ON_CONFIG_ERROR = false
#
# @return [0.0.0] default redis version is only to avoid NoMethodError on nil
REDIS_VERSION = "0.0.0"

#
Expand Down Expand Up @@ -185,6 +223,12 @@ def add_strategy(name, klass)
self.strategies = new_strategies
end

#
# The current version of redis
#
#
# @return [String] a version string eg. `5.0.1`
#
def redis_version
self.current_redis_version = SidekiqUniqueJobs.fetch_redis_version if current_redis_version == REDIS_VERSION
current_redis_version
Expand Down
2 changes: 1 addition & 1 deletion lib/sidekiq_unique_jobs/exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def initialize(lock_config)
#
# @author Mikael Henriksson <[email protected]>
class InvalidUniqueArguments < UniqueJobsError
def initialize(**options)
def initialize(options)
given = options[:given]
worker_class = options[:worker_class]
unique_args_method = options[:unique_args_method]
Expand Down
28 changes: 15 additions & 13 deletions lib/sidekiq_unique_jobs/job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,41 @@ module Job
extend self

# Adds timeout, expiration, unique_args, unique_prefix and unique_digest to the sidekiq job hash
# @return [void] nothing returned here matters
def add_uniqueness(item)
add_timeout_and_expiration(item)
# @return [Hash] the job hash
def prepare(item)
add_lock_timeout(item)
add_lock_ttl(item)
add_digest(item)
item
end

def prepare(item)
add_uniqueness(item)
item
end

# Adds unique_args, unique_prefix and unique_digest to the sidekiq job hash
# @return [Hash] the job hash
def add_digest(item)
add_unique_prefix(item)
add_unique_args(item)
add_unique_digest(item)

item
end

private

def add_timeout_and_expiration(item)
calculator = SidekiqUniqueJobs::TimeCalculator.new(item)
item[LOCK_TIMEOUT] = calculator.lock_timeout
item[LOCK_TTL] = calculator.lock_ttl
def add_lock_ttl(item)
item[LOCK_TTL] = SidekiqUniqueJobs::LockTTL.calculate(item)
end

def add_lock_timeout(item)
item[LOCK_TIMEOUT] = SidekiqUniqueJobs::LockTimeout.calculate(item)
end

def add_unique_args(item)
item[UNIQUE_ARGS] = SidekiqUniqueJobs::UniqueArgs.call(item)
item[UNIQUE_ARGS] = SidekiqUniqueJobs::LockArgs.call(item)
end

def add_unique_digest(item)
item[UNIQUE_DIGEST] = SidekiqUniqueJobs::UniqueDigest.call(item)
item[UNIQUE_DIGEST] = SidekiqUniqueJobs::LockDigest.call(item)
end

def add_unique_prefix(item)
Expand Down
6 changes: 3 additions & 3 deletions lib/sidekiq_unique_jobs/lock/base_lock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def initialize(item, callback, redis_pool = nil)
@callback = callback
@redis_pool = redis_pool
@attempt = 0
add_uniqueness_when_missing # Used to ease testing
prepare_item # Used to ease testing
@lock_config = LockConfig.new(item)
end

Expand Down Expand Up @@ -90,12 +90,12 @@ def locksmith

private

def add_uniqueness_when_missing
def prepare_item
return if item.key?(UNIQUE_DIGEST)

# The below should only be done to ease testing
# in production this will be done by the middleware
SidekiqUniqueJobs::Job.add_uniqueness(item)
SidekiqUniqueJobs::Job.prepare(item)
end

def call_strategy
Expand Down
Loading

0 comments on commit 867941d

Please sign in to comment.