From 7df2c38b6be34c4e1ec9a2ca423c8c2bf606d377 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 1 Feb 2019 22:24:52 +0100 Subject: [PATCH 01/23] Various upgrades - Tweak codeclimate - Change to double quotes - Adds changelog rake task/gem - Adds yard configuration --- .codeclimate.yml | 24 +- .csslintrc | 2 - .dockerignore | 4 - .eslintignore | 1 - .eslintrc | 213 ------------------ .gitignore | 2 - .mdlrc | 1 + .rspec | 3 +- .rubocop.yml | 85 ++++--- .rubocop_todo.yml | 67 ++++++ .travis.yml | 9 +- .yardopts | 8 +- Gemfile | 25 +- Guardfile | 29 --- Rakefile | 23 +- bin/bench | 10 +- bin/uniquejobs | 4 +- examples/custom_queue_job.rb | 2 +- .../custom_queue_job_with_filter_method.rb | 2 +- examples/custom_queue_job_with_filter_proc.rb | 4 +- examples/my_unique_job_with_filter_method.rb | 2 +- examples/my_unique_job_with_filter_proc.rb | 2 +- examples/unique_job_with_filter_method.rb | 2 +- lib/sidekiq-unique-jobs.rb | 2 +- lib/sidekiq_unique_jobs.rb | 69 +++--- lib/sidekiq_unique_jobs/cli.rb | 25 +- lib/sidekiq_unique_jobs/client/middleware.rb | 2 +- lib/sidekiq_unique_jobs/constants.rb | 45 ++-- lib/sidekiq_unique_jobs/digests.rb | 4 +- lib/sidekiq_unique_jobs/lock/base_lock.rb | 6 +- .../lock/until_executed.rb | 2 +- .../lock/while_executing.rb | 2 +- lib/sidekiq_unique_jobs/locksmith.rb | 8 +- lib/sidekiq_unique_jobs/logging.rb | 2 +- lib/sidekiq_unique_jobs/middleware.rb | 13 +- lib/sidekiq_unique_jobs/normalizer.rb | 2 +- lib/sidekiq_unique_jobs/on_conflict.rb | 19 +- lib/sidekiq_unique_jobs/on_conflict/raise.rb | 2 +- lib/sidekiq_unique_jobs/on_conflict/reject.rb | 6 +- .../on_conflict/strategy.rb | 2 +- .../options_with_fallback.rb | 2 +- lib/sidekiq_unique_jobs/scripts.rb | 10 +- lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb | 2 +- lib/sidekiq_unique_jobs/testing.rb | 6 +- lib/sidekiq_unique_jobs/timeout.rb | 2 +- lib/sidekiq_unique_jobs/unique_args.rb | 4 +- lib/sidekiq_unique_jobs/util.rb | 6 +- lib/sidekiq_unique_jobs/version.rb | 2 +- lib/sidekiq_unique_jobs/web.rb | 16 +- lib/sidekiq_unique_jobs/web/helpers.rb | 4 +- lib/tasks/changelog.rake | 18 ++ rails_example/Rakefile | 2 +- rails_example/bin/bundle | 4 +- rails_example/bin/check_or_setup_db | 24 +- rails_example/bin/rails | 6 +- rails_example/bin/rake | 4 +- rails_example/bin/setup | 16 +- rails_example/bin/update | 16 +- rails_example/spec/spec_helper.rb | 2 +- sidekiq-unique-jobs.gemspec | 36 ++- spec/examples/another_unique_job_spec.rb | 14 +- spec/examples/custom_queue_job_spec.rb | 10 +- ...ustom_queue_job_with_filter_method_spec.rb | 14 +- .../custom_queue_job_with_filter_proc_spec.rb | 16 +- spec/examples/expiring_job_spec.rb | 70 +++--- spec/examples/inline_worker_spec.rb | 14 +- spec/examples/just_a_worker_spec.rb | 14 +- spec/examples/long_running_job_spec.rb | 14 +- spec/examples/main_job_spec.rb | 16 +- spec/examples/my_job_spec.rb | 14 +- spec/examples/my_unique_job_spec.rb | 62 ++--- .../my_unique_job_with_filter_method_spec.rb | 24 +- .../my_unique_job_with_filter_proc_spec.rb | 22 +- spec/examples/notify_worker_spec.rb | 12 +- spec/examples/plain_class_spec.rb | 14 +- spec/examples/simple_worker_spec.rb | 22 +- spec/examples/spawn_simple_worker_spec.rb | 16 +- spec/examples/test_class_spec.rb | 8 +- .../unique_across_workers_job_spec.rb | 12 +- .../unique_job_on_conflict_raise_spec.rb | 16 +- .../unique_job_on_conflict_reject_spec.rb | 16 +- .../unique_job_on_conflict_reschedule_spec.rb | 16 +- .../unique_job_with_nil_unique_args_spec.rb | 22 +- ...que_job_with_no_unique_args_method_spec.rb | 16 +- ..._job_without_unique_args_parameter_spec.rb | 16 +- .../examples/unique_on_all_queues_job_spec.rb | 12 +- .../until_and_while_executing_job_spec.rb | 12 +- spec/examples/until_executed2_job_spec.rb | 16 +- spec/examples/until_executed_job_spec.rb | 18 +- spec/examples/until_executing_job_spec.rb | 12 +- spec/examples/until_expired_job_spec.rb | 16 +- .../examples/until_global_expired_job_spec.rb | 12 +- spec/examples/while_executing_job_spec.rb | 22 +- spec/examples/without_argument_job_spec.rb | 12 +- spec/integration/sidekiq/retry_set_spec.rb | 32 +-- .../client/middleware_spec.rb | 138 ++++++------ .../sidekiq_unique_jobs/legacy_lock_spec.rb | 74 +++--- .../lock/until_and_while_executing_spec.rb | 34 +-- .../lock/until_executed_spec.rb | 58 ++--- .../lock/until_executing_spec.rb | 56 ++--- .../lock/until_expired_spec.rb | 44 ++-- .../lock/while_executing_reject_spec.rb | 48 ++-- .../lock/while_executing_spec.rb | 40 ++-- .../sidekiq_unique_jobs/locksmith_spec.rb | 84 +++---- .../until_and_while_executing_spec.rb | 48 ++-- .../server/middleware_spec.rb | 30 +-- .../sidekiq_unique_jobs/web_spec.rb | 32 +-- spec/spec_helper.rb | 41 ++-- spec/support/matchers/redis_matchers.rb | 6 +- spec/support/retry.rb | 2 +- spec/support/ruby_meta.rb | 2 +- .../shared_examples/a_lockable_lock.rb | 32 +-- .../shared_examples/a_performing_worker.rb | 4 +- .../an_executing_lock_with_error_handling.rb | 8 +- .../shared_examples/sidekiq_with_options.rb | 2 +- .../with_a_stubbed_locksmith.rb | 2 +- spec/support/sidekiq_helpers.rb | 14 +- spec/support/sidekiq_meta.rb | 4 +- spec/support/version_check.rb | 4 +- spec/unit/sidekiq_unique_jobs/cli_spec.rb | 54 ++--- .../client/middleware_spec.rb | 24 +- .../unit/sidekiq_unique_jobs/core_ext_spec.rb | 22 +- spec/unit/sidekiq_unique_jobs/digests_spec.rb | 24 +- .../lock/base_lock_spec.rb | 66 +++--- .../lock/until_and_while_executing_spec.rb | 26 +-- .../lock/until_executed_spec.rb | 38 ++-- .../lock/until_executing_spec.rb | 14 +- .../lock/until_expired_spec.rb | 22 +- .../lock/while_executing_reject_spec.rb | 26 +-- .../lock/while_executing_spec.rb | 24 +- .../sidekiq_unique_jobs/middleware_spec.rb | 16 +- .../sidekiq_unique_jobs/normalizer_spec.rb | 8 +- .../on_conflict/log_spec.rb | 12 +- .../on_conflict/raise_spec.rb | 12 +- .../on_conflict/reject_spec.rb | 44 ++-- .../on_conflict/replace_spec.rb | 42 ++-- .../on_conflict/reschedule_spec.rb | 14 +- .../on_conflict/strategy_spec.rb | 16 +- .../sidekiq_unique_jobs/on_conflict_spec.rb | 4 +- .../options_with_fallback_spec.rb | 84 +++---- spec/unit/sidekiq_unique_jobs/scripts_spec.rb | 18 +- .../server/middleware_spec.rb | 20 +- .../sidekiq_unique_jobs/sidekiq/api_spec.rb | 92 ++++++++ .../sidekiq_unique_ext_spec.rb | 92 -------- .../sidekiq_worker_methods_spec.rb | 26 +-- .../timeout/calculator_spec.rb | 18 +- .../sidekiq_unique_jobs/unique_args_spec.rb | 105 ++++----- .../sidekiq_unique_jobs/unlockable_spec.rb | 12 +- spec/unit/sidekiq_unique_jobs/util_spec.rb | 72 +++--- spec/unit/sidekiq_unique_jobs_spec.rb | 38 ++-- 150 files changed, 1675 insertions(+), 1788 deletions(-) delete mode 100644 .csslintrc delete mode 100644 .dockerignore delete mode 100644 .eslintignore delete mode 100644 .eslintrc create mode 100644 .mdlrc create mode 100644 .rubocop_todo.yml create mode 100644 lib/tasks/changelog.rake create mode 100644 spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb delete mode 100644 spec/unit/sidekiq_unique_jobs/sidekiq_unique_ext_spec.rb diff --git a/.codeclimate.yml b/.codeclimate.yml index 0d4f28a2a..4962e39e3 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,17 +1,15 @@ --- version: '2' plugins: - bundler-audit: - enabled: false duplication: enabled: true config: languages: - ruby - flog: - enabled: true fixme: enabled: true + flog: + enabled: true markdownlint: enabled: true reek: @@ -20,16 +18,16 @@ plugins: file: .reek.yml rubocop: enabled: true - channel: rubocop-0-57 + channel: rubocop-0-63 config: file: .rubocop.yml + exclude_patterns: - - Gemfile + - "Gemfile" - "*.gemspec" - - Appraisals - - spec/**/*.rb - - gemfiles/**/* - - rails_example/**/* - - redis/**/* - - tmp/**/* - + - "Appraisals" + - "spec/**/*.rb" + - "gemfiles/**/*" + - "rails_example/**/*" + - "redis/**/*" + - "tmp/**/*" diff --git a/.csslintrc b/.csslintrc deleted file mode 100644 index aacba956e..000000000 --- a/.csslintrc +++ /dev/null @@ -1,2 +0,0 @@ ---exclude-exts=.min.css ---ignore=adjoining-classes,box-model,ids,order-alphabetical,unqualified-attributes diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 27f1d9cc0..000000000 --- a/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -.dockerignore -.byebug_history -log/* -tmp/* diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 96212a359..000000000 --- a/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -**/*{.,-}min.js diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 9faa37508..000000000 --- a/.eslintrc +++ /dev/null @@ -1,213 +0,0 @@ -ecmaFeatures: - modules: true - jsx: true - -env: - amd: true - browser: true - es6: true - jquery: true - node: true - -# http://eslint.org/docs/rules/ -rules: - # Possible Errors - comma-dangle: [2, never] - no-cond-assign: 2 - no-console: 0 - no-constant-condition: 2 - no-control-regex: 2 - no-debugger: 2 - no-dupe-args: 2 - no-dupe-keys: 2 - no-duplicate-case: 2 - no-empty: 2 - no-empty-character-class: 2 - no-ex-assign: 2 - no-extra-boolean-cast: 2 - no-extra-parens: 0 - no-extra-semi: 2 - no-func-assign: 2 - no-inner-declarations: [2, functions] - no-invalid-regexp: 2 - no-irregular-whitespace: 2 - no-negated-in-lhs: 2 - no-obj-calls: 2 - no-regex-spaces: 2 - no-sparse-arrays: 2 - no-unexpected-multiline: 2 - no-unreachable: 2 - use-isnan: 2 - valid-jsdoc: 0 - valid-typeof: 2 - - # Best Practices - accessor-pairs: 2 - block-scoped-var: 0 - complexity: [2, 6] - consistent-return: 0 - curly: 0 - default-case: 0 - dot-location: 0 - dot-notation: 0 - eqeqeq: 2 - guard-for-in: 2 - no-alert: 2 - no-caller: 2 - no-case-declarations: 2 - no-div-regex: 2 - no-else-return: 0 - no-empty-label: 2 - no-empty-pattern: 2 - no-eq-null: 2 - no-eval: 2 - no-extend-native: 2 - no-extra-bind: 2 - no-fallthrough: 2 - no-floating-decimal: 0 - no-implicit-coercion: 0 - no-implied-eval: 2 - no-invalid-this: 0 - no-iterator: 2 - no-labels: 0 - no-lone-blocks: 2 - no-loop-func: 2 - no-magic-number: 0 - no-multi-spaces: 0 - no-multi-str: 0 - no-native-reassign: 2 - no-new-func: 2 - no-new-wrappers: 2 - no-new: 2 - no-octal-escape: 2 - no-octal: 2 - no-proto: 2 - no-redeclare: 2 - no-return-assign: 2 - no-script-url: 2 - no-self-compare: 2 - no-sequences: 0 - no-throw-literal: 0 - no-unused-expressions: 2 - no-useless-call: 2 - no-useless-concat: 2 - no-void: 2 - no-warning-comments: 0 - no-with: 2 - radix: 2 - vars-on-top: 0 - wrap-iife: 2 - yoda: 0 - - # Strict - strict: 0 - - # Variables - init-declarations: 0 - no-catch-shadow: 2 - no-delete-var: 2 - no-label-var: 2 - no-shadow-restricted-names: 2 - no-shadow: 0 - no-undef-init: 2 - no-undef: 0 - no-undefined: 0 - no-unused-vars: 0 - no-use-before-define: 0 - - # Node.js and CommonJS - callback-return: 2 - global-require: 2 - handle-callback-err: 2 - no-mixed-requires: 0 - no-new-require: 0 - no-path-concat: 2 - no-process-exit: 2 - no-restricted-modules: 0 - no-sync: 0 - - # Stylistic Issues - array-bracket-spacing: 0 - block-spacing: 0 - brace-style: 0 - camelcase: 0 - comma-spacing: 0 - comma-style: 0 - computed-property-spacing: 0 - consistent-this: 0 - eol-last: 0 - func-names: 0 - func-style: 0 - id-length: 0 - id-match: 0 - indent: 0 - jsx-quotes: 0 - key-spacing: 0 - linebreak-style: 0 - lines-around-comment: 0 - max-depth: 0 - max-len: 0 - max-nested-callbacks: 0 - max-params: 0 - max-statements: [2, 30] - new-cap: 0 - new-parens: 0 - newline-after-var: 0 - no-array-constructor: 0 - no-bitwise: 0 - no-continue: 0 - no-inline-comments: 0 - no-lonely-if: 0 - no-mixed-spaces-and-tabs: 0 - no-multiple-empty-lines: 0 - no-negated-condition: 0 - no-nested-ternary: 0 - no-new-object: 0 - no-plusplus: 0 - no-restricted-syntax: 0 - no-spaced-func: 0 - no-ternary: 0 - no-trailing-spaces: 0 - no-underscore-dangle: 0 - no-unneeded-ternary: 0 - object-curly-spacing: 0 - one-var: 0 - operator-assignment: 0 - operator-linebreak: 0 - padded-blocks: 0 - quote-props: 0 - quotes: 0 - require-jsdoc: 0 - semi-spacing: 0 - semi: 0 - sort-vars: 0 - space-after-keywords: 0 - space-before-blocks: 0 - space-before-function-paren: 0 - space-before-keywords: 0 - space-in-parens: 0 - space-infix-ops: 0 - space-return-throw-case: 0 - space-unary-ops: 0 - spaced-comment: 0 - wrap-regex: 0 - - # ECMAScript 6 - arrow-body-style: 0 - arrow-parens: 0 - arrow-spacing: 0 - constructor-super: 0 - generator-star-spacing: 0 - no-arrow-condition: 0 - no-class-assign: 0 - no-const-assign: 0 - no-dupe-class-members: 0 - no-this-before-super: 0 - no-var: 0 - object-shorthand: 0 - prefer-arrow-callback: 0 - prefer-const: 0 - prefer-reflect: 0 - prefer-spread: 0 - prefer-template: 0 - require-yield: 0 diff --git a/.gitignore b/.gitignore index b88ffac75..4785f39cd 100644 --- a/.gitignore +++ b/.gitignore @@ -24,5 +24,3 @@ rails_example/spec/examples.txt /.byebug_history /.yardoc/ - -/spec/examples.txt diff --git a/.mdlrc b/.mdlrc new file mode 100644 index 000000000..b7e08259a --- /dev/null +++ b/.mdlrc @@ -0,0 +1 @@ +rules "~MD013" diff --git a/.rspec b/.rspec index 09127182c..34c5164d9 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,3 @@ +--format documentation --color ---order random +--require spec_helper diff --git a/.rubocop.yml b/.rubocop.yml index 7410c18fe..6a501a3fa 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,15 +1,24 @@ -require: rubocop-rspec +inherit_from: .rubocop_todo.yml + +require: + - rubocop-rspec + +inherit_mode: + merge: + - Exclude + AllCops: + TargetRubyVersion: 2.3 Include: - - '**/Rakefile' - - 'lib/**/*.rb' - - 'bin/**/*.rb' - - 'spec/**/*.rb' - - 'examples/**/*.rb' + - "**/Rakefile" + - "lib/**/*.rb" + - "bin/**/*.rb" + - "spec/**/*.rb" + - "examples/**/*.rb" Exclude: - - 'Gemfile.lock' - - 'gemfiles/**/*' - TargetRubyVersion: 2.3 + - "Gemfile.lock" + - "**/*.erb" + - "rails_example/**/*" Lint/HandleExceptions: Enabled: true @@ -32,7 +41,8 @@ Metrics/MethodLength: Metrics/BlockLength: Enabled: true Exclude: - - '**/spec/**/*.rb' + - "**/spec/**/*.rb" + - "**/*.rake" Metrics/PerceivedComplexity: Max: 8 @@ -46,64 +56,53 @@ Naming/ConstantName: Naming/FileName: Enabled: true Exclude: - - 'lib/sidekiq-unique-jobs.rb' - - '**/Gemfile' - - '**/Appraisals' - - '**/*.gemspec' + - "**/Gemfile" Naming/UncommunicativeMethodParamName: AllowedNames: - ex -RSpec/DescribeClass: - Enabled: false - -RSpec/ExampleLength: - Enabled: false - -RSpec/ExpectActual: - Enabled: false - -RSpec/ExpectChange: - Enabled: false - -RSpec/ExpectInHook: - Enabled: false - -RSpec/MessageSpies: - Enabled: false +RSpec/AlignLeftLetBrace: + Enabled: true -RSpec/MultipleExpectations: - Enabled: false +RSpec/FilePath: + Enabled: true + Exclude: + - "spec/stub_requests/webmock_builder_spec.rb" RSpec/NestedGroups: Max: 4 Enabled: true -RSpec/RepeatedExample: - Enabled: false - Style/FrozenStringLiteralComment: Enabled: true Style/Documentation: - Enabled: false - -Style/SignalException: - EnforcedStyle: only_fail - Enabled: false + Enabled: true + Exclude: + - "examples/**/*.rb" + - "rails_example/**/*.rb" + - "bin/**/*.rb" + - "lib/sidekiq_unique_jobs/testing.rb" + - "lib/sidekiq_unique_jobs/core_ext.rb" + - "lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb" + - "lib/sidekiq_unique_jobs/web/**/*" + - "lib/sidekiq_unique_jobs/on_conflict.rb" + - "lib/sidekiq_unique_jobs/timeout.rb" Style/GlobalVars: Enabled: true +Style/ModuleFunction: + Enabled: false + Style/StringLiterals: Enabled: true - EnforcedStyle: single_quotes + EnforcedStyle: double_quotes ConsistentQuotesInMultiline: true Style/StringLiteralsInInterpolation: Enabled: true - EnforcedStyle: single_quotes Style/SymbolArray: Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 000000000..a3a36467e --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,67 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2019-02-01 21:51:49 +0100 using RuboCop version 0.63.1. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 1 +# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms. +# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS +Naming/FileName: + Exclude: + - '**/Gemfile' + - 'lib/sidekiq-unique-jobs.rb' + +# Offense count: 2 +RSpec/DescribeClass: + Exclude: + - 'spec/unit/sidekiq_unique_jobs/core_ext_spec.rb' + +# Offense count: 43 +# Configuration parameters: Max. +RSpec/ExampleLength: + Enabled: false + +# Offense count: 29 +RSpec/ExpectActual: + Exclude: + - 'spec/routing/**/*' + - 'spec/examples/expiring_job_spec.rb' + - 'spec/examples/my_unique_job_spec.rb' + +# Offense count: 10 +RSpec/ExpectInHook: + Exclude: + - 'spec/integration/sidekiq/retry_set_spec.rb' + - 'spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb' + - 'spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb' + - 'spec/unit/sidekiq_unique_jobs/util_spec.rb' + +# Offense count: 27 +# Configuration parameters: EnforcedStyle. +# SupportedStyles: have_received, receive +RSpec/MessageSpies: + Exclude: + - 'spec/examples/spawn_simple_worker_spec.rb' + - 'spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb' + - 'spec/support/shared_examples/a_performing_worker.rb' + - 'spec/unit/sidekiq_unique_jobs/cli_spec.rb' + - 'spec/unit/sidekiq_unique_jobs/middleware_spec.rb' + - 'spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb' + - 'spec/unit/sidekiq_unique_jobs/scripts_spec.rb' + +# Offense count: 76 +# Configuration parameters: AggregateFailuresByDefault. +RSpec/MultipleExpectations: + Max: 9 + +# Offense count: 8 +RSpec/RepeatedExample: + Exclude: + - 'spec/unit/sidekiq_unique_jobs/unique_args_spec.rb' + +# Offense count: 56 +Style/Documentation: + Enabled: false diff --git a/.travis.yml b/.travis.yml index b05621720..b50fbeddc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,26 +12,33 @@ services: - redis-server before_install: + - gem install bundler -v 2.0.1 - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - chmod +x ./cc-test-reporter + before_script: - - ./cc-test-reporter before-build + - if [[ "${COV}" = "true" ]]; then ./cc-test-reporter before-build; fi; + script: - if [[ "${COV}" = "true" ]]; then bundle exec rubocop -P; fi; - bundle exec rspec + after_script: - if [[ "${COV}" = "true" ]]; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT; fi; + rvm: - 2.5.1 - 2.4.2 - 2.3.2 - jruby-9.2.0.0 + matrix: fast_finish: true include: - rvm: 2.5.1 gemfile: gemfiles/sidekiq_develop.gemfile env: COV=true + gemfile: - gemfiles/sidekiq_develop.gemfile - gemfiles/sidekiq_4.0.gemfile diff --git a/.yardopts b/.yardopts index f35bd1d7e..94fe4e4f2 100644 --- a/.yardopts +++ b/.yardopts @@ -1,7 +1 @@ - --no-private - --exclude lib/sidekiq_unique_jobs/testing.rb - --exclude lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb - --exclude lib/sidekiq_unique_jobs/middleware.rb - --exclude lib/sidekiq_unique_jobs/core_ext.rb - --exclude lib/sidekiq_unique_jobs/cli.rb - +--no-private --output-dir docs lib/stub_requests/**/*.rb --markup-provider=redcarpet --markup=markdown - README.md diff --git a/Gemfile b/Gemfile index 51306d8ab..cbe422e9e 100644 --- a/Gemfile +++ b/Gemfile @@ -9,16 +9,17 @@ gem 'rspec-retry', require: false gem 'rspec-eventually', require: false platforms :mri_25 do - gem 'benchmark-ips', require: false - gem 'fasterer', require: false - gem 'guard', require: false - gem 'guard-reek', require: false - gem 'guard-rspec', require: false - gem 'guard-rubocop', require: false - gem 'memory_profiler', require: false - gem 'pry-byebug', require: false - gem 'rubocop', require: false - gem 'rubocop-rspec', require: false - gem 'simplecov-json', require: false - gem 'travis', require: false + gem 'benchmark-ips' + gem 'fasterer' + gem 'guard' + gem 'guard-reek' + gem 'guard-rspec' + gem 'guard-rubocop' + gem 'memory_profiler' + gem 'reek', '>= 5.3', + gem 'pry' + gem 'rubocop' + gem 'rubocop-rspec' + gem 'simplecov-json' + gem 'rb-readline' end diff --git a/Guardfile b/Guardfile index b9b18024b..4dae91cad 100644 --- a/Guardfile +++ b/Guardfile @@ -1,35 +1,7 @@ -# A sample Guardfile -# More info at https://github.com/guard/guard#readme - -## Uncomment and set this to only include directories you want to watch -# directories %w(app lib config test spec features) \ -# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")} - -## Note: if you are using the `directories` clause above and you are not -## watching the project directory ('.'), then you will want to move -## the Guardfile to a watched dir and symlink it back, e.g. -# -# $ mkdir config -# $ mv Guardfile config/ -# $ ln -s config/Guardfile . -# -# and, you'll have to watch "config/Guardfile" instead of "Guardfile" - -# Note: The cmd option is now required due to the increasing number of ways -# rspec may be run, below are examples of the most common uses. -# * bundler: 'bundle exec rspec' -# * bundler binstubs: 'bin/rspec' -# * spring: 'bin/rspec' (This will use spring if running and you have -# installed the spring binstubs per the docs) -# * zeus: 'zeus rspec' (requires the server to be started separately) -# * 'just' rspec: 'rspec' - guard :rspec, cmd: "env COV=false bundle exec rspec" do require "guard/rspec/dsl" dsl = Guard::RSpec::Dsl.new(self) - # Feel free to open issues for suggestions and improvements - # RSpec files rspec = dsl.rspec watch(%r{^lib/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" } @@ -39,7 +11,6 @@ guard :rspec, cmd: "env COV=false bundle exec rspec" do watch(rspec.spec_support) { rspec.spec_dir } watch(rspec.spec_files) - # Ruby files ruby = dsl.ruby dsl.watch_spec_files_for(ruby.lib_files) end diff --git a/Rakefile b/Rakefile index 964485ca6..96cecfedc 100644 --- a/Rakefile +++ b/Rakefile @@ -1,12 +1,25 @@ # frozen_string_literal: true -require 'rubygems' -require 'bundler/setup' -require 'bundler/gem_tasks' -require 'rspec/core/rake_task' -require 'rubocop/rake_task' +require "bundler/gem_tasks" +require "rspec/core/rake_task" +require "rubocop/rake_task" + +Dir.glob("#{File.expand_path(__dir__)}/lib/tasks/**/*.rake").each { |f| import f } RuboCop::RakeTask.new(:style) RSpec::Core::RakeTask.new(:spec) +require "yard" +YARD::Rake::YardocTask.new do |t| + t.files = %w[lib/**/*.rb"] + t.options = %w[ + --no-private + --output-dir docs + --readme README.md + --output-dir docs + --markup=markdown + --markup-provider=redcarpet + ] +end + task default: [:style, :spec] diff --git a/bin/bench b/bin/bench index ea9aa44b9..d1086cc4e 100755 --- a/bin/bench +++ b/bin/bench @@ -3,17 +3,17 @@ # Trap interrupts to quit cleanly. See # https://twitter.com/mitchellh/status/283014103189053442 -Signal.trap('INT') { abort } +Signal.trap("INT") { abort } -require 'bundler/setup' -require 'benchmark/ips' -require 'sidekiq-unique-jobs' +require "bundler/setup" +require "benchmark/ips" +require "sidekiq-unique-jobs" ITERATIONS ||= 10_000 Benchmark.ips do |x| x.config(time: 5, warmup: 2) - x.report('new_shit') do |_times| + x.report("new_shit") do |_times| SidekiqUniqueJobs::Scripts::AcquireLock.execute(nil, SecureRandom.hex, SecureRandom.hex) end x.compare! diff --git a/bin/uniquejobs b/bin/uniquejobs index 1ac931250..923d479b8 100755 --- a/bin/uniquejobs +++ b/bin/uniquejobs @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # frozen_string_literal: true -require 'bundler/setup' -require 'sidekiq_unique_jobs' +require "bundler/setup" +require "sidekiq_unique_jobs" SidekiqUniqueJobs::Cli.start(ARGV) diff --git a/examples/custom_queue_job.rb b/examples/custom_queue_job.rb index 83bb07329..523769ae3 100644 --- a/examples/custom_queue_job.rb +++ b/examples/custom_queue_job.rb @@ -6,7 +6,7 @@ class CustomQueueJob include Sidekiq::Worker sidekiq_options queue: :customqueue - def perform(one, two = 'two') + def perform(one, two = "two") [one, two] end end diff --git a/examples/custom_queue_job_with_filter_method.rb b/examples/custom_queue_job_with_filter_method.rb index d7b9d0e13..ac8be5891 100644 --- a/examples/custom_queue_job_with_filter_method.rb +++ b/examples/custom_queue_job_with_filter_method.rb @@ -2,7 +2,7 @@ # :nocov: -require_relative 'custom_queue_job' +require_relative "custom_queue_job" class CustomQueueJobWithFilterMethod < CustomQueueJob sidekiq_options lock: :until_executed, unique_args: :args_filter diff --git a/examples/custom_queue_job_with_filter_proc.rb b/examples/custom_queue_job_with_filter_proc.rb index 01d13b761..34f6d3a02 100644 --- a/examples/custom_queue_job_with_filter_proc.rb +++ b/examples/custom_queue_job_with_filter_proc.rb @@ -2,7 +2,7 @@ # :nocov: -require_relative './custom_queue_job' +require_relative "./custom_queue_job" class CustomQueueJobWithFilterProc < CustomQueueJob # slightly contrived example of munging args to the @@ -10,7 +10,7 @@ class CustomQueueJobWithFilterProc < CustomQueueJob sidekiq_options lock: :until_expired, unique_args: (lambda do |args| options = args.extract_options! - options.delete('random') + options.delete("random") args + [options] end) end diff --git a/examples/my_unique_job_with_filter_method.rb b/examples/my_unique_job_with_filter_method.rb index 1822475d5..42a924f69 100644 --- a/examples/my_unique_job_with_filter_method.rb +++ b/examples/my_unique_job_with_filter_method.rb @@ -16,6 +16,6 @@ def perform(*) def self.filtered_args(args) options = args.extract_options! - [args.first, options['type']] + [args.first, options["type"]] end end diff --git a/examples/my_unique_job_with_filter_proc.rb b/examples/my_unique_job_with_filter_proc.rb index a424330ac..b1c653faa 100644 --- a/examples/my_unique_job_with_filter_proc.rb +++ b/examples/my_unique_job_with_filter_proc.rb @@ -10,7 +10,7 @@ class MyUniqueJobWithFilterProc retry: true, unique_args: (lambda do |args| options = args.extract_options! - [args.first, options['type']] + [args.first, options["type"]] end) def perform(*) diff --git a/examples/unique_job_with_filter_method.rb b/examples/unique_job_with_filter_method.rb index af2e8a16e..a94345d01 100644 --- a/examples/unique_job_with_filter_method.rb +++ b/examples/unique_job_with_filter_method.rb @@ -16,6 +16,6 @@ def perform(*) def self.filtered_args(args) options = args.extract_options! - [args.first, options['type']] + [args.first, options["type"]] end end diff --git a/lib/sidekiq-unique-jobs.rb b/lib/sidekiq-unique-jobs.rb index 65e6507b3..2ac110655 100644 --- a/lib/sidekiq-unique-jobs.rb +++ b/lib/sidekiq-unique-jobs.rb @@ -1,3 +1,3 @@ # frozen_string_literal: true -require 'sidekiq_unique_jobs' +require "sidekiq_unique_jobs" diff --git a/lib/sidekiq_unique_jobs.rb b/lib/sidekiq_unique_jobs.rb index 36cff1db2..b6f35d218 100644 --- a/lib/sidekiq_unique_jobs.rb +++ b/lib/sidekiq_unique_jobs.rb @@ -1,39 +1,38 @@ # frozen_string_literal: true -require 'yaml' if RUBY_VERSION.include?('2.0.0') -require 'forwardable' -require 'concurrent/mutable_struct' -require 'ostruct' +require "yaml" if RUBY_VERSION.include?("2.0.0") +require "forwardable" +require "concurrent/mutable_struct" +require "ostruct" -require 'sidekiq_unique_jobs/version' -require 'sidekiq_unique_jobs/constants' -require 'sidekiq_unique_jobs/logging' -require 'sidekiq_unique_jobs/sidekiq_worker_methods' -require 'sidekiq_unique_jobs/connection' -require 'sidekiq_unique_jobs/exceptions' -require 'sidekiq_unique_jobs/job' -require 'sidekiq_unique_jobs/util' -require 'sidekiq_unique_jobs/digests' -require 'sidekiq_unique_jobs/cli' -require 'sidekiq_unique_jobs/core_ext' -require 'sidekiq_unique_jobs/timeout' -require 'sidekiq_unique_jobs/scripts' -require 'sidekiq_unique_jobs/unique_args' -require 'sidekiq_unique_jobs/unlockable' -require 'sidekiq_unique_jobs/locksmith' -require 'sidekiq_unique_jobs/lock/base_lock' -require 'sidekiq_unique_jobs/lock/until_executed' -require 'sidekiq_unique_jobs/lock/until_executing' -require 'sidekiq_unique_jobs/lock/until_expired' -require 'sidekiq_unique_jobs/lock/while_executing' -require 'sidekiq_unique_jobs/lock/while_executing_reject' -require 'sidekiq_unique_jobs/lock/until_and_while_executing' -require 'sidekiq_unique_jobs/options_with_fallback' -require 'sidekiq_unique_jobs/middleware' -require 'sidekiq_unique_jobs/sidekiq_unique_ext' -require 'sidekiq_unique_jobs/on_conflict' +require "sidekiq_unique_jobs/version" +require "sidekiq_unique_jobs/constants" +require "sidekiq_unique_jobs/logging" +require "sidekiq_unique_jobs/sidekiq_worker_methods" +require "sidekiq_unique_jobs/connection" +require "sidekiq_unique_jobs/exceptions" +require "sidekiq_unique_jobs/job" +require "sidekiq_unique_jobs/util" +require "sidekiq_unique_jobs/digests" +require "sidekiq_unique_jobs/cli" +require "sidekiq_unique_jobs/core_ext" +require "sidekiq_unique_jobs/timeout" +require "sidekiq_unique_jobs/scripts" +require "sidekiq_unique_jobs/unique_args" +require "sidekiq_unique_jobs/unlockable" +require "sidekiq_unique_jobs/locksmith" +require "sidekiq_unique_jobs/lock/base_lock" +require "sidekiq_unique_jobs/lock/until_executed" +require "sidekiq_unique_jobs/lock/until_executing" +require "sidekiq_unique_jobs/lock/until_expired" +require "sidekiq_unique_jobs/lock/while_executing" +require "sidekiq_unique_jobs/lock/while_executing_reject" +require "sidekiq_unique_jobs/lock/until_and_while_executing" +require "sidekiq_unique_jobs/options_with_fallback" +require "sidekiq_unique_jobs/middleware" +require "sidekiq_unique_jobs/sidekiq_unique_ext" +require "sidekiq_unique_jobs/on_conflict" -# Namespace for this gem # # Contains configuration and utility methods that belongs top level # @@ -56,7 +55,7 @@ def config @config ||= Config.new( 0, true, - 'uniquejobs', + "uniquejobs", Sidekiq.logger, ) end @@ -76,7 +75,7 @@ def logger=(other) # Change global configuration while yielding # @yield control to the caller def use_config(tmp_config) - fail ::ArgumentError, "#{name}.#{__method__} needs a block" unless block_given? + raise ::ArgumentError, "#{name}.#{__method__} needs a block" unless block_given? old_config = config.to_h configure(tmp_config) @@ -104,6 +103,6 @@ def configure(options = {}) end def redis_version - @redis_version ||= redis { |conn| conn.info('server')['redis_version'] } + @redis_version ||= redis { |conn| conn.info("server")["redis_version"] } end end diff --git a/lib/sidekiq_unique_jobs/cli.rb b/lib/sidekiq_unique_jobs/cli.rb index f7a066aa2..8dc12fba3 100644 --- a/lib/sidekiq_unique_jobs/cli.rb +++ b/lib/sidekiq_unique_jobs/cli.rb @@ -1,24 +1,29 @@ # frozen_string_literal: true -require 'thor' +require "thor" module SidekiqUniqueJobs + # + # Command line interface for unique jobs + # + # @author Mikael Henriksson + # class Cli < Thor def self.banner(command, _namespace = nil, _subcommand = false) "jobs #{@package_name} #{command.usage}" end - desc 'keys PATTERN', 'list all unique keys and their expiry time' - option :count, aliases: :c, type: :numeric, default: 1000, desc: 'The max number of keys to return' - def keys(pattern = '*') + desc "keys PATTERN", "list all unique keys and their expiry time" + option :count, aliases: :c, type: :numeric, default: 1000, desc: "The max number of keys to return" + def keys(pattern = "*") keys = Util.keys(pattern, options[:count]) say "Found #{keys.size} keys matching '#{pattern}':" print_in_columns(keys.sort) if keys.any? end - desc 'del PATTERN', 'deletes unique keys 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 keys to return' + desc "del PATTERN", "deletes unique keys 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 keys to return" def del(pattern) max_count = options[:count] if options[:dry_run] @@ -30,7 +35,7 @@ def del(pattern) end end - desc 'console', 'drop into a console with easy access to helper methods' + desc "console", "drop into a console with easy access to helper methods" def console say "Use `keys '*', 1000 to display the first 1000 unique keys matching '*'" say "Use `del '*', 1000, true (default) to see how many keys would be deleted for the pattern '*'" @@ -41,10 +46,10 @@ def console no_commands do def console_class - require 'pry' + require "pry" Pry rescue LoadError - require 'irb' + require "irb" IRB end end diff --git a/lib/sidekiq_unique_jobs/client/middleware.rb b/lib/sidekiq_unique_jobs/client/middleware.rb index a6148b822..007a55a5d 100644 --- a/lib/sidekiq_unique_jobs/client/middleware.rb +++ b/lib/sidekiq_unique_jobs/client/middleware.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'sidekiq_unique_jobs/server/middleware' +require "sidekiq_unique_jobs/server/middleware" module SidekiqUniqueJobs module Client diff --git a/lib/sidekiq_unique_jobs/constants.rb b/lib/sidekiq_unique_jobs/constants.rb index effc7d572..c1d29c941 100644 --- a/lib/sidekiq_unique_jobs/constants.rb +++ b/lib/sidekiq_unique_jobs/constants.rb @@ -1,24 +1,29 @@ # frozen_string_literal: true +# +# Module with constants to avoid string duplication +# +# @author Mikael Henriksson +# module SidekiqUniqueJobs - ARGS_KEY ||= 'args' - AT_KEY ||= 'at' - CLASS_KEY ||= 'class' - JID_KEY ||= 'jid' - LOCK_EXPIRATION_KEY ||= 'lock_expiration' - LOCK_TIMEOUT_KEY ||= 'lock_timeout' - LOG_DUPLICATE_KEY ||= 'log_duplicate_payload' - QUEUE_KEY ||= 'queue' - UNIQUE_ACROSS_QUEUES_KEY ||= 'unique_across_queues' - UNIQUE_ACROSS_WORKERS_KEY ||= 'unique_across_workers' - UNIQUE_ARGS_KEY ||= 'unique_args' - UNIQUE_DIGEST_KEY ||= 'unique_digest' - UNIQUE_KEY ||= 'unique' - UNIQUE_SET ||= 'unique:keys' - LOCK_KEY ||= 'lock' - ON_CONFLICT_KEY ||= 'on_conflict' - UNIQUE_ON_ALL_QUEUES_KEY ||= 'unique_on_all_queues' # TODO: Remove in v6.1 - UNIQUE_PREFIX_KEY ||= 'unique_prefix' - RETRY_SET ||= 'retry' - SCHEDULE_SET ||= 'schedule' + ARGS_KEY ||= "args" + AT_KEY ||= "at" + CLASS_KEY ||= "class" + JID_KEY ||= "jid" + LOCK_EXPIRATION_KEY ||= "lock_expiration" + LOCK_TIMEOUT_KEY ||= "lock_timeout" + LOG_DUPLICATE_KEY ||= "log_duplicate_payload" + QUEUE_KEY ||= "queue" + UNIQUE_ACROSS_QUEUES_KEY ||= "unique_across_queues" + UNIQUE_ACROSS_WORKERS_KEY ||= "unique_across_workers" + UNIQUE_ARGS_KEY ||= "unique_args" + UNIQUE_DIGEST_KEY ||= "unique_digest" + UNIQUE_KEY ||= "unique" + UNIQUE_SET ||= "unique:keys" + LOCK_KEY ||= "lock" + ON_CONFLICT_KEY ||= "on_conflict" + UNIQUE_ON_ALL_QUEUES_KEY ||= "unique_on_all_queues" # TODO: Remove in v6.1 + UNIQUE_PREFIX_KEY ||= "unique_prefix" + RETRY_SET ||= "retry" + SCHEDULE_SET ||= "schedule" end diff --git a/lib/sidekiq_unique_jobs/digests.rb b/lib/sidekiq_unique_jobs/digests.rb index b4368ee56..d218d8e2e 100644 --- a/lib/sidekiq_unique_jobs/digests.rb +++ b/lib/sidekiq_unique_jobs/digests.rb @@ -6,7 +6,7 @@ module SidekiqUniqueJobs # @author Mikael Henriksson module Digests DEFAULT_COUNT = 1_000 - SCAN_PATTERN = '*' + SCAN_PATTERN = "*" CHUNK_SIZE = 100 include SidekiqUniqueJobs::Logging @@ -57,7 +57,7 @@ def del(digest: nil, pattern: nil, count: DEFAULT_COUNT) return delete_by_pattern(pattern, count: count) if pattern return delete_by_digest(digest) if digest - raise ArgumentError, 'either digest or pattern need to be provided' + raise ArgumentError, "either digest or pattern need to be provided" end private diff --git a/lib/sidekiq_unique_jobs/lock/base_lock.rb b/lib/sidekiq_unique_jobs/lock/base_lock.rb index 198af41a3..373ad185d 100644 --- a/lib/sidekiq_unique_jobs/lock/base_lock.rb +++ b/lib/sidekiq_unique_jobs/lock/base_lock.rb @@ -108,14 +108,14 @@ def locksmith def with_cleanup yield rescue Sidekiq::Shutdown - log_info('Sidekiq is shutting down, the job `should` be put back on the queue. Keeping the lock!') + log_info("Sidekiq is shutting down, the job `should` be put back on the queue. Keeping the lock!") raise else unlock_with_callback end def unlock_with_callback - return log_warn('might need to be unlocked manually') unless unlock + return log_warn("might need to be unlocked manually") unless unlock callback_safely item[JID_KEY] @@ -124,7 +124,7 @@ def unlock_with_callback def callback_safely callback&.call rescue StandardError - log_warn('unlocked successfully but the #after_unlock callback failed!') + log_warn("unlocked successfully but the #after_unlock callback failed!") raise end diff --git a/lib/sidekiq_unique_jobs/lock/until_executed.rb b/lib/sidekiq_unique_jobs/lock/until_executed.rb index 6780dc86b..3b5a172be 100644 --- a/lib/sidekiq_unique_jobs/lock/until_executed.rb +++ b/lib/sidekiq_unique_jobs/lock/until_executed.rb @@ -8,7 +8,7 @@ class Lock # # @author Mikael Henriksson class UntilExecuted < BaseLock - OK ||= 'OK' + OK ||= "OK" # Executes in the Sidekiq server process # @yield to the worker class perform method diff --git a/lib/sidekiq_unique_jobs/lock/while_executing.rb b/lib/sidekiq_unique_jobs/lock/while_executing.rb index 3f858fb07..9955253d6 100644 --- a/lib/sidekiq_unique_jobs/lock/while_executing.rb +++ b/lib/sidekiq_unique_jobs/lock/while_executing.rb @@ -11,7 +11,7 @@ class Lock # # @author Mikael Henriksson class WhileExecuting < BaseLock - RUN_SUFFIX ||= ':RUN' + RUN_SUFFIX ||= ":RUN" # @param [Hash] item the Sidekiq job hash # @param [Proc] callback callback to call after unlock diff --git a/lib/sidekiq_unique_jobs/locksmith.rb b/lib/sidekiq_unique_jobs/locksmith.rb index 597dc4a1d..76035d61e 100644 --- a/lib/sidekiq_unique_jobs/locksmith.rb +++ b/lib/sidekiq_unique_jobs/locksmith.rb @@ -133,19 +133,19 @@ def return_token_or_block_value(token) end def available_key - @available_key ||= namespaced_key('AVAILABLE') + @available_key ||= namespaced_key("AVAILABLE") end def exists_key - @exists_key ||= namespaced_key('EXISTS') + @exists_key ||= namespaced_key("EXISTS") end def grabbed_key - @grabbed_key ||= namespaced_key('GRABBED') + @grabbed_key ||= namespaced_key("GRABBED") end def version_key - @version_key ||= namespaced_key('VERSION') + @version_key ||= namespaced_key("VERSION") end def namespaced_key(variable) diff --git a/lib/sidekiq_unique_jobs/logging.rb b/lib/sidekiq_unique_jobs/logging.rb index c79da3c53..05a624369 100644 --- a/lib/sidekiq_unique_jobs/logging.rb +++ b/lib/sidekiq_unique_jobs/logging.rb @@ -51,7 +51,7 @@ def log_fatal(message_or_exception = nil, &block) end def logging_context(middleware_class, job_hash) - digest = job_hash['unique_digest'] + digest = job_hash["unique_digest"] "#{middleware_class} #{"DIG-#{digest}" if digest}" end end diff --git a/lib/sidekiq_unique_jobs/middleware.rb b/lib/sidekiq_unique_jobs/middleware.rb index 3e72aa4bf..9a512331f 100644 --- a/lib/sidekiq_unique_jobs/middleware.rb +++ b/lib/sidekiq_unique_jobs/middleware.rb @@ -1,8 +1,13 @@ # frozen_string_literal: true -require 'sidekiq' +require "sidekiq" module SidekiqUniqueJobs + # + # Provides the sidekiq middleware that makes the gem work + # + # @author Mikael Henriksson + # module Middleware def self.extended(base) base.class_eval do @@ -18,12 +23,12 @@ def configure_middleware def configure_server_middleware Sidekiq.configure_server do |config| config.client_middleware do |chain| - require 'sidekiq_unique_jobs/client/middleware' + require "sidekiq_unique_jobs/client/middleware" chain.add SidekiqUniqueJobs::Client::Middleware end config.server_middleware do |chain| - require 'sidekiq_unique_jobs/server/middleware' + require "sidekiq_unique_jobs/server/middleware" chain.add SidekiqUniqueJobs::Server::Middleware end end @@ -32,7 +37,7 @@ def configure_server_middleware def configure_client_middleware Sidekiq.configure_client do |config| config.client_middleware do |chain| - require 'sidekiq_unique_jobs/client/middleware' + require "sidekiq_unique_jobs/client/middleware" chain.add SidekiqUniqueJobs::Client::Middleware end end diff --git a/lib/sidekiq_unique_jobs/normalizer.rb b/lib/sidekiq_unique_jobs/normalizer.rb index d91f34159..1f3bcff64 100644 --- a/lib/sidekiq_unique_jobs/normalizer.rb +++ b/lib/sidekiq_unique_jobs/normalizer.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'json' +require "json" module SidekiqUniqueJobs # Normalizes hashes by dumping them to json and loading them from json diff --git a/lib/sidekiq_unique_jobs/on_conflict.rb b/lib/sidekiq_unique_jobs/on_conflict.rb index 7dd390a67..41f3376f7 100644 --- a/lib/sidekiq_unique_jobs/on_conflict.rb +++ b/lib/sidekiq_unique_jobs/on_conflict.rb @@ -1,14 +1,19 @@ # frozen_string_literal: true -require_relative 'on_conflict/strategy' -require_relative 'on_conflict/null_strategy' -require_relative 'on_conflict/log' -require_relative 'on_conflict/raise' -require_relative 'on_conflict/reject' -require_relative 'on_conflict/replace' -require_relative 'on_conflict/reschedule' +require_relative "on_conflict/strategy" +require_relative "on_conflict/null_strategy" +require_relative "on_conflict/log" +require_relative "on_conflict/raise" +require_relative "on_conflict/reject" +require_relative "on_conflict/replace" +require_relative "on_conflict/reschedule" module SidekiqUniqueJobs + # + # Provides lock conflict resolutions + # + # @author Mikael Henriksson + # module OnConflict STRATEGIES = { log: OnConflict::Log, diff --git a/lib/sidekiq_unique_jobs/on_conflict/raise.rb b/lib/sidekiq_unique_jobs/on_conflict/raise.rb index 549e6b24e..e4118328c 100644 --- a/lib/sidekiq_unique_jobs/on_conflict/raise.rb +++ b/lib/sidekiq_unique_jobs/on_conflict/raise.rb @@ -10,7 +10,7 @@ class Raise < OnConflict::Strategy # This will cause Sidekiq to retry the job # @raise [SidekiqUniqueJobs::Conflict] def call - fail SidekiqUniqueJobs::Conflict, item + raise SidekiqUniqueJobs::Conflict, item end end end diff --git a/lib/sidekiq_unique_jobs/on_conflict/reject.rb b/lib/sidekiq_unique_jobs/on_conflict/reject.rb index eca10e889..5386730f8 100644 --- a/lib/sidekiq_unique_jobs/on_conflict/reject.rb +++ b/lib/sidekiq_unique_jobs/on_conflict/reject.rb @@ -53,9 +53,9 @@ def deadset def push_to_deadset Sidekiq.redis do |conn| conn.multi do - conn.zadd('dead', current_time, payload) - conn.zremrangebyscore('dead', '-inf', current_time - Sidekiq::DeadSet.timeout) - conn.zremrangebyrank('dead', 0, -Sidekiq::DeadSet.max_jobs) + conn.zadd("dead", current_time, payload) + conn.zremrangebyscore("dead", "-inf", current_time - Sidekiq::DeadSet.timeout) + conn.zremrangebyrank("dead", 0, -Sidekiq::DeadSet.max_jobs) end end end diff --git a/lib/sidekiq_unique_jobs/on_conflict/strategy.rb b/lib/sidekiq_unique_jobs/on_conflict/strategy.rb index 54a0229e3..49761deca 100644 --- a/lib/sidekiq_unique_jobs/on_conflict/strategy.rb +++ b/lib/sidekiq_unique_jobs/on_conflict/strategy.rb @@ -21,7 +21,7 @@ def initialize(item) # Use strategy on conflict # @raise [NotImplementedError] needs to be implemented in child class def call - fail NotImplementedError, 'needs to be implemented in child class' + raise NotImplementedError, "needs to be implemented in child class" end def replace? diff --git a/lib/sidekiq_unique_jobs/options_with_fallback.rb b/lib/sidekiq_unique_jobs/options_with_fallback.rb index ce89de8f4..270f9ef36 100644 --- a/lib/sidekiq_unique_jobs/options_with_fallback.rb +++ b/lib/sidekiq_unique_jobs/options_with_fallback.rb @@ -50,7 +50,7 @@ def lock def lock_class @lock_class ||= begin LOCKS.fetch(lock_type.to_sym) do - fail UnknownLock, "No implementation for `lock: :#{lock_type}`" + raise UnknownLock, "No implementation for `lock: :#{lock_type}`" end end end diff --git a/lib/sidekiq_unique_jobs/scripts.rb b/lib/sidekiq_unique_jobs/scripts.rb index c6f2726e1..5a6002fef 100644 --- a/lib/sidekiq_unique_jobs/scripts.rb +++ b/lib/sidekiq_unique_jobs/scripts.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true -require 'pathname' -require 'digest/sha1' -require 'concurrent/map' +require "pathname" +require "digest/sha1" +require "concurrent/map" module SidekiqUniqueJobs # Interface to dealing with .lua files # # @author Mikael Henriksson module Scripts - LUA_PATHNAME ||= Pathname.new(__FILE__).dirname.join('../../redis').freeze + LUA_PATHNAME ||= Pathname.new(__FILE__).dirname.join("../../redis").freeze SCRIPT_SHAS ||= Concurrent::Map.new include SidekiqUniqueJobs::Connection @@ -64,7 +64,7 @@ def script_sha(conn, file_name) # @param [Symbol] file_name the name of the lua script # @raise [ScriptError] when the error isn't handled def handle_error(ex, file_name) - if ex.message == 'NOSCRIPT No matching script. Please use EVAL.' + if ex.message == "NOSCRIPT No matching script. Please use EVAL." SCRIPT_SHAS.delete(file_name) return yield if block_given? end diff --git a/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb b/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb index 47b575141..b0aea768a 100644 --- a/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb +++ b/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'sidekiq/api' +require "sidekiq/api" module Sidekiq class SortedEntry diff --git a/lib/sidekiq_unique_jobs/testing.rb b/lib/sidekiq_unique_jobs/testing.rb index 19e88bd4a..d90dd9f53 100644 --- a/lib/sidekiq_unique_jobs/testing.rb +++ b/lib/sidekiq_unique_jobs/testing.rb @@ -2,8 +2,8 @@ # :nocov: -require 'sidekiq' -require 'sidekiq/testing' +require "sidekiq" +require "sidekiq/testing" module Sidekiq def self.use_options(tmp_config = {}) @@ -52,7 +52,7 @@ class << self module Testing def clear_all_ext clear_all_orig - SidekiqUniqueJobs::Util.del('*', 1000) + SidekiqUniqueJobs::Util.del("*", 1000) end end end diff --git a/lib/sidekiq_unique_jobs/timeout.rb b/lib/sidekiq_unique_jobs/timeout.rb index af45d8b16..fc93e800b 100644 --- a/lib/sidekiq_unique_jobs/timeout.rb +++ b/lib/sidekiq_unique_jobs/timeout.rb @@ -5,4 +5,4 @@ module Timeout end end -require 'sidekiq_unique_jobs/timeout/calculator' +require "sidekiq_unique_jobs/timeout/calculator" diff --git a/lib/sidekiq_unique_jobs/unique_args.rb b/lib/sidekiq_unique_jobs/unique_args.rb index df7ca7f58..5ae9788a4 100644 --- a/lib/sidekiq_unique_jobs/unique_args.rb +++ b/lib/sidekiq_unique_jobs/unique_args.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'digest' -require 'sidekiq_unique_jobs/normalizer' +require "digest" +require "sidekiq_unique_jobs/normalizer" module SidekiqUniqueJobs # Handles uniqueness of sidekiq arguments diff --git a/lib/sidekiq_unique_jobs/util.rb b/lib/sidekiq_unique_jobs/util.rb index d718b2db0..83bc93178 100644 --- a/lib/sidekiq_unique_jobs/util.rb +++ b/lib/sidekiq_unique_jobs/util.rb @@ -7,7 +7,7 @@ module SidekiqUniqueJobs # @author Mikael Henriksson module Util DEFAULT_COUNT = 1_000 - SCAN_PATTERN = '*' + SCAN_PATTERN = "*" include SidekiqUniqueJobs::Logging include SidekiqUniqueJobs::Connection @@ -44,7 +44,7 @@ def keys_with_ttl(pattern = SCAN_PATTERN, count = DEFAULT_COUNT) # @param [Integer] count the maximum number of keys to delete # @return [Integer] the number of keys deleted def del(pattern = SCAN_PATTERN, count = 0) - raise ArgumentError, 'Please provide a number of keys to delete greater than zero' if count.zero? + raise ArgumentError, "Please provide a number of keys to delete greater than zero" if count.zero? pattern = suffix(pattern) @@ -91,7 +91,7 @@ def prefix(key) end def suffix(key) - return "#{key}*" unless key.end_with?(':*') + return "#{key}*" unless key.end_with?(":*") key end diff --git a/lib/sidekiq_unique_jobs/version.rb b/lib/sidekiq_unique_jobs/version.rb index 1d9f6aabc..b6acaa099 100644 --- a/lib/sidekiq_unique_jobs/version.rb +++ b/lib/sidekiq_unique_jobs/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module SidekiqUniqueJobs - VERSION = '6.0.8' + VERSION = "6.0.8" end diff --git a/lib/sidekiq_unique_jobs/web.rb b/lib/sidekiq_unique_jobs/web.rb index 2e363cb5a..d8c38928c 100644 --- a/lib/sidekiq_unique_jobs/web.rb +++ b/lib/sidekiq_unique_jobs/web.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true begin - require 'sidekiq/web' + require "sidekiq/web" rescue LoadError # rubocop:disable Lint/HandleExceptions # client-only usage end -require_relative 'web/helpers' +require_relative "web/helpers" module SidekiqUniqueJobs # Utility module to help manage unique keys in redis. @@ -19,9 +19,9 @@ def self.registered(app) # rubocop:disable Metrics/MethodLength include Web::Helpers end - app.get '/unique_digests' do - @filter = params[:filter] || '*' - @filter = '*' if @filter == '' + app.get "/unique_digests" do + @filter = params[:filter] || "*" + @filter = "*" if @filter == "" @count = (params[:count] || 100).to_i @current_cursor = params[:cursor] @prev_cursor = params[:prev_cursor] @@ -31,14 +31,14 @@ def self.registered(app) # rubocop:disable Metrics/MethodLength erb(unique_template(:unique_digests)) end - app.get '/unique_digests/:digest' do + app.get "/unique_digests/:digest" do @digest = params[:digest] @unique_keys = Util.keys("#{@digest}*", 1000) erb(unique_template(:unique_digest)) end - app.get '/unique_digests/:digest/delete' do + app.get "/unique_digests/:digest/delete" do Digests.del(digest: params[:digest]) redirect_to :unique_digests end @@ -48,6 +48,6 @@ def self.registered(app) # rubocop:disable Metrics/MethodLength if defined?(Sidekiq::Web) Sidekiq::Web.register SidekiqUniqueJobs::Web - Sidekiq::Web.tabs['Unique Digests'] = 'unique_digests' + Sidekiq::Web.tabs["Unique Digests"] = "unique_digests" # Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), 'locales') end diff --git a/lib/sidekiq_unique_jobs/web/helpers.rb b/lib/sidekiq_unique_jobs/web/helpers.rb index ddda54d74..5e9f068c3 100644 --- a/lib/sidekiq_unique_jobs/web/helpers.rb +++ b/lib/sidekiq_unique_jobs/web/helpers.rb @@ -3,7 +3,7 @@ module SidekiqUniqueJobs module Web module Helpers - VIEW_PATH = File.expand_path('../web/views', __dir__) + VIEW_PATH = File.expand_path("../web/views", __dir__) def unique_template(name) File.open(File.join(VIEW_PATH, "#{name}.erb")).read @@ -21,7 +21,7 @@ def cparams(options) next unless SAFE_CPARAMS.include?(key) "#{key}=#{CGI.escape(value.to_s)}" - end.compact.join('&') + end.compact.join("&") end def redirect_to(subpath) diff --git a/lib/tasks/changelog.rake b/lib/tasks/changelog.rake new file mode 100644 index 000000000..e5f21b930 --- /dev/null +++ b/lib/tasks/changelog.rake @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +desc "Generate a Changelog" +task :changelog do + # rubocop:disable Style/MutableConstant + CHANGELOG_COMMAND ||= %w[ + github_changelog_generator + -u + mhenrixon + -p + stub_requests + --no-verbose + --token + ] + # rubocop:enable Style/MutableConstant + + sh(*CHANGELOG_COMMAND.push(ENV["CHANGELOG_GITHUB_TOKEN"])) +end diff --git a/rails_example/Rakefile b/rails_example/Rakefile index e51cf0e17..dbf84da93 100644 --- a/rails_example/Rakefile +++ b/rails_example/Rakefile @@ -3,6 +3,6 @@ # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. -require File.expand_path('config/application', __dir__) +require File.expand_path("config/application", __dir__) Rails.application.load_tasks diff --git a/rails_example/bin/bundle b/rails_example/bin/bundle index 2dbb71769..5015ba6f8 100755 --- a/rails_example/bin/bundle +++ b/rails_example/bin/bundle @@ -1,5 +1,5 @@ #!/usr/bin/env ruby # frozen_string_literal: true -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) -load Gem.bin_path('bundler', 'bundle') +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) +load Gem.bin_path("bundler", "bundle") diff --git a/rails_example/bin/check_or_setup_db b/rails_example/bin/check_or_setup_db index 22810cb9b..00eb2b5c5 100755 --- a/rails_example/bin/check_or_setup_db +++ b/rails_example/bin/check_or_setup_db @@ -8,14 +8,14 @@ # We are using this custom script instead of running the # `rake db:version || rake db:setup` commands, as that currently leaves a # couple of small ruby zombie processes running in the app container: -require 'rubygems' -require 'rake' -require 'bundler' +require "rubygems" +require "rake" +require "bundler" Bundler.setup(:default) -require 'active_record' -require 'pg' +require "active_record" +require "pg" exit begin connection_tries ||= 3 @@ -24,21 +24,21 @@ exit begin rescue PG::ConnectionBad unless (connection_tries -= 1).zero? puts "Retrying DB connection #{connection_tries} more times..." - sleep ENV.fetch('APP_SETUP_WAIT', '5').to_i + sleep ENV.fetch("APP_SETUP_WAIT", "5").to_i retry end 1 rescue ActiveRecord::NoDatabaseError, ActiveRecord::AdapterNotSpecified include ActiveRecord::Tasks # rubocop:disable Style/MixinUsage - DatabaseTasks.root = File.expand_path '..', __dir__ - DatabaseTasks.db_dir = File.join DatabaseTasks.root, 'db' - DatabaseTasks.env = ENV.fetch 'ENV', ENV.fetch('RAILS_ENV', 'development') + DatabaseTasks.root = File.expand_path "..", __dir__ + DatabaseTasks.db_dir = File.join DatabaseTasks.root, "db" + DatabaseTasks.env = ENV.fetch "ENV", ENV.fetch("RAILS_ENV", "development") # The App database seeder: DatabaseTasks.seed_loader = (Class.new do def load_seed - seed_file_path = File.join DatabaseTasks.db_dir, 'seeds.rb' + seed_file_path = File.join DatabaseTasks.db_dir, "seeds.rb" raise "Seed file '#{seed_file_path}' does not exist" unless File.file?(seed_file_path) load seed_file_path @@ -46,8 +46,8 @@ exit begin end).new # Add model dirs to the autoload_paths for the seeder to run smoothly: - ActiveSupport::Dependencies.autoload_paths << File.join(DatabaseTasks.root, 'app', 'models', 'concerns') - ActiveSupport::Dependencies.autoload_paths << File.join(DatabaseTasks.root, 'app', 'models') + ActiveSupport::Dependencies.autoload_paths << File.join(DatabaseTasks.root, "app", "models", "concerns") + ActiveSupport::Dependencies.autoload_paths << File.join(DatabaseTasks.root, "app", "models") return 2 unless DatabaseTasks.create_current return 3 unless DatabaseTasks.load_schema_current diff --git a/rails_example/bin/rails b/rails_example/bin/rails index a31728ab9..22f2d8dee 100755 --- a/rails_example/bin/rails +++ b/rails_example/bin/rails @@ -1,6 +1,6 @@ #!/usr/bin/env ruby # frozen_string_literal: true -APP_PATH = File.expand_path('../config/application', __dir__) -require_relative '../config/boot' -require 'rails/commands' +APP_PATH = File.expand_path("../config/application", __dir__) +require_relative "../config/boot" +require "rails/commands" diff --git a/rails_example/bin/rake b/rails_example/bin/rake index c19995500..e436ea54a 100755 --- a/rails_example/bin/rake +++ b/rails_example/bin/rake @@ -1,6 +1,6 @@ #!/usr/bin/env ruby # frozen_string_literal: true -require_relative '../config/boot' -require 'rake' +require_relative "../config/boot" +require "rake" Rake.application.run diff --git a/rails_example/bin/setup b/rails_example/bin/setup index fdb13c5ce..78380f59a 100755 --- a/rails_example/bin/setup +++ b/rails_example/bin/setup @@ -1,11 +1,11 @@ #!/usr/bin/env ruby # frozen_string_literal: true -require 'fileutils' +require "fileutils" include FileUtils # rubocop:disable Style/MixinUsage # path to your application root. -APP_ROOT = File.expand_path('..', __dir__) +APP_ROOT = File.expand_path("..", __dir__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") @@ -15,9 +15,9 @@ chdir APP_ROOT do # This script is a starting point to setup your application. # Add necessary setup steps to this file. - puts '== Installing dependencies ==' - system! 'gem install bundler --conservative' - system('bundle check') || system!('bundle install') + puts "== Installing dependencies ==" + system! "gem install bundler --conservative" + system("bundle check") || system!("bundle install") # Install JavaScript dependencies if using Yarn # system('bin/yarn') @@ -28,11 +28,11 @@ chdir APP_ROOT do # end puts "\n== Preparing database ==" - system! 'bin/rails db:setup' + system! "bin/rails db:setup" puts "\n== Removing old logs and tempfiles ==" - system! 'bin/rails log:clear tmp:clear' + system! "bin/rails log:clear tmp:clear" puts "\n== Restarting application server ==" - system! 'bin/rails restart' + system! "bin/rails restart" end diff --git a/rails_example/bin/update b/rails_example/bin/update index 73dd1c3f7..88bc67c03 100755 --- a/rails_example/bin/update +++ b/rails_example/bin/update @@ -1,11 +1,11 @@ #!/usr/bin/env ruby # frozen_string_literal: true -require 'fileutils' +require "fileutils" include FileUtils # rubocop:disable Style/MixinUsage # path to your application root. -APP_ROOT = File.expand_path('..', __dir__) +APP_ROOT = File.expand_path("..", __dir__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") @@ -15,19 +15,19 @@ chdir APP_ROOT do # This script is a way to update your development environment automatically. # Add necessary update steps to this file. - puts '== Installing dependencies ==' - system! 'gem install bundler --conservative' - system('bundle check') || system!('bundle install') + puts "== Installing dependencies ==" + system! "gem install bundler --conservative" + system("bundle check") || system!("bundle install") # Install JavaScript dependencies if using Yarn # system('bin/yarn') puts "\n== Updating database ==" - system! 'bin/rails db:migrate' + system! "bin/rails db:migrate" puts "\n== Removing old logs and tempfiles ==" - system! 'bin/rails log:clear tmp:clear' + system! "bin/rails log:clear tmp:clear" puts "\n== Restarting application server ==" - system! 'bin/rails restart' + system! "bin/rails restart" end diff --git a/rails_example/spec/spec_helper.rb b/rails_example/spec/spec_helper.rb index d6befd16a..0cefc7bb1 100644 --- a/rails_example/spec/spec_helper.rb +++ b/rails_example/spec/spec_helper.rb @@ -15,7 +15,7 @@ config.shared_context_metadata_behavior = :apply_to_host_groups config.filter_run_when_matching :focus - config.example_status_persistence_file_path = 'spec/examples.txt' + config.example_status_persistence_file_path = ".rspec_status" # config.disable_monkey_patching! config.default_formatter = 'doc' if config.files_to_run.one? diff --git a/sidekiq-unique-jobs.gemspec b/sidekiq-unique-jobs.gemspec index 3cf57eb28..9dd551769 100644 --- a/sidekiq-unique-jobs.gemspec +++ b/sidekiq-unique-jobs.gemspec @@ -11,11 +11,20 @@ Gem::Specification.new do |spec| spec.authors = ['Mikael Henriksson'] spec.email = ['mikael@zoolutions.se'] - spec.summary = 'Uniqueness for Sidekiq Jobs' - spec.description = 'Handles various types of unique jobs for Sidekiq' - spec.homepage = 'https://github.com/mhenrixon/sidekiq-unique-jobs' + spec.summary = 'Prevent duplicate jobs in Sidekiq' + spec.description = 'An attempt to prevent simultaneous Sidekiq jobs with the same unique arguments to run' + spec.homepage = 'https://mhenrixon.github.com/sidekiq-unique-jobs' spec.license = 'MIT' + if spec.respond_to?(:metadata) + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = "https://github.com/mhenrixon/stub_requests" + spec.metadata["changelog_uri"] = "https://github.com/mhenrixon/stub_requests/CHANGELOG.md" + else + raise "RubyGems 2.0 or newer is required to protect against " \ + "public gem pushes." + end + spec.bindir = 'bin' spec.executables = %w[uniquejobs] @@ -30,13 +39,22 @@ Gem::Specification.new do |spec| spec.add_dependency 'sidekiq', '>= 4.0', '< 6.0' spec.add_dependency 'thor', '~> 0' - spec.add_development_dependency 'bundler', '>= 1.16' - spec.add_development_dependency 'rspec', '~> 3.7' - spec.add_development_dependency 'rake', '~> 12.3' + spec.add_development_dependency 'bundler', '>= 2.0' + spec.add_development_dependency 'rspec', '~> 3.7' + spec.add_development_dependency 'rake', '~> 12.3' spec.add_development_dependency 'timecop', '~> 0.9' - spec.add_development_dependency 'yard', '~> 0.9' - spec.add_development_dependency 'gem-release', '~> 1.0' - spec.add_development_dependency 'awesome_print', '~> 1.8' spec.add_development_dependency 'rack-test' spec.add_development_dependency 'sinatra' + + # ===== Utilities ===== + spec.add_development_dependency "travis", ">= 1.8.9" + + # ===== Documentation ===== + spec.add_development_dependency "yard", "~> 0.9.18" + spec.add_development_dependency "redcarpet", "~> 3.4" + spec.add_development_dependency "github-markup", "~> 3.0" + spec.add_development_dependency "github_changelog_generator", "~> 1.14" + + # ===== Release Management ===== + spec.add_development_dependency "gem-release", ">= 2.0" end diff --git a/spec/examples/another_unique_job_spec.rb b/spec/examples/another_unique_job_spec.rb index 44f6940b0..527daddc3 100644 --- a/spec/examples/another_unique_job_spec.rb +++ b/spec/examples/another_unique_job_spec.rb @@ -1,20 +1,20 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe AnotherUniqueJob, redis: :redis do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :working2, - 'retry' => 1, - 'backtrace' => 10, - 'lock' => :until_executed, + "queue" => :working2, + "retry" => 1, + "backtrace" => 10, + "lock" => :until_executed, } end end - it_behaves_like 'a performing worker', splat_arguments: false do + it_behaves_like "a performing worker", splat_arguments: false do let(:args) { %w[one two] } end end diff --git a/spec/examples/custom_queue_job_spec.rb b/spec/examples/custom_queue_job_spec.rb index 8fabd1427..c260f4126 100644 --- a/spec/examples/custom_queue_job_spec.rb +++ b/spec/examples/custom_queue_job_spec.rb @@ -1,18 +1,18 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe CustomQueueJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :customqueue, - 'retry' => true, + "queue" => :customqueue, + "retry" => true, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { %w[one two] } end end diff --git a/spec/examples/custom_queue_job_with_filter_method_spec.rb b/spec/examples/custom_queue_job_with_filter_method_spec.rb index 981000dd8..662490af7 100644 --- a/spec/examples/custom_queue_job_with_filter_method_spec.rb +++ b/spec/examples/custom_queue_job_with_filter_method_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe CustomQueueJobWithFilterMethod do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :customqueue, - 'retry' => true, - 'lock' => :until_executed, - 'unique_args' => :args_filter, + "queue" => :customqueue, + "retry" => true, + "lock" => :until_executed, + "unique_args" => :args_filter, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { %w[one two] } end end diff --git a/spec/examples/custom_queue_job_with_filter_proc_spec.rb b/spec/examples/custom_queue_job_with_filter_proc_spec.rb index be664a954..c5bb40942 100644 --- a/spec/examples/custom_queue_job_with_filter_proc_spec.rb +++ b/spec/examples/custom_queue_job_with_filter_proc_spec.rb @@ -1,20 +1,20 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe CustomQueueJobWithFilterProc do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :customqueue, - 'retry' => true, - 'lock' => :until_expired, - 'unique_args' => a_kind_of(Proc), + "queue" => :customqueue, + "retry" => true, + "lock" => :until_expired, + "unique_args" => a_kind_of(Proc), } end end - it_behaves_like 'a performing worker' do - let(:args) { [1, 'random' => rand, 'name' => 'foobar'] } + it_behaves_like "a performing worker" do + let(:args) { [1, "random" => rand, "name" => "foobar"] } end end diff --git a/spec/examples/expiring_job_spec.rb b/spec/examples/expiring_job_spec.rb index 1d71150a9..769f0ad30 100644 --- a/spec/examples/expiring_job_spec.rb +++ b/spec/examples/expiring_job_spec.rb @@ -1,85 +1,85 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe ExpiringJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'lock_expiration' => 600, - 'retry' => true, - 'lock' => :until_executed, + "lock_expiration" => 600, + "retry" => true, + "lock" => :until_executed, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { [1, 2] } end - describe 'client middleware' do - context 'when job is delayed' do + describe "client middleware" do + context "when job is delayed" do before { described_class.perform_in(60, 1, 2) } - it 'rejects new scheduled jobs' do - expect(1).to be_enqueued_in('customqueue') + it "rejects new scheduled jobs" do + expect(1).to be_enqueued_in("customqueue") described_class.perform_in(3600, 1, 2) - expect(1).to be_enqueued_in('customqueue') + expect(1).to be_enqueued_in("customqueue") expect(1).to be_scheduled_at(Time.now.to_f + 2 * 60) end - it 'rejects new jobs' do + it "rejects new jobs" do described_class.perform_async(1, 2) - expect(1).to be_enqueued_in('customqueue') + expect(1).to be_enqueued_in("customqueue") end - it 'allows duplicate messages to different queues' do - expect(1).to be_enqueued_in('customqueue2') - with_sidekiq_options_for(described_class, queue: 'customqueue2') do + it "allows duplicate messages to different queues" do + expect(1).to be_enqueued_in("customqueue2") + with_sidekiq_options_for(described_class, queue: "customqueue2") do described_class.perform_async(1, 2) - expect(1).to be_enqueued_in('customqueue2') + expect(1).to be_enqueued_in("customqueue2") end end - it 'sets keys to expire as per configuration' do - lock_expiration = described_class.get_sidekiq_options['lock_expiration'] + it "sets keys to expire as per configuration" do + lock_expiration = described_class.get_sidekiq_options["lock_expiration"] unique_keys.each do |key| - next if key.end_with?(':GRABBED') + next if key.end_with?(":GRABBED") expect(ttl(key)).to be_within(1).of(lock_expiration + 60) end end end - context 'when job is pushed' do + context "when job is pushed" do before { described_class.perform_async(1, 2) } - it 'rejects new scheduled jobs' do - expect(1).to be_enqueued_in('customqueue') + it "rejects new scheduled jobs" do + expect(1).to be_enqueued_in("customqueue") described_class.perform_in(60, 1, 2) - expect(1).to be_enqueued_in('customqueue') + expect(1).to be_enqueued_in("customqueue") expect(0).to be_scheduled_at(Time.now.to_f + 2 * 60) end - it 'rejects new jobs' do - expect(1).to be_enqueued_in('customqueue') + it "rejects new jobs" do + expect(1).to be_enqueued_in("customqueue") described_class.perform_async(1, 2) - expect(1).to be_enqueued_in('customqueue') + expect(1).to be_enqueued_in("customqueue") end - it 'allows duplicate messages to different queues' do - expect(1).to be_enqueued_in('customqueue') - expect(0).to be_enqueued_in('customqueue2') - with_sidekiq_options_for(described_class, queue: 'customqueue2') do + it "allows duplicate messages to different queues" do + expect(1).to be_enqueued_in("customqueue") + expect(0).to be_enqueued_in("customqueue2") + with_sidekiq_options_for(described_class, queue: "customqueue2") do described_class.perform_async(1, 2) - expect(1).to be_enqueued_in('customqueue2') + expect(1).to be_enqueued_in("customqueue2") end end - it 'sets keys to expire as per configuration' do - lock_expiration = described_class.get_sidekiq_options['lock_expiration'] + it "sets keys to expire as per configuration" do + lock_expiration = described_class.get_sidekiq_options["lock_expiration"] unique_keys.each do |key| - next if key.end_with?(':GRABBED') + next if key.end_with?(":GRABBED") expect(ttl(key)).to be_within(1).of(lock_expiration) end diff --git a/spec/examples/inline_worker_spec.rb b/spec/examples/inline_worker_spec.rb index b3b949c8c..e228b1d5d 100644 --- a/spec/examples/inline_worker_spec.rb +++ b/spec/examples/inline_worker_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe InlineWorker do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'lock_timeout' => 5, - 'retry' => true, - 'lock' => :while_executing, + "lock_timeout" => 5, + "retry" => true, + "lock" => :while_executing, } end end - it_behaves_like 'a performing worker' do - let(:args) { 'one' } + it_behaves_like "a performing worker" do + let(:args) { "one" } end end diff --git a/spec/examples/just_a_worker_spec.rb b/spec/examples/just_a_worker_spec.rb index e642cc85e..2cb00a25f 100644 --- a/spec/examples/just_a_worker_spec.rb +++ b/spec/examples/just_a_worker_spec.rb @@ -1,18 +1,18 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe JustAWorker do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :testqueue, - 'retry' => true, - 'lock' => :until_executed, + "queue" => :testqueue, + "retry" => true, + "lock" => :until_executed, } end end - it_behaves_like 'a performing worker' do - let(:args) { { 'test' => 1 } } + it_behaves_like "a performing worker" do + let(:args) { { "test" => 1 } } end end diff --git a/spec/examples/long_running_job_spec.rb b/spec/examples/long_running_job_spec.rb index 95d835d90..145bbd00d 100644 --- a/spec/examples/long_running_job_spec.rb +++ b/spec/examples/long_running_job_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe LongRunningJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :customqueue, - 'retry' => 10, - 'lock' => :until_and_while_executing, - 'lock_expiration' => 7_200, + "queue" => :customqueue, + "retry" => 10, + "lock" => :until_and_while_executing, + "lock_expiration" => 7_200, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { %w[one two] } end end diff --git a/spec/examples/main_job_spec.rb b/spec/examples/main_job_spec.rb index 26190e91c..415ad88eb 100644 --- a/spec/examples/main_job_spec.rb +++ b/spec/examples/main_job_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe MainJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'log_duplicate_payload' => true, - 'queue' => :customqueue, - 'retry' => true, - 'lock' => :until_executed, + "log_duplicate_payload" => true, + "queue" => :customqueue, + "retry" => true, + "lock" => :until_executed, } end end - it_behaves_like 'a performing worker' do - let(:args) { 'one' } + it_behaves_like "a performing worker" do + let(:args) { "one" } end end diff --git a/spec/examples/my_job_spec.rb b/spec/examples/my_job_spec.rb index 50a9609ba..737977423 100644 --- a/spec/examples/my_job_spec.rb +++ b/spec/examples/my_job_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe MyJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'backtrace' => 10, - 'queue' => :working, - 'retry' => 1, + "backtrace" => 10, + "queue" => :working, + "retry" => 1, } end end - it_behaves_like 'a performing worker' do - let(:args) { 'one' } + it_behaves_like "a performing worker" do + let(:args) { "one" } end end diff --git a/spec/examples/my_unique_job_spec.rb b/spec/examples/my_unique_job_spec.rb index b679e64dc..4a1439023 100644 --- a/spec/examples/my_unique_job_spec.rb +++ b/spec/examples/my_unique_job_spec.rb @@ -1,76 +1,76 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe MyUniqueJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'lock' => :until_executed, - 'lock_expiration' => 7_200, - 'queue' => :customqueue, - 'retry' => 10, + "lock" => :until_executed, + "lock_expiration" => 7_200, + "queue" => :customqueue, + "retry" => 10, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { %w[one two] } end - describe 'client middleware', redis: :redis do - context 'when job is delayed' do + describe "client middleware", redis: :redis do + context "when job is delayed" do before { described_class.perform_in(3600, 1, 2) } - it 'rejects new scheduled jobs' do - expect(1).to be_enqueued_in('customqueue') + it "rejects new scheduled jobs" do + expect(1).to be_enqueued_in("customqueue") described_class.perform_in(3600, 1, 2) described_class.perform_in(3600, 1, 2) described_class.perform_in(3600, 1, 2) - expect(1).to be_enqueued_in('customqueue') - expect(1).to be_enqueued_in('schedule') + expect(1).to be_enqueued_in("customqueue") + expect(1).to be_enqueued_in("schedule") expect(schedule_count).to eq(1) expect(1).to be_scheduled_at(Time.now.to_f + 2 * 3600) end - it 'rejects new jobs' do + it "rejects new jobs" do described_class.perform_async(1, 2) - expect(1).to be_enqueued_in('customqueue') + expect(1).to be_enqueued_in("customqueue") end - it 'allows duplicate messages to different queues' do - expect(1).to be_enqueued_in('customqueue2') - with_sidekiq_options_for(described_class, queue: 'customqueue2') do + it "allows duplicate messages to different queues" do + expect(1).to be_enqueued_in("customqueue2") + with_sidekiq_options_for(described_class, queue: "customqueue2") do described_class.perform_async(1, 2) - expect(1).to be_enqueued_in('customqueue2') + expect(1).to be_enqueued_in("customqueue2") end end end - context 'when job is pushed' do + context "when job is pushed" do before { described_class.perform_async(1, 2) } - it 'rejects new scheduled jobs' do - expect(1).to be_enqueued_in('customqueue') + it "rejects new scheduled jobs" do + expect(1).to be_enqueued_in("customqueue") described_class.perform_in(60, 1, 2) - expect(1).to be_enqueued_in('customqueue') + expect(1).to be_enqueued_in("customqueue") expect(0).to be_scheduled_at(Time.now.to_f + 2 * 60) end - it 'rejects new jobs' do - expect(1).to be_enqueued_in('customqueue') + it "rejects new jobs" do + expect(1).to be_enqueued_in("customqueue") described_class.perform_async(1, 2) - expect(1).to be_enqueued_in('customqueue') + expect(1).to be_enqueued_in("customqueue") end - it 'allows duplicate messages to different queues' do - expect(1).to be_enqueued_in('customqueue') - expect(0).to be_enqueued_in('customqueue2') + it "allows duplicate messages to different queues" do + expect(1).to be_enqueued_in("customqueue") + expect(0).to be_enqueued_in("customqueue2") - with_sidekiq_options_for(described_class, queue: 'customqueue2') do + with_sidekiq_options_for(described_class, queue: "customqueue2") do described_class.perform_async(1, 2) - expect(1).to be_enqueued_in('customqueue2') + expect(1).to be_enqueued_in("customqueue2") end end end diff --git a/spec/examples/my_unique_job_with_filter_method_spec.rb b/spec/examples/my_unique_job_with_filter_method_spec.rb index ec2d98954..71f8725f9 100644 --- a/spec/examples/my_unique_job_with_filter_method_spec.rb +++ b/spec/examples/my_unique_job_with_filter_method_spec.rb @@ -1,29 +1,29 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe MyUniqueJobWithFilterMethod do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'backtrace' => true, - 'queue' => :customqueue, - 'retry' => true, - 'lock' => :until_executed, - 'unique_args' => :filtered_args, + "backtrace" => true, + "queue" => :customqueue, + "retry" => true, + "lock" => :until_executed, + "unique_args" => :filtered_args, } end end - it_behaves_like 'a performing worker' do - let(:args) { ['hundred', 'type' => 'extremely unique', 'id' => 44] } + it_behaves_like "a performing worker" do + let(:args) { ["hundred", "type" => "extremely unique", "id" => 44] } end - describe '.filtered_args' do + describe ".filtered_args" do subject { described_class.filtered_args(args) } - let(:args) { ['two', 'type' => 'very unique', 'id' => 4] } + let(:args) { ["two", "type" => "very unique", "id" => 4] } - it { is_expected.to eq(['two', 'very unique']) } + it { is_expected.to eq(["two", "very unique"]) } end end diff --git a/spec/examples/my_unique_job_with_filter_proc_spec.rb b/spec/examples/my_unique_job_with_filter_proc_spec.rb index fb3173f24..8b181c4be 100644 --- a/spec/examples/my_unique_job_with_filter_proc_spec.rb +++ b/spec/examples/my_unique_job_with_filter_proc_spec.rb @@ -1,27 +1,27 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe MyUniqueJobWithFilterProc do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'backtrace' => true, - 'queue' => :customqueue, - 'retry' => true, - 'lock' => :until_executed, + "backtrace" => true, + "queue" => :customqueue, + "retry" => true, + "lock" => :until_executed, } end end - it_behaves_like 'a performing worker' do - let(:args) { ['one', 'type' => 'unique', 'id' => 2] } + it_behaves_like "a performing worker" do + let(:args) { ["one", "type" => "unique", "id" => 2] } end - describe 'unique_args' do - subject(:unique_args) { described_class.get_sidekiq_options['unique_args'].call(args) } + describe "unique_args" do + subject(:unique_args) { described_class.get_sidekiq_options["unique_args"].call(args) } - let(:args) { ['one', 'type' => 'unique', 'id' => 2] } + let(:args) { ["one", "type" => "unique", "id" => 2] } it { is_expected.to eq(%w[one unique]) } end diff --git a/spec/examples/notify_worker_spec.rb b/spec/examples/notify_worker_spec.rb index af4931a6d..662a2368f 100644 --- a/spec/examples/notify_worker_spec.rb +++ b/spec/examples/notify_worker_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe NotifyWorker do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :notify_worker, - 'retry' => true, - 'lock' => :until_executed, + "queue" => :notify_worker, + "retry" => true, + "lock" => :until_executed, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { %w[one two] } end end diff --git a/spec/examples/plain_class_spec.rb b/spec/examples/plain_class_spec.rb index 9cc957ed8..68fcf0187 100644 --- a/spec/examples/plain_class_spec.rb +++ b/spec/examples/plain_class_spec.rb @@ -1,21 +1,21 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe PlainClass do - describe '.run' do + describe ".run" do subject { described_class.run(arg) } - let(:arg) { 'argument' } + let(:arg) { "argument" } - it { is_expected.to eq(['argument']) } + it { is_expected.to eq(["argument"]) } end - describe '#run' do + describe "#run" do subject { described_class.new.run(arg) } - let(:arg) { 'another argument' } + let(:arg) { "another argument" } - it { is_expected.to eq(['another argument']) } + it { is_expected.to eq(["another argument"]) } end end diff --git a/spec/examples/simple_worker_spec.rb b/spec/examples/simple_worker_spec.rb index e055d05cf..a87bb557b 100644 --- a/spec/examples/simple_worker_spec.rb +++ b/spec/examples/simple_worker_spec.rb @@ -1,29 +1,29 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SimpleWorker do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :default, - 'retry' => true, - 'lock' => :until_executed, + "queue" => :default, + "retry" => true, + "lock" => :until_executed, } end end - it_behaves_like 'a performing worker', splat_arguments: false do - let(:args) { ['one', 'type' => 'unique', 'id' => 2] } + it_behaves_like "a performing worker", splat_arguments: false do + let(:args) { ["one", "type" => "unique", "id" => 2] } end - describe 'unique_args' do + describe "unique_args" do subject do - described_class.get_sidekiq_options['unique_args'].call(args) + described_class.get_sidekiq_options["unique_args"].call(args) end - let(:args) { ['unique', 'type' => 'unique', 'id' => 2] } + let(:args) { ["unique", "type" => "unique", "id" => 2] } - it { is_expected.to eq(['unique']) } + it { is_expected.to eq(["unique"]) } end end diff --git a/spec/examples/spawn_simple_worker_spec.rb b/spec/examples/spawn_simple_worker_spec.rb index 2baac3b7b..fefcce5b5 100644 --- a/spec/examples/spawn_simple_worker_spec.rb +++ b/spec/examples/spawn_simple_worker_spec.rb @@ -1,25 +1,25 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SpawnSimpleWorker do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :not_default, - 'retry' => true, + "queue" => :not_default, + "retry" => true, } end end - it_behaves_like 'a performing worker', splat_arguments: false do - let(:args) { ['one', 'type' => 'unique', 'id' => 2] } + it_behaves_like "a performing worker", splat_arguments: false do + let(:args) { ["one", "type" => "unique", "id" => 2] } end - describe '#perform' do + describe "#perform" do let(:args) { %w[one two] } - it 'spawns another job' do + it "spawns another job" do expect(SimpleWorker).to receive(:perform_async).with(args).and_return(true) described_class.new.perform(args) end diff --git a/spec/examples/test_class_spec.rb b/spec/examples/test_class_spec.rb index 196246334..5566ee42c 100644 --- a/spec/examples/test_class_spec.rb +++ b/spec/examples/test_class_spec.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe TestClass do - describe '.run' do + describe ".run" do subject { described_class.run(arg) } - let(:arg) { 'the one' } + let(:arg) { "the one" } - it { is_expected.to eq('the one') } + it { is_expected.to eq("the one") } end end diff --git a/spec/examples/unique_across_workers_job_spec.rb b/spec/examples/unique_across_workers_job_spec.rb index fb877269d..e6933fd96 100644 --- a/spec/examples/unique_across_workers_job_spec.rb +++ b/spec/examples/unique_across_workers_job_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UniqueAcrossWorkersJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'retry' => true, - 'lock' => :until_executed, - 'unique_across_workers' => true, + "retry" => true, + "lock" => :until_executed, + "unique_across_workers" => true, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { %w[one two] } end end diff --git a/spec/examples/unique_job_on_conflict_raise_spec.rb b/spec/examples/unique_job_on_conflict_raise_spec.rb index 5e01ffa81..568e4bb09 100644 --- a/spec/examples/unique_job_on_conflict_raise_spec.rb +++ b/spec/examples/unique_job_on_conflict_raise_spec.rb @@ -1,20 +1,20 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UniqueJobOnConflictRaise do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'lock' => :while_executing, - 'on_conflict' => :raise, - 'queue' => :customqueue, - 'retry' => true, + "lock" => :while_executing, + "on_conflict" => :raise, + "queue" => :customqueue, + "retry" => true, } end end - it_behaves_like 'a performing worker' do - let(:args) { ['hundred', 'type' => 'extremely unique', 'id' => 44] } + it_behaves_like "a performing worker" do + let(:args) { ["hundred", "type" => "extremely unique", "id" => 44] } end end diff --git a/spec/examples/unique_job_on_conflict_reject_spec.rb b/spec/examples/unique_job_on_conflict_reject_spec.rb index 4622410ec..604c92950 100644 --- a/spec/examples/unique_job_on_conflict_reject_spec.rb +++ b/spec/examples/unique_job_on_conflict_reject_spec.rb @@ -1,20 +1,20 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UniqueJobOnConflictReject do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'lock' => :while_executing, - 'on_conflict' => :reject, - 'queue' => :customqueue, - 'retry' => true, + "lock" => :while_executing, + "on_conflict" => :reject, + "queue" => :customqueue, + "retry" => true, } end end - it_behaves_like 'a performing worker' do - let(:args) { ['hundred', 'type' => 'extremely unique', 'id' => 44] } + it_behaves_like "a performing worker" do + let(:args) { ["hundred", "type" => "extremely unique", "id" => 44] } end end diff --git a/spec/examples/unique_job_on_conflict_reschedule_spec.rb b/spec/examples/unique_job_on_conflict_reschedule_spec.rb index d4840ecee..87b2279be 100644 --- a/spec/examples/unique_job_on_conflict_reschedule_spec.rb +++ b/spec/examples/unique_job_on_conflict_reschedule_spec.rb @@ -1,20 +1,20 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UniqueJobOnConflictReschedule do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'lock' => :while_executing, - 'on_conflict' => :reschedule, - 'queue' => :customqueue, - 'retry' => true, + "lock" => :while_executing, + "on_conflict" => :reschedule, + "queue" => :customqueue, + "retry" => true, } end end - it_behaves_like 'a performing worker' do - let(:args) { ['hundred', 'type' => 'extremely unique', 'id' => 44] } + it_behaves_like "a performing worker" do + let(:args) { ["hundred", "type" => "extremely unique", "id" => 44] } end end diff --git a/spec/examples/unique_job_with_nil_unique_args_spec.rb b/spec/examples/unique_job_with_nil_unique_args_spec.rb index 0daa3a0ee..4aedd5e87 100644 --- a/spec/examples/unique_job_with_nil_unique_args_spec.rb +++ b/spec/examples/unique_job_with_nil_unique_args_spec.rb @@ -1,28 +1,28 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UniqueJobWithNilUniqueArgs do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'backtrace' => true, - 'queue' => :customqueue, - 'retry' => true, - 'lock' => :until_executed, - 'unique_args' => :unique_args, + "backtrace" => true, + "queue" => :customqueue, + "retry" => true, + "lock" => :until_executed, + "unique_args" => :unique_args, } end end - it_behaves_like 'a performing worker', splat_arguments: false do - let(:args) { ['argument one', 'two', 'three'] } + it_behaves_like "a performing worker", splat_arguments: false do + let(:args) { ["argument one", "two", "three"] } end - describe '.unique_args' do + describe ".unique_args" do subject { described_class.unique_args(args) } - let(:args) { ['argument one', 'two', 'three'] } + let(:args) { ["argument one", "two", "three"] } it { is_expected.to eq(nil) } end diff --git a/spec/examples/unique_job_with_no_unique_args_method_spec.rb b/spec/examples/unique_job_with_no_unique_args_method_spec.rb index 6c7b5d98e..b8e8fecaa 100644 --- a/spec/examples/unique_job_with_no_unique_args_method_spec.rb +++ b/spec/examples/unique_job_with_no_unique_args_method_spec.rb @@ -1,21 +1,21 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UniqueJobWithNoUniqueArgsMethod do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'backtrace' => true, - 'queue' => :customqueue, - 'retry' => true, - 'lock' => :until_executed, - 'unique_args' => :filtered_args, + "backtrace" => true, + "queue" => :customqueue, + "retry" => true, + "lock" => :until_executed, + "unique_args" => :filtered_args, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { %w[one two] } end end diff --git a/spec/examples/unique_job_without_unique_args_parameter_spec.rb b/spec/examples/unique_job_without_unique_args_parameter_spec.rb index bb47faab3..4266eca10 100644 --- a/spec/examples/unique_job_without_unique_args_parameter_spec.rb +++ b/spec/examples/unique_job_without_unique_args_parameter_spec.rb @@ -1,21 +1,21 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UniqueJobWithoutUniqueArgsParameter do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'backtrace' => true, - 'queue' => :customqueue, - 'retry' => true, - 'lock' => :until_executed, - 'unique_args' => :unique_args, + "backtrace" => true, + "queue" => :customqueue, + "retry" => true, + "lock" => :until_executed, + "unique_args" => :unique_args, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { true } end end diff --git a/spec/examples/unique_on_all_queues_job_spec.rb b/spec/examples/unique_on_all_queues_job_spec.rb index 513550878..edc3f4e2a 100644 --- a/spec/examples/unique_on_all_queues_job_spec.rb +++ b/spec/examples/unique_on_all_queues_job_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UniqueOnAllQueuesJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'retry' => true, - 'lock' => :until_executed, - 'unique_on_all_queues' => true, + "retry" => true, + "lock" => :until_executed, + "unique_on_all_queues" => true, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { %w[one two three] } end end diff --git a/spec/examples/until_and_while_executing_job_spec.rb b/spec/examples/until_and_while_executing_job_spec.rb index 13aa01b66..d182e79d6 100644 --- a/spec/examples/until_and_while_executing_job_spec.rb +++ b/spec/examples/until_and_while_executing_job_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UntilAndWhileExecutingJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :working, - 'retry' => true, - 'lock' => :until_and_while_executing, + "queue" => :working, + "retry" => true, + "lock" => :until_and_while_executing, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { [%w[one]] } end end diff --git a/spec/examples/until_executed2_job_spec.rb b/spec/examples/until_executed2_job_spec.rb index 7dae3045f..54252f44a 100644 --- a/spec/examples/until_executed2_job_spec.rb +++ b/spec/examples/until_executed2_job_spec.rb @@ -1,21 +1,21 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UntilExecuted2Job do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'backtrace' => 10, - 'lock' => :until_executed, - 'lock_timeout' => 0, - 'queue' => :working, - 'retry' => 1, + "backtrace" => 10, + "lock" => :until_executed, + "lock_timeout" => 0, + "queue" => :working, + "retry" => 1, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { %w[one two] } end end diff --git a/spec/examples/until_executed_job_spec.rb b/spec/examples/until_executed_job_spec.rb index ec0ca0a21..60b9e1e52 100644 --- a/spec/examples/until_executed_job_spec.rb +++ b/spec/examples/until_executed_job_spec.rb @@ -1,22 +1,22 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UntilExecutedJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'backtrace' => 10, - 'lock_timeout' => 0, - 'lock_expiration' => 5000, - 'queue' => :working, - 'retry' => 1, - 'lock' => :until_executed, + "backtrace" => 10, + "lock_timeout" => 0, + "lock_expiration" => 5000, + "queue" => :working, + "retry" => 1, + "lock" => :until_executed, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { %w[one two] } end end diff --git a/spec/examples/until_executing_job_spec.rb b/spec/examples/until_executing_job_spec.rb index dd5675b9c..82edae904 100644 --- a/spec/examples/until_executing_job_spec.rb +++ b/spec/examples/until_executing_job_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UntilExecutingJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'queue' => :working, - 'retry' => true, - 'lock' => :until_executing, + "queue" => :working, + "retry" => true, + "lock" => :until_executing, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { no_args } end end diff --git a/spec/examples/until_expired_job_spec.rb b/spec/examples/until_expired_job_spec.rb index 90e88d56d..14df8bcef 100644 --- a/spec/examples/until_expired_job_spec.rb +++ b/spec/examples/until_expired_job_spec.rb @@ -1,20 +1,20 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UntilExpiredJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'lock_expiration' => 1, - 'lock_timeout' => 0, - 'retry' => true, - 'lock' => :until_expired, + "lock_expiration" => 1, + "lock_timeout" => 0, + "retry" => true, + "lock" => :until_expired, } end end - it_behaves_like 'a performing worker' do - let(:args) { 'one' } + it_behaves_like "a performing worker" do + let(:args) { "one" } end end diff --git a/spec/examples/until_global_expired_job_spec.rb b/spec/examples/until_global_expired_job_spec.rb index a2a578602..58412f82a 100644 --- a/spec/examples/until_global_expired_job_spec.rb +++ b/spec/examples/until_global_expired_job_spec.rb @@ -1,18 +1,18 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe UntilGlobalExpiredJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'retry' => true, - 'lock' => :until_expired, + "retry" => true, + "lock" => :until_expired, } end end - it_behaves_like 'a performing worker' do - let(:args) { 'one' } + it_behaves_like "a performing worker" do + let(:args) { "one" } end end diff --git a/spec/examples/while_executing_job_spec.rb b/spec/examples/while_executing_job_spec.rb index 13dcd3981..35d5597a6 100644 --- a/spec/examples/while_executing_job_spec.rb +++ b/spec/examples/while_executing_job_spec.rb @@ -1,26 +1,26 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe WhileExecutingJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'backtrace' => 10, - 'queue' => :working, - 'retry' => 1, - 'lock' => :while_executing, + "backtrace" => 10, + "queue" => :working, + "retry" => 1, + "lock" => :while_executing, } end end - it_behaves_like 'a performing worker' do - let(:args) { 'one' } + it_behaves_like "a performing worker" do + let(:args) { "one" } end - describe 'client middleware' do - context 'when job is already scheduled' do - it 'pushes the job immediately' do + describe "client middleware" do + context "when job is already scheduled" do + it "pushes the job immediately" do described_class.perform_in(3600, 1) expect(described_class.perform_async(1)).not_to eq(nil) end diff --git a/spec/examples/without_argument_job_spec.rb b/spec/examples/without_argument_job_spec.rb index 0a05d44ec..4d81d9654 100644 --- a/spec/examples/without_argument_job_spec.rb +++ b/spec/examples/without_argument_job_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe WithoutArgumentJob do - it_behaves_like 'sidekiq with options' do + it_behaves_like "sidekiq with options" do let(:options) do { - 'log_duplicate_payload' => true, - 'retry' => true, - 'lock' => :until_executed, + "log_duplicate_payload" => true, + "retry" => true, + "lock" => :until_executed, } end end - it_behaves_like 'a performing worker' do + it_behaves_like "a performing worker" do let(:args) { no_args } end end diff --git a/spec/integration/sidekiq/retry_set_spec.rb b/spec/integration/sidekiq/retry_set_spec.rb index fa1d27f80..1116ed51c 100644 --- a/spec/integration/sidekiq/retry_set_spec.rb +++ b/spec/integration/sidekiq/retry_set_spec.rb @@ -1,38 +1,38 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe Sidekiq::RetrySet, redis: :redis do let(:locksmith) { SidekiqUniqueJobs::Locksmith.new(item) } let(:args) { [1, 2] } let(:worker_class) { MyUniqueJob } - let(:jid) { 'ajobid' } + let(:jid) { "ajobid" } let(:lock) { :until_executed } let(:lock_expiration) { 7_200 } let(:queue) { :customqueue } let(:retry_at) { Time.now.to_f + 360 } - let(:unique_digest) { 'uniquejobs:9e9b5ce5d423d3ea470977004b50ff84' } + let(:unique_digest) { "uniquejobs:9e9b5ce5d423d3ea470977004b50ff84" } let(:item) do { - 'args' => args, - 'class' => worker_class, - 'failed_at' => Time.now.to_f, - 'jid' => jid, - 'lock' => lock, - 'lock_expiration' => lock_expiration, - 'queue' => queue, - 'retry_at' => retry_at, - 'retry_count' => 1, - 'unique_digest' => unique_digest, + "args" => args, + "class" => worker_class, + "failed_at" => Time.now.to_f, + "jid" => jid, + "lock" => lock, + "lock_expiration" => lock_expiration, + "queue" => queue, + "retry_at" => retry_at, + "retry_count" => 1, + "unique_digest" => unique_digest, } end before do - zadd('retry', retry_at.to_s, Sidekiq.dump_json(item)) + zadd("retry", retry_at.to_s, Sidekiq.dump_json(item)) expect(retry_count).to eq(1) end - context 'when a job is locked' do + context "when a job is locked" do before do expect(locksmith.lock).to eq(jid) expect(unique_keys).to match_array(%W[ @@ -43,7 +43,7 @@ expect(ttl("#{unique_digest}:GRABBED")).to eq(-1) end - it 'can be put back on queue' do + it "can be put back on queue" do expect { described_class.new.retry_all } .to change { queue_count(queue) } .from(0).to(1) diff --git a/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb b/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb index 03bf18445..247f113c0 100644 --- a/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Client::Middleware, redis: :redis, redis_db: 1 do - describe 'when a job is already scheduled' do - it 'processes jobs properly' do - jid = NotifyWorker.perform_in(1, 183, 'xxxx') + describe "when a job is already scheduled" do + it "processes jobs properly" do + jid = NotifyWorker.perform_in(1, 183, "xxxx") expect(jid).not_to eq(nil) expect(schedule_count).to eq(1) @@ -17,7 +17,7 @@ expect(keys).to include(*expected) end - it 'rejects nested subsequent jobs with the same arguments' do + it "rejects nested subsequent jobs with the same arguments" do expect(SimpleWorker.perform_async(1)).not_to eq(nil) expect(SimpleWorker.perform_async(1)).to eq(nil) expect(SimpleWorker.perform_in(60, 1)).to eq(nil) @@ -26,11 +26,11 @@ expect(schedule_count).to eq(0) expect(SpawnSimpleWorker.perform_async(1)).not_to eq(nil) - expect(queue_count('default')).to eq(1) - expect(queue_count('not_default')).to eq(1) + expect(queue_count("default")).to eq(1) + expect(queue_count("not_default")).to eq(1) end - it 'schedules new jobs when arguments differ' do + it "schedules new jobs when arguments differ" do [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20].each do |x| MainJob.perform_in(x, x) end @@ -38,7 +38,7 @@ expect(schedule_count).to eq(20) end - it 'schedules allows jobs to be scheduled ' do + it "schedules allows jobs to be scheduled " do class ShitClass def self.do_it(_one) # whatever @@ -53,154 +53,154 @@ def self.do_it(_one) end end - it 'does not push duplicate messages when unique_args are filtered with a proc' do + it "does not push duplicate messages when unique_args are filtered with a proc" do 10.times { MyUniqueJobWithFilterProc.perform_async(1) } - expect(queue_count('customqueue')).to eq(1) + expect(queue_count("customqueue")).to eq(1) Sidekiq.redis(&:flushdb) - expect(queue_count('customqueue')).to eq(0) + expect(queue_count("customqueue")).to eq(0) 10.times do Sidekiq::Client.push( - 'class' => MyUniqueJobWithFilterProc, - 'queue' => 'customqueue', - 'args' => [1, type: 'value', some: 'not used'], + "class" => MyUniqueJobWithFilterProc, + "queue" => "customqueue", + "args" => [1, type: "value", some: "not used"], ) end - expect(queue_count('customqueue')).to eq(1) + expect(queue_count("customqueue")).to eq(1) end - it 'does not push duplicate messages when unique_args are filtered with a method' do + it "does not push duplicate messages when unique_args are filtered with a method" do 10.times { MyUniqueJobWithFilterMethod.perform_async(1) } - expect(queue_count('customqueue')).to eq(1) + expect(queue_count("customqueue")).to eq(1) Sidekiq.redis(&:flushdb) - expect(queue_count('customqueue')).to eq(0) + expect(queue_count("customqueue")).to eq(0) 10.times do Sidekiq::Client.push( - 'class' => MyUniqueJobWithFilterMethod, - 'queue' => 'customqueue', - 'args' => [1, type: 'value', some: 'not used'], + "class" => MyUniqueJobWithFilterMethod, + "queue" => "customqueue", + "args" => [1, type: "value", some: "not used"], ) end - expect(queue_count('customqueue')).to eq(1) + expect(queue_count("customqueue")).to eq(1) end - it 'does not queue duplicates when when calling delay' do - 10.times { PlainClass.delay(unique: :until_executed, queue: 'customqueue').run(1) } + it "does not queue duplicates when when calling delay" do + 10.times { PlainClass.delay(unique: :until_executed, queue: "customqueue").run(1) } - expect(queue_count('customqueue')).to eq(1) + expect(queue_count("customqueue")).to eq(1) end - context 'when class is not unique' do - it 'pushes duplicate messages' do + context "when class is not unique" do + it "pushes duplicate messages" do 10.times do - Sidekiq::Client.push('class' => CustomQueueJob, 'queue' => 'customqueue', 'args' => [1, 2]) + Sidekiq::Client.push("class" => CustomQueueJob, "queue" => "customqueue", "args" => [1, 2]) end - expect(queue_count('customqueue')).to eq(10) + expect(queue_count("customqueue")).to eq(10) end end - describe 'when unique_args is defined' do - context 'when filter method is defined' do - it 'pushes no duplicate messages' do + describe "when unique_args is defined" do + context "when filter method is defined" do + it "pushes no duplicate messages" do expect(CustomQueueJobWithFilterMethod).to respond_to(:args_filter) - expect(CustomQueueJobWithFilterMethod.get_sidekiq_options['unique_args']).to eq :args_filter + expect(CustomQueueJobWithFilterMethod.get_sidekiq_options["unique_args"]).to eq :args_filter (0..10).each do |i| Sidekiq::Client.push( - 'class' => CustomQueueJobWithFilterMethod, - 'queue' => 'customqueue', - 'args' => [1, i], + "class" => CustomQueueJobWithFilterMethod, + "queue" => "customqueue", + "args" => [1, i], ) end - expect(queue_count('customqueue')).to eq(1) + expect(queue_count("customqueue")).to eq(1) end end - context 'when filter proc is defined' do - let(:args) { [1, { random: rand, name: 'foobar' }] } + context "when filter proc is defined" do + let(:args) { [1, { random: rand, name: "foobar" }] } - it 'pushes no duplicate messages' do + it "pushes no duplicate messages" do 100.times { CustomQueueJobWithFilterProc.perform_async(args) } - expect(queue_count('customqueue')).to eq(1) + expect(queue_count("customqueue")).to eq(1) end end - context 'when unique_on_all_queues is set' do - it 'pushes no duplicate messages on other queues' do - item = { 'class' => UniqueOnAllQueuesJob, 'args' => [1, 2] } - Sidekiq::Client.push(item.merge('queue' => 'customqueue')) - Sidekiq::Client.push(item.merge('queue' => 'customqueue2')) + context "when unique_on_all_queues is set" do + it "pushes no duplicate messages on other queues" do + item = { "class" => UniqueOnAllQueuesJob, "args" => [1, 2] } + Sidekiq::Client.push(item.merge("queue" => "customqueue")) + Sidekiq::Client.push(item.merge("queue" => "customqueue2")) - expect(queue_count('customqueue')).to eq(1) - expect(queue_count('customqueue2')).to eq(0) + expect(queue_count("customqueue")).to eq(1) + expect(queue_count("customqueue2")).to eq(0) end end - context 'when unique_across_workers is set' do - it 'does not push duplicate messages for other workers' do + context "when unique_across_workers is set" do + it "does not push duplicate messages for other workers" do item_one = { - 'queue' => 'customqueue1', - 'class' => UniqueAcrossWorkersJob, - 'unique_across_workers' => true, - 'args' => [1, 2], + "queue" => "customqueue1", + "class" => UniqueAcrossWorkersJob, + "unique_across_workers" => true, + "args" => [1, 2], } item_two = { - 'queue' => 'customqueue1', - 'class' => MyUniqueJob, - 'unique_across_workers' => true, - 'args' => [1, 2], + "queue" => "customqueue1", + "class" => MyUniqueJob, + "unique_across_workers" => true, + "args" => [1, 2], } Sidekiq::Client.push(item_one) Sidekiq::Client.push(item_two) - expect(queue_count('customqueue1')).to eq(1) + expect(queue_count("customqueue1")).to eq(1) end end end - it 'expires the digest when a scheduled job is scheduled at' do + it "expires the digest when a scheduled job is scheduled at" do expected_expires_at = Time.now.to_i + 15 * 60 - Time.now.utc.to_i - MyUniqueJob.perform_in(expected_expires_at, 'mika', 'hel') + MyUniqueJob.perform_in(expected_expires_at, "mika", "hel") unique_keys.each do |key| - next if key.end_with?(':GRABBED') + next if key.end_with?(":GRABBED") expect(ttl(key)).to be_within(10).of(8_099) end end - it 'logs duplicate payload when config turned on' do + it "logs duplicate payload when config turned on" do expect(Sidekiq.logger).to receive(:warn).with(/^payload is not unique/) with_sidekiq_options_for(UntilExecutedJob, log_duplicate_payload: true) do 2.times do - Sidekiq::Client.push('class' => UntilExecutedJob, 'queue' => 'customqueue', 'args' => [1, 2]) + Sidekiq::Client.push("class" => UntilExecutedJob, "queue" => "customqueue", "args" => [1, 2]) end - expect(queue_count('customqueue')).to eq(1) + expect(queue_count("customqueue")).to eq(1) end end - it 'does not log duplicate payload when config turned off' do + it "does not log duplicate payload when config turned off" do expect(SidekiqUniqueJobs.logger).not_to receive(:warn).with(/^payload is not unique/) with_sidekiq_options_for(UntilExecutedJob, log_duplicate_payload: false) do 2.times do - Sidekiq::Client.push('class' => UntilExecutedJob, 'queue' => 'customqueue', 'args' => [1, 2]) + Sidekiq::Client.push("class" => UntilExecutedJob, "queue" => "customqueue", "args" => [1, 2]) end - expect(queue_count('customqueue')).to eq(1) + expect(queue_count("customqueue")).to eq(1) end end end diff --git a/spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb b/spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb index 92b5eb81b..caf589024 100644 --- a/spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb @@ -1,53 +1,53 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" # rubocop:disable RSpec/FilePath RSpec.describe SidekiqUniqueJobs::Locksmith, redis: :redis do - let(:locksmith_one) { described_class.new(lock_item) } + let(:locksmith_one) { described_class.new(lock_item) } let(:lock_expiration) { nil } let(:redis_pool) { nil } - let(:jid_one) { 'maaaahjid' } - let(:jid_two) { 'anotherjid' } - let(:unique_digest) { 'uniquejobs:test_mutex_key' } - let(:queue) { 'dupsallowed' } + let(:jid_one) { "maaaahjid" } + let(:jid_two) { "anotherjid" } + let(:unique_digest) { "uniquejobs:test_mutex_key" } + let(:queue) { "dupsallowed" } let(:unique) { :until_executed } let(:worker_class) { UntilExecutedJob } let(:lock_item) do { - 'args' => [1], - 'class' => UntilExecutedJob, - 'jid' => jid_one, - 'lock_expiration' => lock_expiration, - 'queue' => queue, - 'lock' => unique, - 'unique_digest' => unique_digest, + "args" => [1], + "class" => UntilExecutedJob, + "jid" => jid_one, + "lock_expiration" => lock_expiration, + "queue" => queue, + "lock" => unique, + "unique_digest" => unique_digest, } end let(:locksmith_two) { described_class.new(lock_item_two) } - let(:lock_item_two) { lock_item.merge('jid' => jid_two) } + let(:lock_item_two) { lock_item.merge("jid" => jid_two) } - context 'with a legacy uniquejobs hash' do + context "with a legacy uniquejobs hash" do before do SidekiqUniqueJobs.redis do |conn| conn.multi do - conn.hset('uniquejobs', 'bogus', 'value') - conn.hset('uniquejobs', 'bogus', 'value 2') + conn.hset("uniquejobs", "bogus", "value") + conn.hset("uniquejobs", "bogus", "value 2") end end end - it 'deletes the uniquejobs hash' do - expect(keys).to include('uniquejobs') - expect(hexists('uniquejobs', 'bogus')).to eq(true) + it "deletes the uniquejobs hash" do + expect(keys).to include("uniquejobs") + expect(hexists("uniquejobs", "bogus")).to eq(true) locksmith_one.delete - expect(keys).not_to include('uniquejobs') - expect(hexists('uniquejobs', 'bogus')).to eq(false) + expect(keys).not_to include("uniquejobs") + expect(hexists("uniquejobs", "bogus")).to eq(false) end end - context 'with a legacy lock' do + context "with a legacy lock" do before do result = SidekiqUniqueJobs::Scripts.call( :acquire_lock, @@ -60,63 +60,63 @@ expect(unique_keys).to include(unique_digest) end - context 'when lock_expiration is unset' do + context "when lock_expiration is unset" do let(:lock_value) { jid_one } - it 'unlocks immediately' do + it "unlocks immediately" do locksmith_one.unlock!(jid_one) expect(ttl(unique_digest)).to eq(-2) # key does not exist anymore end - it 'can soft deletes the lock' do + it "can soft deletes the lock" do expect(locksmith_one.delete).to eq(nil) expect(unique_keys).not_to include(unique_digest) end - it 'can force delete the lock' do + it "can force delete the lock" do expect(locksmith_one.delete!).to eq(nil) expect(unique_keys).not_to include(unique_digest) end end - context 'when lock_expiration is set' do + context "when lock_expiration is set" do let(:lock_value) { jid_one } let(:lock_expiration) { 10 } - it 'can signal to expire the lock after 10' do + it "can signal to expire the lock after 10" do locksmith_one.unlock(jid_one) expect(ttl(unique_digest)).to be_within(1).of(10) end - it 'cannot soft delete the lock' do + it "cannot soft delete the lock" do expect(locksmith_one.delete).to eq(nil) expect(unique_keys).to include(unique_digest) end - it 'can force delete the lock' do + it "can force delete the lock" do expect(locksmith_one.delete!).to eq(nil) expect(unique_keys).not_to include(unique_digest) end end - context 'when the value of unique_digest is 2' do - let(:lock_value) { '2' } + context "when the value of unique_digest is 2" do + let(:lock_value) { "2" } - it 'returns the stored jid' do + it "returns the stored jid" do expect(locksmith_one.lock(0)).to eq(jid_one) end end - context 'when the value of unique_digest is jid' do + context "when the value of unique_digest is jid" do let(:lock_value) { jid_one } - it 'returns the stored jid' do + it "returns the stored jid" do expect(locksmith_one.lock(0)).to eq(jid_one) end - it 'can not be locked by another jid' do + it "can not be locked by another jid" do expect(locksmith_two.lock(0)).to eq(nil) end end diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb index 422b4f224..d045d8ee4 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilAndWhileExecuting, redis: :redis, redis_db: 3 do include SidekiqHelpers @@ -11,8 +11,8 @@ let(:process_two) { described_class.new(item_two, callback) } let(:runtime_two) { SidekiqUniqueJobs::Lock::WhileExecuting.new(item_two.dup, callback) } - let(:jid_one) { 'jid one' } - let(:jid_two) { 'jid two' } + let(:jid_one) { "jid one" } + let(:jid_two) { "jid two" } let(:lock_timeout) { nil } let(:sleepy_time) { 0 } let(:worker_class) { UntilAndWhileExecutingJob } @@ -21,15 +21,15 @@ let(:args) { [sleepy_time] } let(:callback) { -> {} } let(:item_one) do - { 'jid' => jid_one, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args, - 'lock_timeout' => lock_timeout } + { "jid" => jid_one, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args, + "lock_timeout" => lock_timeout } end let(:item_two) do - item_one.merge('jid' => jid_two) + item_one.merge("jid" => jid_two) end before do @@ -37,33 +37,33 @@ allow(process_two).to receive(:runtime_lock).and_return(runtime_two) end - it_behaves_like 'a lock implementation' + it_behaves_like "a lock implementation" - it 'has not locked runtime_one' do + it "has not locked runtime_one" do process_one.lock expect(runtime_one).not_to be_locked end - context 'when process_one executes the job' do - it 'releases the lock for process_one' do + context "when process_one executes the job" do + it "releases the lock for process_one" do process_one.execute do expect(process_one).not_to be_locked end end - it 'is locked by runtime_one' do + it "is locked by runtime_one" do process_one.execute do expect(runtime_one).to be_locked end end - it 'allows process_two to lock' do + it "allows process_two to lock" do process_one.execute do expect(process_two.lock).to eq(jid_two) end end - it 'process two cannot execute the job' do + it "process two cannot execute the job" do process_one.execute do process_two.lock unset = true diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb index fe0df7f6b..2dfebce33 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuted, redis: :redis do include SidekiqHelpers @@ -8,61 +8,61 @@ let(:process_one) { described_class.new(item_one, callback) } let(:process_two) { described_class.new(item_two, callback) } - let(:jid_one) { 'jid one' } - let(:jid_two) { 'jid two' } + let(:jid_one) { "jid one" } + let(:jid_two) { "jid two" } let(:worker_class) { UntilExecutedJob } let(:unique) { :until_executed } let(:queue) { :executed } let(:args) { %w[array of arguments] } let(:callback) { -> {} } let(:item_one) do - { 'jid' => jid_one, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args } + { "jid" => jid_one, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args } end let(:item_two) do - { 'jid' => jid_two, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args } + { "jid" => jid_two, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args } end before do allow(callback).to receive(:call).and_call_original end - describe '#lock' do - it_behaves_like 'a lock implementation' + describe "#lock" do + it_behaves_like "a lock implementation" end - describe '#execute' do - it_behaves_like 'an executing lock implementation' + describe "#execute" do + it_behaves_like "an executing lock implementation" - it 'unlocks after executing' do + it "unlocks after executing" do process_one.lock process_one.execute {} expect(process_one).not_to be_locked end end - describe '#delete' do + describe "#delete" do subject(:delete) { process_one.delete } - context 'when locked' do - context 'when expiration is not negative' do - it 'deletes the lock without fuss' do + context "when locked" do + context "when expiration is not negative" do + it "deletes the lock without fuss" do worker_class.use_options(lock_expiration: nil) do process_one.lock - expect { delete }.to change { unique_keys.size }.from(2).to(0) + expect { delete }.to change(unique_keys, :size).from(2).to(0) end end end - context 'when expiration is positive' do - it 'does not delete the lock' do + context "when expiration is positive" do + it "does not delete the lock" do worker_class.use_options(lock_expiration: 100) do process_one.lock expect { delete }.not_to change(unique_keys, :size) @@ -72,14 +72,14 @@ end end - describe '#delete!' do + describe "#delete!" do subject(:delete!) { process_one.delete! } - context 'when locked' do + context "when locked" do before { process_one.lock } - it 'deletes the lock without fuss' do - expect { delete! }.to change { unique_keys.size }.from(2).to(0) + it "deletes the lock without fuss" do + expect { delete! }.to change(unique_keys, :size).from(2).to(0) end end end diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb index b7cc81d6c..6c94b4a87 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuting, redis: :redis do include SidekiqHelpers @@ -8,38 +8,38 @@ let(:process_one) { described_class.new(item_one, callback) } let(:process_two) { described_class.new(item_two, callback) } - let(:jid_one) { 'jid one' } - let(:jid_two) { 'jid two' } + let(:jid_one) { "jid one" } + let(:jid_two) { "jid two" } let(:worker_class) { UntilExecutedJob } let(:unique) { :until_executed } let(:queue) { :executed } let(:args) { %w[array of arguments] } let(:callback) { -> {} } let(:item_one) do - { 'jid' => jid_one, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args } + { "jid" => jid_one, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args } end let(:item_two) do - { 'jid' => jid_two, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args } + { "jid" => jid_two, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args } end before do allow(callback).to receive(:call).and_call_original end - describe '#lock' do - it_behaves_like 'a lock implementation' + describe "#lock" do + it_behaves_like "a lock implementation" end - describe '#execute' do - it 'unlocks before executing' do + describe "#execute" do + it "unlocks before executing" do process_one.lock process_one.execute do expect(process_one).not_to be_locked @@ -47,21 +47,21 @@ end end - describe '#delete' do + describe "#delete" do subject(:delete) { process_one.delete } - context 'when locked' do - context 'when expiration is not negative' do - it 'deletes the lock without fuss' do + context "when locked" do + context "when expiration is not negative" do + it "deletes the lock without fuss" do worker_class.use_options(lock_expiration: nil) do process_one.lock - expect { delete }.to change { unique_keys.size }.from(2).to(0) + expect { delete }.to change(unique_keys, :size).from(2).to(0) end end end - context 'when expiration is positive' do - it 'does not delete the lock' do + context "when expiration is positive" do + it "does not delete the lock" do worker_class.use_options(lock_expiration: 100) do process_one.lock expect { delete }.not_to change(unique_keys, :size) @@ -71,14 +71,14 @@ end end - describe '#delete!' do + describe "#delete!" do subject(:delete!) { process_one.delete! } - context 'when locked' do + context "when locked" do before { process_one.lock } - it 'deletes the lock without fuss' do - expect { delete! }.to change { unique_keys.size }.from(2).to(0) + it "deletes the lock without fuss" do + expect { delete! }.to change(unique_keys, :size).from(2).to(0) end end end diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb index a81f4f014..69d9a4254 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExpired, redis: :redis do include SidekiqHelpers @@ -8,52 +8,52 @@ let(:process_one) { described_class.new(item_one, callback) } let(:process_two) { described_class.new(item_two, callback) } - let(:jid_one) { 'jid one' } - let(:jid_two) { 'jid two' } + let(:jid_one) { "jid one" } + let(:jid_two) { "jid two" } let(:worker_class) { UntilExpiredJob } let(:unique) { :until_expired } let(:queue) { :rejecting } let(:args) { %w[array of arguments] } let(:callback) { -> {} } let(:item_one) do - { 'jid' => jid_one, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args } + { "jid" => jid_one, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args } end let(:item_two) do - { 'jid' => jid_two, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args } + { "jid" => jid_two, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args } end before do allow(callback).to receive(:call).and_call_original end - describe '#lock' do - it_behaves_like 'a lock implementation' + describe "#lock" do + it_behaves_like "a lock implementation" end - describe '#execute' do - it_behaves_like 'an executing lock implementation' + describe "#execute" do + it_behaves_like "an executing lock implementation" - it 'keeps lock after executing' do + it "keeps lock after executing" do process_one.lock process_one.execute {} expect(process_one).to be_locked - expect(ttl('uniquejobs:da6005926a8457526e998f0033901dfc:EXISTS')).to eq(1) + expect(ttl("uniquejobs:da6005926a8457526e998f0033901dfc:EXISTS")).to eq(1) end end - describe '#unlock' do - context 'when lock is locked' do + describe "#unlock" do + context "when lock is locked" do before { process_one.lock } - it 'keeps the lock even when unlocking' do + it "keeps the lock even when unlocking" do expect(process_one.unlock).to eq(true) expect(process_one).to be_locked end diff --git a/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb index 265e41820..4bee3ce53 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecutingReject, redis: :redis do include SidekiqHelpers @@ -8,30 +8,30 @@ let(:process_one) { described_class.new(item_one, callback) } let(:process_two) { described_class.new(item_two, callback) } - let(:jid_one) { 'jid one' } - let(:jid_two) { 'jid two' } + let(:jid_one) { "jid one" } + let(:jid_two) { "jid two" } let(:worker_class) { WhileExecutingRejectJob } let(:unique) { :while_executing_reject } let(:queue) { :rejecting } let(:args) { %w[array of arguments] } let(:callback) { -> {} } let(:item_one) do - { 'jid' => jid_one, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args } + { "jid" => jid_one, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args } end let(:item_two) do - { 'jid' => jid_two, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args } + { "jid" => jid_two, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args } end - describe '#execute' do - it 'does not lock jobs' do + describe "#execute" do + it "does not lock jobs" do expect(process_one.lock).to eq(true) expect(process_one).not_to be_locked @@ -39,15 +39,15 @@ expect(process_two).not_to be_locked end - context 'when job is executing' do - it 'locks the process' do + context "when job is executing" do + it "locks the process" do process_one.execute do expect(process_one).to be_locked end end - shared_examples 'rejects job to deadset' do - it 'moves subsequent jobs to dead queue' do + shared_examples "rejects job to deadset" do + it "moves subsequent jobs to dead queue" do process_one.execute do expect(dead_count).to eq(0) expect { process_two.execute {} } @@ -55,13 +55,13 @@ end end end - it_behaves_like 'rejects job to deadset' + it_behaves_like "rejects job to deadset" - context 'when Sidekiq::DeadSet respond to kill' do - it_behaves_like 'rejects job to deadset' + context "when Sidekiq::DeadSet respond to kill" do + it_behaves_like "rejects job to deadset" end - context 'when Sidekiq::DeadSet does not respond to kill' do + context "when Sidekiq::DeadSet does not respond to kill" do let(:strategy) { SidekiqUniqueJobs::OnConflict::Reject.new(item_two) } before do @@ -69,7 +69,7 @@ allow(process_two).to receive(:strategy).and_return(strategy) end - it_behaves_like 'rejects job to deadset' + it_behaves_like "rejects job to deadset" end end end diff --git a/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb index 9fc6ea278..97542f09d 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting, redis: :redis do include SidekiqHelpers @@ -8,34 +8,34 @@ let(:process_one) { described_class.new(item_one, callback) } let(:process_two) { described_class.new(item_two, callback) } - let(:jid_one) { 'jid one' } - let(:jid_two) { 'jid two' } + let(:jid_one) { "jid one" } + let(:jid_two) { "jid two" } let(:worker_class) { WhileExecutingJob } let(:unique) { :while_executing } let(:queue) { :while_executing } let(:args) { %w[array of arguments] } let(:callback) { -> {} } let(:item_one) do - { 'jid' => jid_one, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args } + { "jid" => jid_one, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args } end let(:item_two) do - { 'jid' => jid_two, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args } + { "jid" => jid_two, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args } end before do allow(callback).to receive(:call).and_call_original end - describe '#lock' do - it 'does not lock jobs' do + describe "#lock" do + it "does not lock jobs" do expect(process_one.lock).to eq(true) expect(process_one).not_to be_locked @@ -44,20 +44,20 @@ end end - describe '#execute' do - context 'when executing' do - it 'locks the process' do + describe "#execute" do + context "when executing" do + it "locks the process" do process_one.execute do expect(process_one).to be_locked end end - it 'calls back' do + it "calls back" do process_one.execute {} expect(callback).to have_received(:call) end - it 'prevents other processes from executing' do + it "prevents other processes from executing" do process_one.execute do unset = true process_two.execute { unset = false } diff --git a/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb b/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb index 1cc153d35..8992428b2 100644 --- a/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb @@ -1,48 +1,48 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Locksmith, redis: :redis do let(:locksmith_one) { described_class.new(item_one) } let(:locksmith_two) { described_class.new(item_two) } - let(:jid_one) { 'maaaahjid' } - let(:jid_two) { 'jidmayhem' } - let(:lock_expiration) { nil } - let(:unique_digest) { 'uniquejobs:randomvalue' } + let(:jid_one) { "maaaahjid" } + let(:jid_two) { "jidmayhem" } + let(:lock_expiration) { nil } + let(:unique_digest) { "uniquejobs:randomvalue" } let(:item_one) do { - 'jid' => jid_one, - 'unique_digest' => unique_digest, - 'lock_expiration' => lock_expiration, + "jid" => jid_one, + "unique_digest" => unique_digest, + "lock_expiration" => lock_expiration, } end - let(:item_two) { item_one.merge('jid' => jid_two) } + let(:item_two) { item_one.merge("jid" => jid_two) } - shared_examples_for 'a lock' do - it 'does not exist from the start' do + shared_examples_for "a lock" do + it "does not exist from the start" do expect(locksmith_one.exists?).to eq(false) locksmith_one.lock expect(locksmith_one.exists?).to eq(true) end - it 'is unlocked from the start' do + it "is unlocked from the start" do expect(locksmith_one.locked?).to eq(false) end - it 'locks and unlocks' do + it "locks and unlocks" do locksmith_one.lock(1) expect(locksmith_one.locked?).to eq(true) locksmith_one.unlock expect(locksmith_one.locked?).to eq(false) end - it 'does not lock twice as a mutex' do + it "does not lock twice as a mutex" do expect(locksmith_one.lock(0)).to be_truthy expect(locksmith_two.lock(0)).to eq(nil) end - it 'executes the given code block' do + it "executes the given code block" do code_executed = false locksmith_one.lock(1) do code_executed = true @@ -50,32 +50,32 @@ expect(code_executed).to eq(true) end - it 'passes an exception right through' do + it "passes an exception right through" do expect do locksmith_one.lock(1) do - raise Exception, 'redis lock exception' + raise Exception, "redis lock exception" end - end.to raise_error(Exception, 'redis lock exception') + end.to raise_error(Exception, "redis lock exception") end - it 'does not leave the lock locked after raising an exception' do + it "does not leave the lock locked after raising an exception" do expect do locksmith_one.lock(1) do - raise Exception, 'redis lock exception' + raise Exception, "redis lock exception" end - end.to raise_error(Exception, 'redis lock exception') + end.to raise_error(Exception, "redis lock exception") expect(locksmith_one.locked?).to eq(false) end - it 'returns the value of the block if block-style locking is used' do + it "returns the value of the block if block-style locking is used" do block_value = locksmith_one.lock(1) do 42 end expect(block_value).to eq(42) end - it 'disappears without a trace when calling `delete!`' do + it "disappears without a trace when calling `delete!`" do original_key_size = keys.size locksmith_one.lock @@ -84,7 +84,7 @@ expect(keys.size).to eq(original_key_size) end - it 'does not block when the timeout is zero' do + it "does not block when the timeout is zero" do did_we_get_in = false locksmith_one.lock do @@ -96,48 +96,48 @@ expect(did_we_get_in).to be false end - it 'is locked when the timeout is zero' do + it "is locked when the timeout is zero" do locksmith_one.lock(0) do expect(locksmith_one.locked?).to be true end expect(locksmith_one.locked?).to eq false end - it 'does something' do + it "does something" do expect(locksmith_one.available_count).to eq(1) locksmith_one.lock(0) expect(locksmith_one.available_count).to eq(0) end end - describe 'lock with expiration' do + describe "lock with expiration" do let(:lock_expiration) { 3 } - it_behaves_like 'a lock' + it_behaves_like "a lock" - it 'creates the expected keys' do + it "creates the expected keys" do locksmith_one.lock - expect(ttl('uniquejobs:randomvalue:EXISTS')).to eq(3) + expect(ttl("uniquejobs:randomvalue:EXISTS")).to eq(3) # PLEASE keep this spec. It verifies that the next lock # doesn't persist the exist_key of another lock sleep 1 - expect(ttl('uniquejobs:randomvalue:EXISTS')).to eq(2) + expect(ttl("uniquejobs:randomvalue:EXISTS")).to eq(2) expect(locksmith_two.lock(0)).to eq(nil) - expect(ttl('uniquejobs:randomvalue:EXISTS')).to eq(2) + expect(ttl("uniquejobs:randomvalue:EXISTS")).to eq(2) - expect(unique_digests).to match_array(['uniquejobs:randomvalue']) + expect(unique_digests).to match_array(["uniquejobs:randomvalue"]) expect(unique_keys).to match_array(%w[ uniquejobs:randomvalue:EXISTS uniquejobs:randomvalue:GRABBED ]) end - it 'expires the expected keys' do + it "expires the expected keys" do locksmith_one.lock - expect(unique_digests).to match_array(['uniquejobs:randomvalue']) + expect(unique_digests).to match_array(["uniquejobs:randomvalue"]) expect(unique_keys).to match_array(%w[ uniquejobs:randomvalue:EXISTS uniquejobs:randomvalue:GRABBED @@ -145,12 +145,12 @@ locksmith_one.unlock expect(unique_digests).to match_array([]) - expect(ttl('uniquejobs:randomvalue:EXISTS')).to eq(3) + expect(ttl("uniquejobs:randomvalue:EXISTS")).to eq(3) end - it 'deletes the expected keys' do + it "deletes the expected keys" do locksmith_one.lock - expect(unique_digests).to match_array(['uniquejobs:randomvalue']) + expect(unique_digests).to match_array(["uniquejobs:randomvalue"]) expect(unique_keys).to match_array(%w[ uniquejobs:randomvalue:EXISTS uniquejobs:randomvalue:GRABBED @@ -160,14 +160,14 @@ expect(unique_keys).to match_array(%w[]) end - it 'expires keys' do + it "expires keys" do Sidekiq.redis(&:flushdb) locksmith_one.lock keys = unique_keys expect(unique_keys).not_to include(keys) end - it 'expires keys after unlocking' do + it "expires keys after unlocking" do Sidekiq.redis(&:flushdb) locksmith_one.lock do # noop @@ -226,14 +226,14 @@ # end # end - describe 'current_time' do + describe "current_time" do let(:lock_stale_client_timeout) { 5 } before do Timecop.freeze(Time.local(1990)) end - it 'with time support should return a different time than frozen time' do + it "with time support should return a different time than frozen time" do expect(locksmith_one.send(:current_time)).not_to eq(Time.now) end end diff --git a/spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb index 6ff041864..fd59788b5 100644 --- a/spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" # rubocop:disable RSpec/FilePath, RSpec/DescribeMethod -RSpec.describe SidekiqUniqueJobs::Server::Middleware, 'unique: :until_and_while_executing', redis: :redis do +RSpec.describe SidekiqUniqueJobs::Server::Middleware, "unique: :until_and_while_executing", redis: :redis do let(:server) { described_class.new } - let(:jid_one) { 'jid one' } - let(:jid_two) { 'jid two' } + let(:jid_one) { "jid one" } + let(:jid_two) { "jid two" } let(:lock_timeout) { nil } let(:sleepy_time) { 0 } let(:worker_class) { UntilAndWhileExecutingJob } @@ -16,43 +16,43 @@ let(:args) { [sleepy_time] } let(:callback) { -> {} } let(:item_one) do - { 'jid' => jid_one, - 'class' => worker_class.to_s, - 'queue' => queue, - 'lock' => unique, - 'args' => args, - 'lock_timeout' => lock_timeout } + { "jid" => jid_one, + "class" => worker_class.to_s, + "queue" => queue, + "lock" => unique, + "args" => args, + "lock_timeout" => lock_timeout } end let(:item_two) do - item_one.merge('jid' => jid_two) + item_one.merge("jid" => jid_two) end - let(:available_key) { 'uniquejobs:f07093737839f88af8593c945143574d:AVAILABLE' } - let(:exists_key) { 'uniquejobs:f07093737839f88af8593c945143574d:EXISTS' } - let(:grabbed_key) { 'uniquejobs:f07093737839f88af8593c945143574d:GRABBED' } - let(:version_key) { 'uniquejobs:f07093737839f88af8593c945143574d:VERSION' } + let(:available_key) { "uniquejobs:f07093737839f88af8593c945143574d:AVAILABLE" } + let(:exists_key) { "uniquejobs:f07093737839f88af8593c945143574d:EXISTS" } + let(:grabbed_key) { "uniquejobs:f07093737839f88af8593c945143574d:GRABBED" } + let(:version_key) { "uniquejobs:f07093737839f88af8593c945143574d:VERSION" } - let(:available_run_key) { 'uniquejobs:f07093737839f88af8593c945143574d:RUN:AVAILABLE' } - let(:exists_run_key) { 'uniquejobs:f07093737839f88af8593c945143574d:RUN:EXISTS' } - let(:grabbed_run_key) { 'uniquejobs:f07093737839f88af8593c945143574d:RUN:GRABBED' } - let(:version_run_key) { 'uniquejobs:f07093737839f88af8593c945143574d:RUN:VERSION' } + let(:available_run_key) { "uniquejobs:f07093737839f88af8593c945143574d:RUN:AVAILABLE" } + let(:exists_run_key) { "uniquejobs:f07093737839f88af8593c945143574d:RUN:EXISTS" } + let(:grabbed_run_key) { "uniquejobs:f07093737839f88af8593c945143574d:RUN:GRABBED" } + let(:version_run_key) { "uniquejobs:f07093737839f88af8593c945143574d:RUN:VERSION" } - context 'when item_one is locked' do + context "when item_one is locked" do before do expect(push_item(item_one)).to eq(jid_one) end - context 'with a lock_timeout of 0' do + context "with a lock_timeout of 0" do let(:lock_timeout) { 0 } - context 'when processing takes 0 seconds' do + context "when processing takes 0 seconds" do let(:sleepy_time) { 0 } - it 'cannot lock item_two' do + it "cannot lock item_two" do expect(push_item(item_two)).to eq(nil) end - it 'item_one can be executed by server' do + it "item_one can be executed by server" do expect(unique_keys).to match_array([grabbed_key, exists_key]) server.call(worker_class, item_one, queue) {} expect(unique_keys).to match_array([available_key, available_run_key]) diff --git a/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb b/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb index 3dfc61e37..0242d8b9a 100644 --- a/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb @@ -1,30 +1,30 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Server::Middleware, redis: :redis, redis_db: 9 do let(:middleware) { SidekiqUniqueJobs::Server::Middleware.new } - let(:queue) { 'working' } + let(:queue) { "working" } - describe '#call' do - describe '#unlock' do - it 'does not unlock keys it does not own' do + describe "#call" do + describe "#unlock" do + it "does not unlock keys it does not own" do jid = UntilExecutedJob.perform_async item = Sidekiq::Queue.new(queue).find_job(jid).item - exists_key = 'uniquejobs:7f28fc7bce5b2f7ea9895080e9b2d282:EXISTS' + exists_key = "uniquejobs:7f28fc7bce5b2f7ea9895080e9b2d282:EXISTS" expect(get_key(exists_key)).to eq(jid) - set_key(exists_key, 'NOT_DELETED') + set_key(exists_key, "NOT_DELETED") middleware.call(UntilExecutedJob.new, item, queue) do - expect(get_key(exists_key)).to eq('NOT_DELETED') + expect(get_key(exists_key)).to eq("NOT_DELETED") end end end - describe ':before_yield' do - it 'removes the lock before yielding to the worker' do + describe ":before_yield" do + it "removes the lock before yielding to the worker" do jid = UntilExecutingJob.perform_async item = Sidekiq::Queue.new(queue).find_job(jid).item worker = UntilExecutingJob.new @@ -37,18 +37,18 @@ end end - describe ':after_yield' do - it 'removes the lock after yielding to the worker' do + describe ":after_yield" do + it "removes the lock after yielding to the worker" do jid = UntilExecutedJob.perform_async item = Sidekiq::Queue.new(queue).find_job(jid).item - middleware.call('UntilExecutedJob', item, queue) do + middleware.call("UntilExecutedJob", item, queue) do # NO OP end unique_keys.each do |key| - next if key.end_with?(':GRABBED') - next if key.end_with?(':EXISTS') + next if key.end_with?(":GRABBED") + next if key.end_with?(":EXISTS") expect(ttl(key)).to eq(5) end diff --git a/spec/integration/sidekiq_unique_jobs/web_spec.rb b/spec/integration/sidekiq_unique_jobs/web_spec.rb index b0aca5d9a..0e43ee4ee 100644 --- a/spec/integration/sidekiq_unique_jobs/web_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/web_spec.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require 'spec_helper' -require 'sidekiq/web' -require 'sidekiq_unique_jobs/web' -require 'rack/test' +require "spec_helper" +require "sidekiq/web" +require "sidekiq_unique_jobs/web" +require "rack/test" RSpec.describe SidekiqUniqueJobs::Web, redis: :redis do include Rack::Test::Methods @@ -16,40 +16,40 @@ def app Sidekiq.redis(&:flushdb) end - let(:digest) { 'uniquejobs:9e9b5ce5d423d3ea470977004b50ff84' } - let(:another_digest) { 'uniquejobs:24c5b03e2d49d765e5dfb2d7c51c5929' } + let(:digest) { "uniquejobs:9e9b5ce5d423d3ea470977004b50ff84" } + let(:another_digest) { "uniquejobs:24c5b03e2d49d765e5dfb2d7c51c5929" } let(:expected_digests) { [digest, another_digest] } - it 'can display digests' do + it "can display digests" do expect(MyUniqueJob.perform_async(1, 2)).not_to eq(nil) expect(MyUniqueJob.perform_async(2, 3)).not_to eq(nil) - get '/unique_digests' + get "/unique_digests" expect(last_response.status).to eq(200) expect(last_response.body).to match("/unique_digests/#{digest}") expect(last_response.body).to match("/unique_digests/#{another_digest}") end - it 'can paginate digests' do + it "can paginate digests" do 110.times do |idx| expect(MyUniqueJob.perform_async(1, idx)).not_to eq(nil) end - get '/unique_digests' + get "/unique_digests" expect(last_response.status).to eq(200) end - it 'can display digest' do + it "can display digest" do expect(MyUniqueJob.perform_async(1, 2)).not_to eq(nil) get "/unique_digests/#{digest}" expect(last_response.status).to eq(200) - expect(last_response.body).to match('uniquejobs:9e9b5ce5d423d3ea470977004b50ff84') - expect(last_response.body).to match('uniquejobs:9e9b5ce5d423d3ea470977004b50ff84:EXISTS') - expect(last_response.body).to match('uniquejobs:9e9b5ce5d423d3ea470977004b50ff84:GRABBED') + expect(last_response.body).to match("uniquejobs:9e9b5ce5d423d3ea470977004b50ff84") + expect(last_response.body).to match("uniquejobs:9e9b5ce5d423d3ea470977004b50ff84:EXISTS") + expect(last_response.body).to match("uniquejobs:9e9b5ce5d423d3ea470977004b50ff84:GRABBED") end - it 'can delete a digest' do + it "can delete a digest" do expect(MyUniqueJob.perform_async(1, 2)).not_to eq(nil) expect(MyUniqueJob.perform_async(2, 3)).not_to eq(nil) @@ -60,7 +60,7 @@ def app follow_redirect! - expect(last_request.url).to end_with('/unique_digests') + expect(last_request.url).to end_with("/unique_digests") expect(last_response.body).not_to match("/unique_digests/#{digest}") expect(last_response.body).to match("/unique_digests/#{another_digest}") diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4a4124e71..d1851d935 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,32 +1,33 @@ # frozen_string_literal: true -if RUBY_ENGINE == 'ruby' && RUBY_VERSION >= '2.5.1' - require 'simplecov' unless %w[false 0].include?(ENV['COV']) +require "bundler/setup" + +if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.5.1" + require "simplecov" unless %w[false 0].include?(ENV["COV"]) begin - require 'pry' - require 'byebug' + require "pry" rescue LoadError - puts 'Pry unavailable' + puts "Pry unavailable" end end -require 'rspec' -require 'rspec/its' -require 'awesome_print' +require "rspec" +require "rspec/its" +require "awesome_print" -require 'sidekiq' -require 'sidekiq/util' -require 'sidekiq-unique-jobs' -require 'timecop' -require 'sidekiq_unique_jobs/testing' +require "sidekiq" +require "sidekiq/util" +require "sidekiq-unique-jobs" +require "timecop" +require "sidekiq_unique_jobs/testing" -Sidekiq.logger = Logger.new('/dev/null') +Sidekiq.logger = Logger.new("/dev/null") SidekiqUniqueJobs.logger.level = Object.const_get("Logger::#{ENV.fetch('LOGLEVEL') { 'error' }.upcase}") -require 'sidekiq/redis_connection' +require "sidekiq/redis_connection" -Dir[File.join(File.dirname(__FILE__), 'support', '**', '*.rb')].each { |f| require f } +Dir[File.join(File.dirname(__FILE__), "support", "**", "*.rb")].each { |f| require f } RSpec.configure do |config| config.define_derived_metadata do |meta| @@ -38,17 +39,17 @@ config.mock_with :rspec do |mocks| mocks.verify_partial_doubles = true end - config.example_status_persistence_file_path = '.rspec_status' - config.filter_run :focus unless ENV['CI'] + config.example_status_persistence_file_path = ".rspec_status" + config.filter_run :focus unless ENV["CI"] config.run_all_when_everything_filtered = true config.disable_monkey_patching! config.warnings = false - config.default_formatter = 'doc' if config.files_to_run.one? + config.default_formatter = "doc" if config.files_to_run.one? config.order = :random Kernel.srand config.seed end -Dir[File.join(File.dirname(__FILE__), '..', 'examples', '**', '*.rb')].each { |f| require f } +Dir[File.join(File.dirname(__FILE__), "..", "examples", "**", "*.rb")].each { |f| require f } def capture(stream) begin diff --git a/spec/support/matchers/redis_matchers.rb b/spec/support/matchers/redis_matchers.rb index 4aa97c632..86378d1e4 100644 --- a/spec/support/matchers/redis_matchers.rb +++ b/spec/support/matchers/redis_matchers.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'rspec/expectations' -require 'rspec/eventually' +require "rspec/expectations" +require "rspec/eventually" RSpec::Matchers.define :be_enqueued_in do |queue| SidekiqUniqueJobs.redis do |conn| @@ -16,7 +16,7 @@ RSpec::Matchers.define :be_scheduled_at do |time| SidekiqUniqueJobs.redis do |conn| - @actual = conn.zcount('schedule', -1, time) + @actual = conn.zcount("schedule", -1, time) match do |count_in_queue| @expected = count_in_queue diff --git a/spec/support/retry.rb b/spec/support/retry.rb index f5d626fb3..ca25db8b4 100644 --- a/spec/support/retry.rb +++ b/spec/support/retry.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'rspec/retry' +require "rspec/retry" RSpec.configure do |config| # show retry status in spec process diff --git a/spec/support/ruby_meta.rb b/spec/support/ruby_meta.rb index c28a653d6..d49d91db4 100644 --- a/spec/support/ruby_meta.rb +++ b/spec/support/ruby_meta.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative 'version_check' +require_relative "version_check" RSpec.configure do |config| config.before do |example| diff --git a/spec/support/shared_examples/a_lockable_lock.rb b/spec/support/shared_examples/a_lockable_lock.rb index 13d609fe7..efa0e8faf 100644 --- a/spec/support/shared_examples/a_lockable_lock.rb +++ b/spec/support/shared_examples/a_lockable_lock.rb @@ -1,60 +1,60 @@ # frozen_string_literal: true -RSpec.shared_examples 'a lock implementation' do - it 'can be locked' do +RSpec.shared_examples "a lock implementation" do + it "can be locked" do expect(process_one.lock).to eq(jid_one) end - context 'when process one has locked the job' do + context "when process one has locked the job" do before { process_one.lock } - it 'has locked process_one' do + it "has locked process_one" do expect(process_one).to be_locked end - it 'prevents process_two from locking' do + it "prevents process_two from locking" do expect(process_two.lock).to eq(nil) end - it 'prevents process_two from executing' do + it "prevents process_two from executing" do expect(process_two.execute {}).to eq(nil) end end end -RSpec.shared_examples 'an executing lock implementation' do - context 'when job has not been locked' do - it 'does not execute' do +RSpec.shared_examples "an executing lock implementation" do + context "when job has not been locked" do + it "does not execute" do unset = true process_one.execute { unset = false } expect(unset).to eq(true) end end - context 'when process_one executes the job' do + context "when process_one executes the job" do before { process_one.lock } - it 'keeps being locked while executing' do + it "keeps being locked while executing" do process_one.execute do expect(process_one).to be_locked end end - it 'keeps being locked when an error is raised' do - expect { process_one.execute { raise 'Hell' } } - .to raise_error('Hell') + it "keeps being locked when an error is raised" do + expect { process_one.execute { raise "Hell" } } + .to raise_error("Hell") expect(process_one).to be_locked end - it 'prevents process_two from locking' do + it "prevents process_two from locking" do process_one.execute do expect(process_two.lock).to eq(nil) expect(process_two).not_to be_locked end end - it 'prevents process_two from executing' do + it "prevents process_two from executing" do process_one.execute do unset = true process_two.execute { unset = false } diff --git a/spec/support/shared_examples/a_performing_worker.rb b/spec/support/shared_examples/a_performing_worker.rb index a2b94bc42..3572bac61 100644 --- a/spec/support/shared_examples/a_performing_worker.rb +++ b/spec/support/shared_examples/a_performing_worker.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true -RSpec.shared_examples 'a performing worker' do |splat_arguments: true| +RSpec.shared_examples "a performing worker" do |splat_arguments: true| let(:worker_instance) { instance_spy(described_class) } before do allow(described_class).to receive(:new).and_return(worker_instance) end - it 'receives the expected arguments' do + it "receives the expected arguments" do SidekiqUniqueJobs.use_config(enabled: false) do Sidekiq::Testing.inline! do if args == no_args diff --git a/spec/support/shared_examples/an_executing_lock_with_error_handling.rb b/spec/support/shared_examples/an_executing_lock_with_error_handling.rb index 599bd59f0..43e2afe7c 100644 --- a/spec/support/shared_examples/an_executing_lock_with_error_handling.rb +++ b/spec/support/shared_examples/an_executing_lock_with_error_handling.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_examples 'an executing lock with error handling' do +RSpec.shared_examples "an executing lock with error handling" do subject(:execute) { lock.execute(&block) } let(:block) { -> {} } @@ -18,12 +18,12 @@ allow(lock).to receive(:log_fatal) end - context 'when yield fails with other errors' do - let(:block) { -> { raise 'HELL' } } + context "when yield fails with other errors" do + let(:block) { -> { raise "HELL" } } let(:locked?) { nil } it 'raises "HELL"' do - expect { execute }.to raise_error('HELL') + expect { execute }.to raise_error("HELL") expect(lock).not_to have_received(:unlock) end diff --git a/spec/support/shared_examples/sidekiq_with_options.rb b/spec/support/shared_examples/sidekiq_with_options.rb index 42ae7deb5..33dfe3dfc 100644 --- a/spec/support/shared_examples/sidekiq_with_options.rb +++ b/spec/support/shared_examples/sidekiq_with_options.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_examples 'sidekiq with options' do +RSpec.shared_examples "sidekiq with options" do subject(:sidekiq_options) { described_class.get_sidekiq_options } it { is_expected.to match(a_hash_including(options)) } diff --git a/spec/support/shared_examples/with_a_stubbed_locksmith.rb b/spec/support/shared_examples/with_a_stubbed_locksmith.rb index 2c73bd185..c3323b0f9 100644 --- a/spec/support/shared_examples/with_a_stubbed_locksmith.rb +++ b/spec/support/shared_examples/with_a_stubbed_locksmith.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_context 'with a stubbed locksmith' do +RSpec.shared_context "with a stubbed locksmith" do let(:locksmith) { instance_double(SidekiqUniqueJobs::Locksmith) } let(:redis_pool) { nil } diff --git a/spec/support/sidekiq_helpers.rb b/spec/support/sidekiq_helpers.rb index 20d7ba477..fbe9052c8 100644 --- a/spec/support/sidekiq_helpers.rb +++ b/spec/support/sidekiq_helpers.rb @@ -4,7 +4,7 @@ module SidekiqHelpers include SidekiqUniqueJobs::Connection def dead_count - zcard('dead') + zcard("dead") end def get_key(key) @@ -32,7 +32,7 @@ def queue_count(queue) end def retry_count - zcard('retry') + zcard("retry") end def scard(queue) @@ -40,11 +40,11 @@ def scard(queue) end def schedule_count - zcard('schedule') + zcard("schedule") end def schedule_count_at(max = Time.now.to_f + 2 * 60) - zcount('schedule', '-inf', max) + zcount("schedule", "-inf", max) end def set_key(key, value) @@ -56,7 +56,7 @@ def ttl(key) end def unique_digests - smembers('unique:keys') + smembers("unique:keys") end def smembers(key) @@ -64,7 +64,7 @@ def smembers(key) end def unique_keys - keys('uniquejobs:*') + keys("uniquejobs:*") end def zadd(queue, timestamp, item) @@ -75,7 +75,7 @@ def zcard(queue) redis { |conn| conn.zcard(queue) } end - def zcount(queue, min = '-inf', max = '+inf') + def zcount(queue, min = "-inf", max = "+inf") redis { |conn| conn.zcount(queue, min, max) } end end diff --git a/spec/support/sidekiq_meta.rb b/spec/support/sidekiq_meta.rb index a122d91e1..c500c3910 100644 --- a/spec/support/sidekiq_meta.rb +++ b/spec/support/sidekiq_meta.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require 'sidekiq/testing' +require "sidekiq/testing" -require_relative 'version_check' +require_relative "version_check" RSpec.configure do |config| config.before(:each, redis: :redis) do |example| diff --git a/spec/support/version_check.rb b/spec/support/version_check.rb index c1da3c14e..456a7c606 100644 --- a/spec/support/version_check.rb +++ b/spec/support/version_check.rb @@ -13,8 +13,8 @@ def initialize(version, constraint) @operator2 = match[:operator2] end - fail ArgumentError, 'A version (5.0) is required to compare against' unless @version - fail ArgumentError, 'At least one operator and version is required (<>= 5.1)' unless @operator1 + raise ArgumentError, "A version (5.0) is required to compare against" unless @version + raise ArgumentError, "At least one operator and version is required (<>= 5.1)" unless @operator1 end def invalid? diff --git a/spec/unit/sidekiq_unique_jobs/cli_spec.rb b/spec/unit/sidekiq_unique_jobs/cli_spec.rb index 353ecfe4e..32ca0c34b 100644 --- a/spec/unit/sidekiq_unique_jobs/cli_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/cli_spec.rb @@ -1,26 +1,26 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" -require 'thor/runner' -require 'irb' +require "thor/runner" +require "irb" -RSpec.describe SidekiqUniqueJobs::Cli, redis: :redis, ruby_ver: '>= 2.4' do +RSpec.describe SidekiqUniqueJobs::Cli, redis: :redis, ruby_ver: ">= 2.4" do let(:item) do { - 'jid' => jid, - 'unique_digest' => unique_key, + "jid" => jid, + "unique_digest" => unique_key, } end - let(:jid) { 'abcdefab' } - let(:unique_key) { 'uniquejobs:abcdefab' } + let(:jid) { "abcdefab" } + let(:unique_key) { "uniquejobs:abcdefab" } let(:max_lock_time) { 1 } - let(:pattern) { '*' } + let(:pattern) { "*" } - describe '#help' do + describe "#help" do subject(:help) { capture(:stdout) { described_class.start(%w[help]) } } - it 'displays help' do + it "displays help" do expect(help).to include <<~HEADER Commands: jobs console # drop into a console with easy access to helper methods @@ -30,10 +30,10 @@ HEADER end - describe '#help del' do + describe "#help del" do subject(:help) { capture(:stdout) { described_class.start(%w[help del]) } } - it 'displays help about the `del` command' do + it "displays help about the `del` command" do expect(help).to eq <<~HEADER Usage: jobs del PATTERN @@ -48,10 +48,10 @@ end end - describe '#help keys' do + describe "#help keys" do subject(:help) { capture(:stdout) { described_class.start(%w[help keys]) } } - it 'displays help about the `key` command' do + it "displays help about the `key` command" do expect(help).to eq <<~HEADER Usage: jobs keys PATTERN @@ -66,27 +66,27 @@ end end - describe '.keys' do + describe ".keys" do subject(:keys) { capture(:stdout) { described_class.start(%w[keys * --count 1000]) } } - context 'when no keys exist' do + context "when no keys exist" do it { is_expected.to eq("Found 0 keys matching '#{pattern}':\n") } end - context 'when a key exists' do + context "when a key exists" do before do SidekiqUniqueJobs::Locksmith.new(item).lock end - after { SidekiqUniqueJobs::Util.del('*', 1000) } + after { SidekiqUniqueJobs::Util.del("*", 1000) } it { is_expected.to include("Found 2 keys matching '*':") } - it { is_expected.to include('uniquejobs:abcdefab:EXISTS') } - it { is_expected.to include('uniquejobs:abcdefab:GRABBED') } + it { is_expected.to include("uniquejobs:abcdefab:EXISTS") } + it { is_expected.to include("uniquejobs:abcdefab:GRABBED") } end end - describe '.del' do + describe ".del" do subject(:del) { capture(:stdout) { described_class.start(args) } } let(:args) { %W[del * #{options} --count 1000] } @@ -95,8 +95,8 @@ SidekiqUniqueJobs::Locksmith.new(item).lock end - context 'with argument --dry-run' do - let(:options) { '--dry-run' } + context "with argument --dry-run" do + let(:options) { "--dry-run" } specify do expect(del).to eq("Would delete 2 keys matching '*'\n") @@ -104,8 +104,8 @@ end end - context 'with argument --no-dry-run' do - let(:options) { '--no-dry-run' } + context "with argument --no-dry-run" do + let(:options) { "--no-dry-run" } specify do expect(del).to eq("Deleted 2 keys matching '*'\n") @@ -114,7 +114,7 @@ end end - describe '.console', ruby_ver: '>= 2.5.1' do + describe ".console", ruby_ver: ">= 2.5.1" do subject(:console) { capture(:stdout) { described_class.start(%w[console]) } } specify do diff --git a/spec/unit/sidekiq_unique_jobs/client/middleware_spec.rb b/spec/unit/sidekiq_unique_jobs/client/middleware_spec.rb index b14584ed4..3b4a039ad 100644 --- a/spec/unit/sidekiq_unique_jobs/client/middleware_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/client/middleware_spec.rb @@ -1,44 +1,44 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" -require 'sidekiq/worker' -require 'sidekiq-unique-jobs' +require "sidekiq/worker" +require "sidekiq-unique-jobs" # rubocop:disable RSpec/InstanceVariable RSpec.describe SidekiqUniqueJobs::Client::Middleware do let(:middleware) { described_class.new } - describe '#call' do + describe "#call" do subject(:call) { middleware.call(worker_class, item, queue, &block) } let(:block) { -> { @inside_block_value = true } } let(:worker_class) { SimpleWorker } - let(:queue) { 'default' } + let(:queue) { "default" } let(:item) do - { 'class' => SimpleWorker, - 'queue' => queue, - 'args' => [1] } + { "class" => SimpleWorker, + "queue" => queue, + "args" => [1] } end before { @inside_block_value = false } - context 'when locking succeeds' do + context "when locking succeeds" do before do allow(middleware).to receive(:locked?).and_return(true) end - it 'yields control' do + it "yields control" do expect { call }.to change { @inside_block_value }.to(true) end end - context 'when already locked' do + context "when already locked" do before do allow(middleware).to receive(:locked?).and_return(false) end - it 'does not yield control' do + it "does not yield control" do expect { call }.not_to change { @inside_block_value }.from(false) end end diff --git a/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb b/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb index 3305c2ff4..c98da3de1 100644 --- a/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb @@ -1,29 +1,29 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" -RSpec.describe 'core_ext.rb' do +RSpec.describe "core_ext.rb" do describe Hash do let(:hash) { { test: :me, not: :me } } - describe '#slice' do + describe "#slice" do specify { expect(hash.slice(:test)).to eq(test: :me) } end - describe '#slice!' do + describe "#slice!" do specify { expect { hash.slice!(:test) }.to change { hash }.to(test: :me) } end - describe '#stringify_keys' do + describe "#stringify_keys" do subject(:stringify_keys) { hash.stringify_keys } - it { is_expected.to eq('test' => :me, 'not' => :me) } + it { is_expected.to eq("test" => :me, "not" => :me) } end - describe '#transform_keys' do + describe "#transform_keys" do subject(:transform_keys) { hash.transform_keys(&:to_s) } - it { is_expected.to eq('test' => :me, 'not' => :me) } + it { is_expected.to eq("test" => :me, "not" => :me) } end end @@ -31,16 +31,16 @@ let(:array) { [1, 2, nil, last_argument] } let(:last_argument) { Object.new } - describe '#extract_options!' do + describe "#extract_options!" do subject(:extract_options!) { array.extract_options! } - context 'when last argument is a hash' do + context "when last argument is a hash" do let(:last_argument) { { test: :me, not: :me } } it { is_expected.to eq(last_argument) } end - context 'when last argument is not a hash' do + context "when last argument is not a hash" do let(:last_argument) { nil } it { is_expected.to eq({}) } diff --git a/spec/unit/sidekiq_unique_jobs/digests_spec.rb b/spec/unit/sidekiq_unique_jobs/digests_spec.rb index e68cf4ca3..0329b78e8 100644 --- a/spec/unit/sidekiq_unique_jobs/digests_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/digests_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Digests, redis: :redis do before do @@ -24,13 +24,13 @@ ] end - describe '.all' do - subject(:all) { described_class.all(pattern: '*', count: 1000) } + describe ".all" do + subject(:all) { described_class.all(pattern: "*", count: 1000) } it { is_expected.to match_array(expected_keys) } end - describe '.del' do + describe ".del" do subject(:del) { described_class.del(digest: digest, pattern: pattern, count: count) } let(:digest) { nil } @@ -41,33 +41,33 @@ allow(described_class).to receive(:log_info) end - context 'when given a pattern' do - let(:pattern) { '*' } + context "when given a pattern" do + let(:pattern) { "*" } - it 'deletes all matching digests' do + it "deletes all matching digests" do expect(del).to eq(10) expect(described_class.all).to match_array([]) end - it 'logs performance info' do + it "logs performance info" do del expect(described_class) .to have_received(:log_info).with( - a_string_starting_with('delete_by_pattern(*, count: 1000)') + a_string_starting_with("delete_by_pattern(*, count: 1000)") .and(matching(/completed in (\d\.\d+)ms/)), ) end end - context 'when given a digest' do + context "when given a digest" do let(:digest) { expected_keys.last } - it 'deletes just the specific digest' do + it "deletes just the specific digest" do expect(del).to eq(9) expect(described_class.all).to match_array(expected_keys - [digest]) end - it 'logs performance info' do + it "logs performance info" do del expect(described_class).to have_received(:log_info) .with( diff --git a/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb index 02246790a..abcbd0e81 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::BaseLock do - include_context 'with a stubbed locksmith' - let(:lock) { described_class.new(item, callback) } - let(:callback) { -> {} } - let(:unique_digest) { 'woohoounique' } + include_context "with a stubbed locksmith" + let(:lock) { described_class.new(item, callback) } + let(:callback) { -> {} } + let(:unique_digest) { "woohoounique" } let(:item) do { - 'jid' => 'maaaahjid', - 'queue' => 'default', - 'class' => 'UntilExecutedJob', - 'lock' => :until_executed, - 'args' => [1], + "jid" => "maaaahjid", + "queue" => "default", + "class" => "UntilExecutedJob", + "lock" => :until_executed, + "args" => [1], } end @@ -23,30 +23,30 @@ def execute end end - describe '#lock' do + describe "#lock" do subject(:lock_lock) { lock.lock } - context 'when already locked?' do + context "when already locked?" do before do allow(lock).to receive(:locked?).and_return(true) end - it { is_expected.to eq('maaaahjid') } + it { is_expected.to eq("maaaahjid") } end - context 'when not locked?' do + context "when not locked?" do before do allow(lock).to receive(:locked?).and_return(false) allow(locksmith).to receive(:lock).with(kind_of(Integer)).and_return(token) end - context 'when a token is retrieved' do - let(:token) { 'another jid' } + context "when a token is retrieved" do + let(:token) { "another jid" } - it { is_expected.to eq('another jid') } + it { is_expected.to eq("another jid") } end - context 'when token is not retrieved' do + context "when token is not retrieved" do let(:token) { nil } it { is_expected.to eq(nil) } @@ -54,55 +54,55 @@ def execute end end - describe '#execute' do + describe "#execute" do it do expect { lock.execute } .to raise_error(NotImplementedError, "#execute needs to be implemented in #{described_class}") end - context 'when an implementation raises Sidekiq::Shutdown while excuting' do + context "when an implementation raises Sidekiq::Shutdown while excuting" do let(:lock) { FailedExecutingLock.new(item, callback) } it do allow(lock).to receive(:unlock_with_callback) allow(lock).to receive(:log_info) - expect { lock.execute { raise Sidekiq::Shutdown, 'boohoo' } } - .to raise_error(Sidekiq::Shutdown, 'boohoo') + expect { lock.execute { raise Sidekiq::Shutdown, "boohoo" } } + .to raise_error(Sidekiq::Shutdown, "boohoo") expect(lock).not_to have_received(:unlock_with_callback) expect(lock).to have_received(:log_info) - .with('Sidekiq is shutting down, the job `should` be put back on the queue. Keeping the lock!') + .with("Sidekiq is shutting down, the job `should` be put back on the queue. Keeping the lock!") end end end - describe '#unlock' do + describe "#unlock" do subject(:unlock) { lock.unlock } before do - allow(locksmith).to receive(:unlock).with(item['jid']).and_return('unlocked') + allow(locksmith).to receive(:unlock).with(item["jid"]).and_return("unlocked") end - it { is_expected.to eq('unlocked') } + it { is_expected.to eq("unlocked") } end - describe '#delete' do + describe "#delete" do subject { lock.delete } - before { allow(locksmith).to receive(:delete).and_return('deleted') } + before { allow(locksmith).to receive(:delete).and_return("deleted") } - it { is_expected.to eq('deleted') } + it { is_expected.to eq("deleted") } end - describe '#delete!' do + describe "#delete!" do subject { lock.delete! } - before { allow(locksmith).to receive(:delete!).and_return('deleted') } + before { allow(locksmith).to receive(:delete!).and_return("deleted") } - it { is_expected.to eq('deleted') } + it { is_expected.to eq("deleted") } end - describe '#locked?' do + describe "#locked?" do it do allow(locksmith).to receive(:locked?).and_return(true) diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb index 7d9768445..73213c70c 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb @@ -1,21 +1,21 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilAndWhileExecuting do - include_context 'with a stubbed locksmith' + include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } let(:callback) { -> {} } let(:item) do { - 'jid' => 'maaaahjid', - 'class' => 'UntilAndWhileExecutingJob', - 'lock' => 'until_and_while_executing', - 'args' => ['one'], + "jid" => "maaaahjid", + "class" => "UntilAndWhileExecutingJob", + "lock" => "until_and_while_executing", + "args" => ["one"], } end - describe '#execute' do + describe "#execute" do let(:runtime_lock) { instance_spy(SidekiqUniqueJobs::Lock::WhileExecuting) } before do @@ -25,10 +25,10 @@ allow(runtime_lock).to receive(:execute).and_yield end - context 'when locked?' do + context "when locked?" do let(:locked?) { true } - it 'unlocks the unique key before yielding' do + it "unlocks the unique key before yielding" do inside_block_value = false lock.execute { inside_block_value = true } @@ -40,10 +40,10 @@ end end - context 'when not locked?' do + context "when not locked?" do let(:locked?) { false } - it 'unlocks the unique key before yielding' do + it "unlocks the unique key before yielding" do inside_block_value = false lock.execute { inside_block_value = true } expect(inside_block_value).to eq(false) @@ -55,12 +55,12 @@ end end - describe '#runtime_lock' do + describe "#runtime_lock" do subject(:runtime_lock) { lock.runtime_lock } it { is_expected.to be_a(SidekiqUniqueJobs::Lock::WhileExecuting) } - it 'initializes with the right arguments' do + it "initializes with the right arguments" do allow(SidekiqUniqueJobs::Lock::WhileExecuting).to receive(:new) runtime_lock diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb index 0a31eb379..f3b7121b9 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb @@ -1,26 +1,26 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuted do - include_context 'with a stubbed locksmith' + include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } let(:callback) { -> {} } let(:item) do { - 'jid' => 'maaaahjid', - 'class' => 'UntilExecutedJob', - 'lock' => 'until_executed', - 'args' => %w[one two], + "jid" => "maaaahjid", + "class" => "UntilExecutedJob", + "lock" => "until_executed", + "args" => %w[one two], } end - describe '#execute' do - it_behaves_like 'an executing lock with error handling' do - context 'when not initially locked?' do + describe "#execute" do + it_behaves_like "an executing lock with error handling" do + context "when not initially locked?" do let(:initially_locked?) { false } - it 'returns without yielding' do + it "returns without yielding" do execute expect(callback).not_to have_received(:call) @@ -28,26 +28,26 @@ end end - context 'when lock is not locked?' do - let(:block) { -> { raise 'HELL' } } + context "when lock is not locked?" do + let(:block) { -> { raise "HELL" } } let(:locked?) { nil } - it 'calls back' do - expect { execute }.to raise_error('HELL') + it "calls back" do + expect { execute }.to raise_error("HELL") expect(callback).not_to have_received(:call) end end - context 'when callback raises error' do - let(:callback) { -> { raise 'CallbackError' } } + context "when callback raises error" do + let(:callback) { -> { raise "CallbackError" } } let(:locked?) { false } - it 'logs a warning' do - expect { execute }.to raise_error('CallbackError') + it "logs a warning" do + expect { execute }.to raise_error("CallbackError") expect(lock).to have_received(:log_warn) - .with('unlocked successfully but the #after_unlock callback failed!') + .with("unlocked successfully but the #after_unlock callback failed!") end end end diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb index 6ce207c3a..1d76c678c 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuting do - include_context 'with a stubbed locksmith' + include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } let(:callback) { -> {} } let(:item) do - { 'jid' => 'maaaahjid', - 'class' => 'UntilExpiredJob', - 'lock' => 'until_timeout' } + { "jid" => "maaaahjid", + "class" => "UntilExpiredJob", + "lock" => "until_timeout" } end - describe '#execute' do - it 'calls the callback' do + describe "#execute" do + it "calls the callback" do allow(lock).to receive(:unlock_with_callback) expect { |block| lock.execute(&block) }.to yield_control diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb index 991d32929..d9d27d6b1 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb @@ -1,28 +1,28 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExpired do - include_context 'with a stubbed locksmith' + include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } let(:callback) { -> {} } let(:item) do - { 'jid' => 'maaaahjid', - 'class' => 'UntilExpiredJob', - 'lock' => 'until_timeout' } + { "jid" => "maaaahjid", + "class" => "UntilExpiredJob", + "lock" => "until_timeout" } end before do allow(callback).to receive(:call) end - describe '#unlock' do + describe "#unlock" do subject(:unlock) { lock.unlock } it { is_expected.to eq(true) } end - describe '#execute' do + describe "#execute" do subject(:execute) { lock.execute(&block) } let(:locked?) { false } @@ -31,16 +31,16 @@ allow(lock).to receive(:locked?).and_return(locked?) end - context 'when locked?' do + context "when locked?" do let(:locked?) { true } - it 'yields to caller' do + it "yields to caller" do expect { |block| lock.execute(&block) }.to yield_control end end - context 'when not locked?' do - it 'does not yield to caller' do + context "when not locked?" do + it "does not yield to caller" do expect { |block| lock.execute(&block) }.not_to yield_control end end diff --git a/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb index 0fb93fec0..be1689dbf 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb @@ -1,29 +1,29 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecutingReject do - include_context 'with a stubbed locksmith' + include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } let(:callback) { -> {} } let(:item) do - { 'jid' => 'maaaahjid', - 'class' => 'WhileExecutingRejectJob', - 'lock' => 'while_executing_reject', - 'args' => [%w[array of arguments]] } + { "jid" => "maaaahjid", + "class" => "WhileExecutingRejectJob", + "lock" => "while_executing_reject", + "args" => [%w[array of arguments]] } end before do allow(lock).to receive(:unlock) end - describe '#lock' do + describe "#lock" do subject { lock.lock } it { is_expected.to eq(true) } end - describe '#execute' do + describe "#execute" do subject(:execute) { lock.execute {} } let(:token) { nil } @@ -33,19 +33,19 @@ allow(lock).to receive(:with_cleanup).and_yield end - context 'when lock succeeds' do - let(:token) { 'a token' } + context "when lock succeeds" do + let(:token) { "a token" } - it 'processes the job' do + it "processes the job" do execute expect(lock).to have_received(:with_cleanup) end end - context 'when lock fails' do + context "when lock fails" do let(:token) { nil } - it 'rejects the job' do + it "rejects the job" do execute expect(lock).not_to have_received(:with_cleanup) diff --git a/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb index 4246d14fb..cad705984 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb @@ -1,34 +1,34 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting do - include_context 'with a stubbed locksmith' + include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } let(:callback) { -> {} } let(:item) do - { 'jid' => 'maaaahjid', - 'class' => 'WhileExecutingJob', - 'lock' => 'while_executing', - 'args' => [%w[array of arguments]] } + { "jid" => "maaaahjid", + "class" => "WhileExecutingJob", + "lock" => "while_executing", + "args" => [%w[array of arguments]] } end - describe '.new' do + describe ".new" do specify do expect { described_class.new(item, callback) } - .to change { item['unique_digest'] } - .to a_string_ending_with(':RUN') + .to change { item["unique_digest"] } + .to a_string_ending_with(":RUN") end end - describe '#lock' do + describe "#lock" do subject { lock.lock } it { is_expected.to eq(true) } end - describe '#execute' do + describe "#execute" do subject(:execute) { lock.execute } before do @@ -41,7 +41,7 @@ # it_behaves_like 'an executing lock with error handling' # end - context 'when lock fails' do + context "when lock fails" do let(:token) { nil } it do diff --git a/spec/unit/sidekiq_unique_jobs/middleware_spec.rb b/spec/unit/sidekiq_unique_jobs/middleware_spec.rb index 82cb16d73..27a17982a 100644 --- a/spec/unit/sidekiq_unique_jobs/middleware_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/middleware_spec.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Middleware do describe SidekiqUniqueJobs do - describe '.configure_middleware' do - it 'configures both client and server middleware' do + describe ".configure_middleware" do + it "configures both client and server middleware" do expect(described_class).to receive(:configure_server_middleware) expect(described_class).to receive(:configure_client_middleware) @@ -13,12 +13,12 @@ end end - describe '.configure_server_middleware' do - let(:server_config) { class_double(Sidekiq) } + describe ".configure_server_middleware" do + let(:server_config) { class_double(Sidekiq) } let(:server_middleware) { instance_double(Sidekiq::Middleware::Chain) } let(:client_middleware) { instance_double(Sidekiq::Middleware::Chain) } - it 'adds client and server middleware when required' do + it "adds client and server middleware when required" do expect(Sidekiq).to receive(:configure_server).and_yield(server_config) expect(server_config).to receive(:client_middleware).and_yield(client_middleware) @@ -30,11 +30,11 @@ end end - describe '.configure_client_middleware' do + describe ".configure_client_middleware" do let(:client_config) { class_double(Sidekiq) } let(:client_middleware) { instance_double(Sidekiq::Middleware::Chain) } - it 'adds client middleware when required' do + it "adds client middleware when required" do expect(Sidekiq).to receive(:configure_client).and_yield(client_config) expect(client_config).to receive(:client_middleware).and_yield(client_middleware) expect(client_middleware).to receive(:add).with(SidekiqUniqueJobs::Client::Middleware) diff --git a/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb b/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb index f98bf8dee..937f3eabf 100644 --- a/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb @@ -1,18 +1,18 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Normalizer do - describe '.jsonify' do + describe ".jsonify" do specify do original = [1, :test, [test: :test]] - expected = [1, 'test', ['test' => 'test']] + expected = [1, "test", ["test" => "test"]] expect(described_class.jsonify(original)).to eq(expected) end specify do original = [1, :test, [test: [test: :test]]] - expected = [1, 'test', ['test' => ['test' => 'test']]] + expected = [1, "test", ["test" => ["test" => "test"]]] expect(described_class.jsonify(original)).to eq(expected) end end diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb index 8457b5702..c2527454a 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb @@ -1,16 +1,16 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Log do let(:strategy) { described_class.new(item) } - let(:unique_digest) { 'uniquejobs:random-digest-value' } - let(:jid) { 'arandomjid' } + let(:unique_digest) { "uniquejobs:random-digest-value" } + let(:jid) { "arandomjid" } let(:item) do - { 'unique_digest' => unique_digest, 'jid' => jid } + { "unique_digest" => unique_digest, "jid" => jid } end - describe '#call' do + describe "#call" do it do allow(strategy).to receive(:log_info) strategy.call @@ -20,7 +20,7 @@ end end - describe '#replace?' do + describe "#replace?" do subject { strategy.replace? } it { is_expected.to eq(false) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb index e5d1f5089..63d010ecd 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb @@ -1,26 +1,26 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Raise do let(:strategy) { described_class.new(item) } - let(:unique_digest) { 'uniquejobs:random-digest-value' } + let(:unique_digest) { "uniquejobs:random-digest-value" } let(:item) do - { 'unique_digest' => unique_digest } + { "unique_digest" => unique_digest } end - describe '#call' do + describe "#call" do let(:call) { strategy.call } it do expect { call }.to raise_error( SidekiqUniqueJobs::Conflict, - 'Item with the key: uniquejobs:random-digest-value is already scheduled or processing', + "Item with the key: uniquejobs:random-digest-value is already scheduled or processing", ) end end - describe '#replace?' do + describe "#replace?" do subject { strategy.replace? } it { is_expected.to eq(false) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb index f97871ed4..ee0dc6b7e 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Reject do - include_context 'with a stubbed locksmith' + include_context "with a stubbed locksmith" let(:strategy) { described_class.new(item) } let(:deadset) { instance_spy(Sidekiq::DeadSet) } - let(:payload) { instance_spy('payload') } + let(:payload) { instance_spy("payload") } let(:item) do - { 'jid' => 'maaaahjid', - 'class' => 'WhileExecutingRejectJob', - 'lock' => 'while_executing_reject', - 'args' => [%w[array of arguments]] } + { "jid" => "maaaahjid", + "class" => "WhileExecutingRejectJob", + "lock" => "while_executing_reject", + "args" => [%w[array of arguments]] } end before do @@ -19,69 +19,69 @@ allow(strategy).to receive(:payload).and_return(payload) end - describe '#replace?' do + describe "#replace?" do subject { strategy.replace? } it { is_expected.to eq(false) } end - describe '#send_to_deadset' do + describe "#send_to_deadset" do subject(:send_to_deadset) { strategy.send_to_deadset } - context 'when deadset_kill?' do + context "when deadset_kill?" do before { allow(strategy).to receive(:deadset_kill?).and_return(true) } - it 'calls deadset_kill' do + it "calls deadset_kill" do expect(strategy).to receive(:deadset_kill) send_to_deadset end end - context 'when not deadset_kill?' do + context "when not deadset_kill?" do before { allow(strategy).to receive(:deadset_kill?).and_return(false) } - it 'calls push_to_deadset' do + it "calls push_to_deadset" do expect(strategy).to receive(:push_to_deadset) send_to_deadset end end end - describe '#deadset_kill' do + describe "#deadset_kill" do subject(:deadset_kill) { strategy.deadset_kill } - context 'when kill_with_options?' do + context "when kill_with_options?" do before { allow(strategy).to receive(:kill_with_options?).and_return(true) } - it 'calls kill_job_with_options' do + it "calls kill_job_with_options" do expect(strategy).to receive(:kill_job_with_options) deadset_kill end end - context 'when not kill_with_options?' do + context "when not kill_with_options?" do before { allow(strategy).to receive(:kill_with_options?).and_return(false) } - it 'calls kill_job_without_options' do + it "calls kill_job_without_options" do expect(strategy).to receive(:kill_job_without_options) deadset_kill end end end - describe '#kill_job_with_options' do + describe "#kill_job_with_options" do subject(:kill_job_with_options) { strategy.kill_job_with_options } - it 'calls deadset.kill with options hash', sidekiq_ver: '>= 5.1.0' do + it "calls deadset.kill with options hash", sidekiq_ver: ">= 5.1.0" do expect(deadset).to receive(:kill).with(payload, notify_failure: false) kill_job_with_options end end - describe '#kill_job_without_options' do + describe "#kill_job_without_options" do subject(:kill_job_without_options) { strategy.kill_job_without_options } - it 'calls deadset.kill without options hash', sidekiq_ver: '>= 5.0.0 && < 5.1.0' do + it "calls deadset.kill without options hash", sidekiq_ver: ">= 5.0.0 && < 5.1.0" do expect(deadset).to receive(:kill).with(payload) kill_job_without_options end diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb index 2f0694a40..d30330104 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb @@ -1,18 +1,18 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Replace, redis: :redis do let(:strategy) { described_class.new(item) } - let(:unique_digest) { 'uniquejobs:56c68cab5038eb57959538866377560d' } - let(:block) { -> { p 'Hello' } } + let(:unique_digest) { "uniquejobs:56c68cab5038eb57959538866377560d" } + let(:block) { -> { p "Hello" } } let(:digest) { SidekiqUniqueJobs::Digests.all.first } let(:item) do - { 'unique_digest' => unique_digest, 'queue' => :customqueue } + { "unique_digest" => unique_digest, "queue" => :customqueue } end - describe '#call' do + describe "#call" do subject(:call) { strategy.call(&block) } before do @@ -21,53 +21,53 @@ allow(block).to receive(:call) end - context 'when job is retried' do - let(:jid) { 'abcdefab' } + context "when job is retried" do + let(:jid) { "abcdefab" } let(:job) { Sidekiq.dump_json(item) } let(:item) do { - 'class' => 'MyUniqueJob', - 'args' => [1, 2], - 'queue' => 'customqueue', - 'jid' => jid, - 'retry_count' => 2, - 'failed_at' => Time.now.to_f, - 'unique_digest' => unique_digest, + "class" => "MyUniqueJob", + "args" => [1, 2], + "queue" => "customqueue", + "jid" => jid, + "retry_count" => 2, + "failed_at" => Time.now.to_f, + "unique_digest" => unique_digest, } end before do Sidekiq.redis do |conn| - conn.zadd('retry', Time.now.to_f.to_s, job) + conn.zadd("retry", Time.now.to_f.to_s, job) end end - it 'removes the job from the retry set' do + it "removes the job from the retry set" do expect { call }.to change { retry_count }.from(1).to(0) expect(block).to have_received(:call) end end - context 'when job is scheduled' do + context "when job is scheduled" do let(:jid) { MyUniqueJob.perform_in(2000, 1, 1) } - it 'removes the job from the scheduled set' do + it "removes the job from the scheduled set" do expect { call }.to change { schedule_count }.from(1).to(0) expect(block).to have_received(:call) end end - context 'when job is enqueued' do + context "when job is enqueued" do let(:jid) { MyUniqueJob.perform_async(1, 1) } - it 'removes the job from the queue' do + it "removes the job from the queue" do expect { call }.to change { queue_count(:customqueue) }.from(1).to(0) expect(block).to have_received(:call) end end end - describe '#replace?' do + describe "#replace?" do subject { strategy.replace? } it { is_expected.to eq(true) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb index ac0bc6b5c..2b02d8d8a 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Reschedule do let(:strategy) { described_class.new(item) } - let(:unique_digest) { 'uniquejobs:random-digest-value' } + let(:unique_digest) { "uniquejobs:random-digest-value" } let(:item) do - { 'class' => UniqueJobOnConflictReschedule, - 'unique_digest' => unique_digest, - 'args' => [1, 2] } + { "class" => UniqueJobOnConflictReschedule, + "unique_digest" => unique_digest, + "args" => [1, 2] } end - describe '#call' do + describe "#call" do let(:call) { strategy.call } it do @@ -19,7 +19,7 @@ end end - describe '#replace?' do + describe "#replace?" do subject { strategy.replace? } it { is_expected.to eq(false) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb index f7f99dfac..53c2311f3 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb @@ -1,29 +1,29 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Strategy, redis: :redis do let(:strategy) { described_class.new(item) } - let(:unique_digest) { 'uniquejobs:56c68cab5038eb57959538866377560d' } + let(:unique_digest) { "uniquejobs:56c68cab5038eb57959538866377560d" } let(:item) do - { 'unique_digest' => unique_digest, 'queue' => :customqueue } + { "unique_digest" => unique_digest, "queue" => :customqueue } end - describe '#replace?' do + describe "#replace?" do subject { strategy.replace? } it { is_expected.to eq(false) } end - describe '#call' do + describe "#call" do let(:call) { strategy.call } - it 'raises an error' do - expect { call }.to raise_error(NotImplementedError, 'needs to be implemented in child class') + it "raises an error" do + expect { call }.to raise_error(NotImplementedError, "needs to be implemented in child class") end end - describe '#replace?' do + describe "#replace?" do subject { strategy.replace? } it { is_expected.to eq(false) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb index 354897774..438f3ed6d 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict do - describe '::STRAGEGIES' do + describe "::STRAGEGIES" do subject { described_class::STRATEGIES } let(:expected) do diff --git a/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb b/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb index 8dc5dc799..3c1e0dbf4 100644 --- a/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OptionsWithFallback do class ClassWithOptions @@ -16,24 +16,24 @@ def initialize(item, options, worker_class = nil) end let(:options_with_fallback) { ClassWithOptions.new(item, options, worker_class) } let(:options) { nil } - let(:worker_class) { 'UntilExecutedJob' } - let(:queue) { 'default' } - let(:jid) { 'maaaahjid' } + let(:worker_class) { "UntilExecutedJob" } + let(:queue) { "default" } + let(:jid) { "maaaahjid" } let(:unique) { :until_executed } let(:args) { [1] } let(:log_duplicate_payload) { false } let(:item) do { - 'jid' => jid, - 'queue' => queue, - 'class' => worker_class, - 'lock' => unique, - 'args' => args, - 'log_duplicate_payload' => log_duplicate_payload, + "jid" => jid, + "queue" => queue, + "class" => worker_class, + "lock" => unique, + "args" => args, + "log_duplicate_payload" => log_duplicate_payload, } end - describe '#unique_enabled?' do + describe "#unique_enabled?" do subject { options_with_fallback.unique_enabled? } let(:options) { {} } @@ -42,12 +42,12 @@ def initialize(item, options, worker_class = nil) it { is_expected.to eq(nil) } context 'when options["unique"] is present' do - let(:options) { { 'lock' => 'while_executing' } } - let(:item) { { 'lock' => 'until_executed' } } + let(:options) { { "lock" => "while_executing" } } + let(:item) { { "lock" => "until_executed" } } - it { is_expected.to eq('while_executing') } + it { is_expected.to eq("while_executing") } - context 'when SidekiqUniqueJobs.config.enabled = false' do + context "when SidekiqUniqueJobs.config.enabled = false" do before { SidekiqUniqueJobs.config.enabled = false } after { SidekiqUniqueJobs.config.enabled = true } @@ -57,11 +57,11 @@ def initialize(item, options, worker_class = nil) end context 'when item["unique"] is present' do - let(:item) { { 'lock' => 'until_executed' } } + let(:item) { { "lock" => "until_executed" } } - it { is_expected.to eq('until_executed') } + it { is_expected.to eq("until_executed") } - context 'when SidekiqUniqueJobs.config.enabled = false' do + context "when SidekiqUniqueJobs.config.enabled = false" do before { SidekiqUniqueJobs.config.enabled = false } after { SidekiqUniqueJobs.config.enabled = true } @@ -71,7 +71,7 @@ def initialize(item, options, worker_class = nil) end end - describe '#unique_disabled?' do + describe "#unique_disabled?" do subject { options_with_fallback.unique_disabled? } let(:options) { {} } @@ -80,25 +80,25 @@ def initialize(item, options, worker_class = nil) it { is_expected.to be_truthy } context 'when options["unique"] is present' do - let(:options) { { 'lock' => 'while_executing' } } - let(:item) { { 'lock' => 'until_executed' } } + let(:options) { { "lock" => "while_executing" } } + let(:item) { { "lock" => "until_executed" } } it { is_expected.to be_falsey } end context 'when item["unique"] is present' do let(:options) { {} } - let(:item) { { 'lock' => 'until_executed' } } + let(:item) { { "lock" => "until_executed" } } it { is_expected.to be_falsey } end end - describe '#log_duplicate_payload?' do + describe "#log_duplicate_payload?" do subject(:log_duplicate_payload?) { options_with_fallback.log_duplicate_payload? } context 'when options["log_duplicate_payload"] is true' do - let(:options) { { 'log_duplicate_payload' => true } } + let(:options) { { "log_duplicate_payload" => true } } it { is_expected.to eq(true) } end @@ -110,7 +110,7 @@ def initialize(item, options, worker_class = nil) end end - describe '#lock' do + describe "#lock" do subject(:lock) { options_with_fallback.lock } context 'when item["unique"] is present' do @@ -119,69 +119,69 @@ def initialize(item, options, worker_class = nil) it { is_expected.to be_a(SidekiqUniqueJobs::Lock::UntilExecuted) } context 'when options["unique"] is present' do - let(:options) { { 'lock' => :while_executing } } + let(:options) { { "lock" => :while_executing } } it { is_expected.to be_a(SidekiqUniqueJobs::Lock::WhileExecuting) } end end end - describe '#lock_class' do + describe "#lock_class" do subject(:lock_class) { options_with_fallback.lock_class } context 'when item["unique"] is present' do - let(:item) { { 'lock' => :until_executed } } + let(:item) { { "lock" => :until_executed } } it { is_expected.to eq(SidekiqUniqueJobs::Lock::UntilExecuted) } context 'when options["unique"] is present' do - let(:options) { { 'lock' => :while_executing } } + let(:options) { { "lock" => :while_executing } } it { is_expected.to eq(SidekiqUniqueJobs::Lock::WhileExecuting) } end end - context 'without matching class in LOCKS' do - let(:item) { { 'lock' => :until_unknown } } + context "without matching class in LOCKS" do + let(:item) { { "lock" => :until_unknown } } it do expect { lock_class } .to raise_error(SidekiqUniqueJobs::UnknownLock, - 'No implementation for `lock: :until_unknown`') + "No implementation for `lock: :until_unknown`") end end end - describe '#lock_type' do + describe "#lock_type" do subject { options_with_fallback.lock_type } context 'when options["unique"] is while_executing' do - let(:options) { { 'lock' => 'while_executing' } } - let(:item) { { 'lock' => 'until_executed' } } + let(:options) { { "lock" => "while_executing" } } + let(:item) { { "lock" => "until_executed" } } - it { is_expected.to eq('while_executing') } + it { is_expected.to eq("while_executing") } end context 'when item["unique"] is until_executed' do let(:options) { {} } - let(:item) { { 'lock' => 'until_executed' } } + let(:item) { { "lock" => "until_executed" } } - it { is_expected.to eq('until_executed') } + it { is_expected.to eq("until_executed") } end end - describe '#options' do + describe "#options" do subject(:class_options) { options_with_fallback.options } - context 'when worker_class respond_to get_sidekiq_options' do + context "when worker_class respond_to get_sidekiq_options" do let(:worker_class) { SimpleWorker } it { is_expected.to eq(SimpleWorker.get_sidekiq_options) } end - context 'when default_worker_options has been configured' do + context "when default_worker_options has been configured" do let(:worker_class) { PlainClass } - let(:default_worker_options) { { 'lock' => :while_executing } } + let(:default_worker_options) { { "lock" => :while_executing } } it do with_default_worker_options(default_worker_options) do diff --git a/spec/unit/sidekiq_unique_jobs/scripts_spec.rb b/spec/unit/sidekiq_unique_jobs/scripts_spec.rb index 530c5d344..fbbe302bb 100644 --- a/spec/unit/sidekiq_unique_jobs/scripts_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/scripts_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Scripts, redis: :redis do subject { SidekiqUniqueJobs::Scripts } @@ -10,18 +10,18 @@ it { is_expected.to respond_to(:script_source).with(1).arguments } it { is_expected.to respond_to(:script_path).with(1).arguments } - describe '.call' do + describe ".call" do subject(:call) { described_class.call(script_name, nil, options) } - let(:jid) { 'abcefab' } - let(:unique_key) { 'uniquejobs:abcefab' } + let(:jid) { "abcefab" } + let(:unique_key) { "uniquejobs:abcefab" } let(:max_lock_time) { 1 } let(:options) { { keys: [unique_key], argv: [jid, max_lock_time] } } - let(:scriptsha) { 'abcdefab' } + let(:scriptsha) { "abcdefab" } let(:script_name) { :acquire_lock } - let(:error_message) { 'Some interesting error' } + let(:error_message) { "Some interesting error" } - context 'when conn.evalsha raises Redis::CommandError' do + context "when conn.evalsha raises Redis::CommandError" do before do call_count = 0 allow(described_class).to receive(:execute_script).with(script_name, nil, options) do @@ -39,8 +39,8 @@ ) end - context 'when error message is No matching script' do - let(:error_message) { 'NOSCRIPT No matching script. Please use EVAL.' } + context "when error message is No matching script" do + let(:error_message) { "NOSCRIPT No matching script. Please use EVAL." } specify do expect(described_class::SCRIPT_SHAS).to receive(:delete).with(script_name) diff --git a/spec/unit/sidekiq_unique_jobs/server/middleware_spec.rb b/spec/unit/sidekiq_unique_jobs/server/middleware_spec.rb index ca9f3e6bf..a16669760 100644 --- a/spec/unit/sidekiq_unique_jobs/server/middleware_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/server/middleware_spec.rb @@ -1,23 +1,23 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" # rubocop:disable RSpec/InstanceVariable RSpec.describe SidekiqUniqueJobs::Server::Middleware do let(:middleware) { described_class.new } - describe '#call' do + describe "#call" do subject(:call) { middleware.call(worker_class, item, queue, &block) } let(:block) { -> { @inside_block_value = true } } let(:worker_class) { WhileExecutingJob } - let(:queue) { 'working' } + let(:queue) { "working" } let(:redis_pool) { nil } let(:args) { [1] } let(:item) do - { 'class' => worker_class, - 'queue' => queue, - 'args' => args } + { "class" => worker_class, + "queue" => queue, + "args" => args } end let(:lock) { instance_spy(SidekiqUniqueJobs::Lock::WhileExecuting) } @@ -27,22 +27,22 @@ allow(lock).to receive(:execute).and_yield end - context 'when unique is disabled' do + context "when unique is disabled" do before do allow(middleware).to receive(:unique_enabled?).and_return(false) end - it 'yields control' do + it "yields control" do expect { call }.to change { @inside_block_value }.to(true) end end - context 'when unique is enabled' do + context "when unique is enabled" do before do allow(middleware).to receive(:unique_enabled?).and_return(true) end - it 'yields control' do + it "yields control" do expect { call }.to change { @inside_block_value }.to(true) end end diff --git a/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb b/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb new file mode 100644 index 000000000..28f064392 --- /dev/null +++ b/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Sidekiq::Api, redis: :redis do + let(:item) do + { "class" => "JustAWorker", + "queue" => "testqueue", + "args" => [foo: "bar"] } + end + + describe Sidekiq::SortedEntry::UniqueExtension do + it "deletes uniqueness lock on delete" do + expect(JustAWorker.perform_in(60 * 60 * 3, foo: "bar")).to be_truthy + expect(unique_keys).to match_array(%w[ + uniquejobs:863b7cb639bd71c828459b97788b2ada:EXISTS + uniquejobs:863b7cb639bd71c828459b97788b2ada:GRABBED + ]) + + Sidekiq::ScheduledSet.new.each(&:delete) + expect(keys("uniquejobs")).to match_array([]) + + expect(JustAWorker.perform_in(60 * 60 * 3, boo: "far")).to be_truthy + end + + it "deletes uniqueness lock on remove_job" do + expect(JustAWorker.perform_in(60 * 60 * 3, foo: "bar")).to be_truthy + expect(unique_keys).to match_array(%w[ + uniquejobs:863b7cb639bd71c828459b97788b2ada:EXISTS + uniquejobs:863b7cb639bd71c828459b97788b2ada:GRABBED + ]) + + Sidekiq::ScheduledSet.new.each do |entry| + entry.send(:remove_job) do |message| + item = Sidekiq.load_json(message) + expect(item).to match( + hash_including( + "args" => [{ "foo" => "bar" }], + "class" => "JustAWorker", + "jid" => kind_of(String), + "lock_expiration" => nil, + "lock_timeout" => 0, + "queue" => "testqueue", + "retry" => true, + "lock" => "until_executed", + "unique_args" => [{ "foo" => "bar" }], + "unique_digest" => "uniquejobs:863b7cb639bd71c828459b97788b2ada", + "unique_prefix" => "uniquejobs", + ), + ) + end + end + available_key = "uniquejobs:863b7cb639bd71c828459b97788b2ada:AVAILABLE" + expect(unique_keys).to match_array([available_key]) + expect(ttl(available_key)).to eq(5) + expect(JustAWorker.perform_in(60 * 60 * 3, boo: "far")).to be_truthy + end + end + + describe Sidekiq::Job::UniqueExtension do + it "deletes uniqueness lock on delete" do + jid = JustAWorker.perform_async(roo: "baf") + expect(keys).not_to match_array([]) + Sidekiq::Queue.new("testqueue").find_job(jid).delete + available_key = "uniquejobs:c2253601bbfe4f3ad300103026ed02f2:AVAILABLE" + expect(unique_keys).to match_array([available_key]) + expect(ttl(available_key)).to eq(5) + end + end + + describe Sidekiq::Queue::UniqueExtension do + it "deletes uniqueness locks on clear" do + JustAWorker.perform_async(oob: "far") + expect(keys).not_to match_array([]) + Sidekiq::Queue.new("testqueue").clear + available_key = "uniquejobs:ebd23329089b53ea1e93066a3365541f:AVAILABLE" + expect(unique_keys).to match_array([available_key]) + expect(ttl(available_key)).to eq(5) + end + end + + describe Sidekiq::JobSet::UniqueExtension do + it "deletes uniqueness locks on clear" do + JustAWorker.perform_in(60 * 60 * 3, roo: "fab") + expect(keys).not_to match_array([]) + Sidekiq::JobSet.new("schedule").clear + available_key = "uniquejobs:a88de37817cb5da99cf76408c7251a1d:AVAILABLE" + expect(unique_keys).to match_array([available_key]) + expect(ttl(available_key)).to eq(5) + end + end +end diff --git a/spec/unit/sidekiq_unique_jobs/sidekiq_unique_ext_spec.rb b/spec/unit/sidekiq_unique_jobs/sidekiq_unique_ext_spec.rb deleted file mode 100644 index 548fd6b18..000000000 --- a/spec/unit/sidekiq_unique_jobs/sidekiq_unique_ext_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'Sidekiq::Api', redis: :redis do - let(:item) do - { 'class' => 'JustAWorker', - 'queue' => 'testqueue', - 'args' => [foo: 'bar'] } - end - - describe Sidekiq::SortedEntry::UniqueExtension do - it 'deletes uniqueness lock on delete' do - expect(JustAWorker.perform_in(60 * 60 * 3, foo: 'bar')).to be_truthy - expect(unique_keys).to match_array(%w[ - uniquejobs:863b7cb639bd71c828459b97788b2ada:EXISTS - uniquejobs:863b7cb639bd71c828459b97788b2ada:GRABBED - ]) - - Sidekiq::ScheduledSet.new.each(&:delete) - expect(keys('uniquejobs')).to match_array([]) - - expect(JustAWorker.perform_in(60 * 60 * 3, boo: 'far')).to be_truthy - end - - it 'deletes uniqueness lock on remove_job' do - expect(JustAWorker.perform_in(60 * 60 * 3, foo: 'bar')).to be_truthy - expect(unique_keys).to match_array(%w[ - uniquejobs:863b7cb639bd71c828459b97788b2ada:EXISTS - uniquejobs:863b7cb639bd71c828459b97788b2ada:GRABBED - ]) - - Sidekiq::ScheduledSet.new.each do |entry| - entry.send(:remove_job) do |message| - item = Sidekiq.load_json(message) - expect(item).to match( - hash_including( - 'args' => [{ 'foo' => 'bar' }], - 'class' => 'JustAWorker', - 'jid' => kind_of(String), - 'lock_expiration' => nil, - 'lock_timeout' => 0, - 'queue' => 'testqueue', - 'retry' => true, - 'lock' => 'until_executed', - 'unique_args' => [{ 'foo' => 'bar' }], - 'unique_digest' => 'uniquejobs:863b7cb639bd71c828459b97788b2ada', - 'unique_prefix' => 'uniquejobs', - ), - ) - end - end - available_key = 'uniquejobs:863b7cb639bd71c828459b97788b2ada:AVAILABLE' - expect(unique_keys).to match_array([available_key]) - expect(ttl(available_key)).to eq(5) - expect(JustAWorker.perform_in(60 * 60 * 3, boo: 'far')).to be_truthy - end - end - - describe Sidekiq::Job::UniqueExtension do - it 'deletes uniqueness lock on delete' do - jid = JustAWorker.perform_async(roo: 'baf') - expect(keys).not_to match_array([]) - Sidekiq::Queue.new('testqueue').find_job(jid).delete - available_key = 'uniquejobs:c2253601bbfe4f3ad300103026ed02f2:AVAILABLE' - expect(unique_keys).to match_array([available_key]) - expect(ttl(available_key)).to eq(5) - end - end - - describe Sidekiq::Queue::UniqueExtension do - it 'deletes uniqueness locks on clear' do - JustAWorker.perform_async(oob: 'far') - expect(keys).not_to match_array([]) - Sidekiq::Queue.new('testqueue').clear - available_key = 'uniquejobs:ebd23329089b53ea1e93066a3365541f:AVAILABLE' - expect(unique_keys).to match_array([available_key]) - expect(ttl(available_key)).to eq(5) - end - end - - describe Sidekiq::JobSet::UniqueExtension do - it 'deletes uniqueness locks on clear' do - JustAWorker.perform_in(60 * 60 * 3, roo: 'fab') - expect(keys).not_to match_array([]) - Sidekiq::JobSet.new('schedule').clear - available_key = 'uniquejobs:a88de37817cb5da99cf76408c7251a1d:AVAILABLE' - expect(unique_keys).to match_array([available_key]) - expect(ttl(available_key)).to eq(5) - end - end -end diff --git a/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb b/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb index d58bdc34e..da58f8344 100644 --- a/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::SidekiqWorkerMethods do class WorkerWithSidekiqMethods @@ -13,30 +13,30 @@ def initialize(worker_class) let(:worker) { WorkerWithSidekiqMethods.new(worker_class) } - describe '#worker_class_constantize' do + describe "#worker_class_constantize" do subject(:worker_class_constantize) { worker.worker_class_constantize } - context 'when worker_class is nil' do + context "when worker_class is nil" do let(:worker_class) { nil } it { is_expected.to eq(nil) } end - context 'when worker_class is MyUniqueJob' do + context "when worker_class is MyUniqueJob" do let(:worker_class) { MyUniqueJob } it { is_expected.to eq(MyUniqueJob) } end - context 'when worker_class is MyUniqueJob' do - let(:worker_class) { 'UntilExecutedJob' } + context "when worker_class is MyUniqueJob" do + let(:worker_class) { "UntilExecutedJob" } it { is_expected.to eq(UntilExecutedJob) } end - context 'when NameError is caught' do - let(:worker_class) { 'UnknownConstant' } - let(:error_message) { 'this class does not exist' } + context "when NameError is caught" do + let(:worker_class) { "UnknownConstant" } + let(:error_message) { "this class does not exist" } before do allow(Object).to receive(:const_get) @@ -44,14 +44,14 @@ def initialize(worker_class) .and_raise(NameError, error_message) end - it 'raises NameError' do + it "raises NameError" do expect { worker_class_constantize }.to raise_error(NameError, error_message) end - context 'when exception.message contains `uninitialized constant`' do - let(:error_message) { 'uninitialized constant' } + context "when exception.message contains `uninitialized constant`" do + let(:error_message) { "uninitialized constant" } - it { is_expected.to eq('UnknownConstant') } + it { is_expected.to eq("UnknownConstant") } end end end diff --git a/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb b/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb index cccd15b94..f24c6468d 100644 --- a/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Timeout::Calculator do - let(:calculator) { described_class.new('class' => worker_class_name, 'at' => schedule_time) } - let(:worker_class_name) { 'MyUniqueJob' } + let(:calculator) { described_class.new("class" => worker_class_name, "at" => schedule_time) } + let(:worker_class_name) { "MyUniqueJob" } let(:schedule_time) { nil } - describe 'public api' do + describe "public api" do subject { calculator } it { is_expected.to respond_to(:time_until_scheduled) } @@ -18,14 +18,14 @@ it { is_expected.to respond_to(:default_worker_options) } end - describe '#time_until_scheduled' do + describe "#time_until_scheduled" do subject(:time_until_scheduled) { calculator.time_until_scheduled } - context 'when not scheduled' do + context "when not scheduled" do it { is_expected.to eq(0) } end - context 'when scheduled' do + context "when scheduled" do let(:schedule_time) { Time.now.utc.to_i + 24 * 60 * 60 } let(:now_in_utc) { Time.now.utc.to_i } @@ -37,10 +37,10 @@ end end - describe '#worker_class' do + describe "#worker_class" do subject(:worker_class) { calculator.worker_class } - let(:worker_class_name) { 'MyUniqueJob' } + let(:worker_class_name) { "MyUniqueJob" } it { is_expected.to eq(MyUniqueJob) } end diff --git a/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb b/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb index 49f36e73f..33a69b2bb 100644 --- a/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb @@ -1,98 +1,99 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::UniqueArgs do let(:unique_args) { described_class.new(item) } let(:worker_class) { UntilExecutedJob } let(:class_name) { worker_class.to_s } - let(:queue) { 'myqueue' } + let(:queue) { "myqueue" } let(:args) { [[1, 2]] } let(:item) do { - 'class' => class_name, - 'queue' => queue, - 'args' => args, + "class" => class_name, + "queue" => queue, + "args" => args, } end - describe '#unique_digest' do + describe "#unique_digest" do subject(:unique_digest) { unique_args.unique_digest } - context 'when args are empty' do + context "when args are empty" do let(:another_unique_args) { described_class.new(item) } let(:worker_class) { WithoutArgumentJob } let(:args) { [] } - context 'with the same unique args' do - it 'equals to unique_digest for that item' do + context "with the same unique args" do + it "equals to unique_digest for that item" do expect(unique_digest).to eq(another_unique_args.unique_digest) end end end - shared_examples 'unique digest' do - context 'with another item' do + shared_examples "unique digest" do + context "with another item" do let(:another_unique_args) { described_class.new(another_item) } - context 'with the same unique args' do - let(:another_item) { item.merge('args' => [1, 2, 'type' => 'it']) } + context "with the same unique args" do + let(:another_item) { item.merge("args" => [1, 2, "type" => "it"]) } - it 'equals to unique_digest for that item' do + it "equals to unique_digest for that item" do expect(unique_digest).to eq(another_unique_args.unique_digest) end end - context 'with different unique args' do - let(:another_item) { item.merge('args' => [1, 3, 'type' => 'that']) } + context "with different unique args" do + let(:another_item) { item.merge("args" => [1, 3, "type" => "that"]) } - it 'differs from unique_digest for that item' do + it "differs from unique_digest for that item" do expect(unique_digest).not_to eq(another_unique_args.unique_digest) end end end end - context 'when unique_args is a proc' do + context "when unique_args is a proc" do let(:worker_class) { MyUniqueJobWithFilterProc } - let(:args) { [1, 2, 'type' => 'it'] } + let(:args) { [1, 2, "type" => "it"] } - it_behaves_like 'unique digest' + it_behaves_like "unique digest" end - context 'when unique_args is a symbol' do + context "when unique_args is a symbol" do let(:worker_class) { MyUniqueJobWithFilterMethod } - let(:args) { [1, 2, 'type' => 'it'] } + let(:args) { [1, 2, "type" => "it"] } - it_behaves_like 'unique digest' + it_behaves_like "unique digest" end end - describe '#digestable_hash' do + describe "#digestable_hash" do subject(:digestable_hash) { unique_args.digestable_hash } let(:expected_hash) do - { 'class' => 'UntilExecutedJob', 'queue' => 'myqueue', 'unique_args' => [[1, 2]] } + { "class" => "UntilExecutedJob", "queue" => "myqueue", "unique_args" => [[1, 2]] } end it { is_expected.to eq(expected_hash) } with_sidekiq_options_for(UntilExecutedJob, unique_args: :unique_args, unique_on_all_queues: true) do - let(:expected_hash) { { 'class' => 'UntilExecutedJob', 'unique_args' => [[1, 2]] } } + let(:expected_hash) { { "class" => "UntilExecutedJob", "unique_args" => [[1, 2]] } } + it { is_expected.to eq(expected_hash) } end with_sidekiq_options_for(UntilExecutedJob, unique_across_workers: true) do - let(:expected_hash) { { 'queue' => 'myqueue', 'unique_args' => [[1, 2]] } } + let(:expected_hash) { { "queue" => "myqueue", "unique_args" => [[1, 2]] } } it { is_expected.to eq(expected_hash) } end end - describe '#unique_args_enabled?' do + describe "#unique_args_enabled?" do subject(:unique_args_enabled?) { unique_args.unique_args_enabled? } - with_default_worker_options(unique: :until_executed, unique_args: ->(args) { args[1]['test'] }) do + with_default_worker_options(unique: :until_executed, unique_args: ->(args) { args[1]["test"] }) do with_sidekiq_options_for(UntilExecutedJob, unique_args: :unique_args) do it { is_expected.to eq(:unique_args) } end @@ -113,7 +114,7 @@ it { is_expected.to be_falsy } end - with_sidekiq_options_for('MissingWorker', unique_args: true) do + with_sidekiq_options_for("MissingWorker", unique_args: true) do it { is_expected.to be_falsy } end @@ -121,7 +122,7 @@ end end - describe '#unique_across_queues?' do + describe "#unique_across_queues?" do subject(:unique_across_queues?) { unique_args.unique_across_queues? } let(:worker_class) { UntilExecutedJob } @@ -137,7 +138,7 @@ end end - describe '#unique_across_workers?' do + describe "#unique_across_workers?" do subject(:unique_across_workers?) { unique_args.unique_across_workers? } it { is_expected.to eq(nil) } @@ -151,42 +152,42 @@ end end - describe '#filtered_args' do + describe "#filtered_args" do subject(:filtered_args) { unique_args.filtered_args(args) } - let(:args) { [1, 'test' => 'it'] } + let(:args) { [1, "test" => "it"] } before do allow(unique_args).to receive(:unique_args_method).and_return(unique_args_method) end - context 'when #unique_args_method is nil' do + context "when #unique_args_method is nil" do let(:unique_args_method) { nil } - it 'logs a debug message' do + it "logs a debug message" do allow(unique_args).to receive(:log_debug) filtered_args expect(unique_args) .to have_received(:log_debug) - .with('filtered_args arguments not filtered (using all arguments for uniqueness)') + .with("filtered_args arguments not filtered (using all arguments for uniqueness)") end it { is_expected.to eq(args) } end end - describe '#filter_by_proc' do + describe "#filter_by_proc" do subject(:filter_by_proc) { unique_args.filter_by_proc(args) } - let(:args) { [1, 'test' => 'it'] } + let(:args) { [1, "test" => "it"] } - context 'when #unique_args_method is a proc' do - let(:filter) { ->(args) { args[1]['test'] } } + context "when #unique_args_method is a proc" do + let(:filter) { ->(args) { args[1]["test"] } } before { allow(unique_args).to receive(:unique_args_method).and_return(filter) } - it { is_expected.to eq('it') } + it { is_expected.to eq("it") } end with_default_worker_options(unique_args: ->(args) { args.first }) do @@ -194,24 +195,24 @@ end end - describe '#filter_by_symbol' do + describe "#filter_by_symbol" do subject(:filter_by_symbol) { unique_args.filter_by_symbol(args) } - context 'when filter is a working symbol' do + context "when filter is a working symbol" do let(:worker_class) { UniqueJobWithFilterMethod } - let(:args) { ['name', 2, 'whatever' => nil, 'type' => 'test'] } + let(:args) { ["name", 2, "whatever" => nil, "type" => "test"] } let(:filtered_args) { %w[name test] } it { is_expected.to eq(filtered_args) } end - context 'when worker takes conditional parameters' do + context "when worker takes conditional parameters" do let(:worker_class) { UniqueJobWithoutUniqueArgsParameter } let(:args) { [1] } it { is_expected.to eq([1]) } - context 'when provided nil' do + context "when provided nil" do let(:args) { [] } it { is_expected.to eq([]) } @@ -220,21 +221,21 @@ context "when workers unique_args method doesn't take parameters" do let(:worker_class) { UniqueJobWithoutUniqueArgsParameter } - let(:args) { ['name', 2, 'whatever' => nil, 'type' => 'test'] } + let(:args) { ["name", 2, "whatever" => nil, "type" => "test"] } it { is_expected.to eq(args) } end - context 'when @worker_class does not respond_to unique_args_method' do + context "when @worker_class does not respond_to unique_args_method" do let(:worker_class) { UniqueJobWithNoUniqueArgsMethod } - let(:args) { ['name', 2, 'whatever' => nil, 'type' => 'test'] } + let(:args) { ["name", 2, "whatever" => nil, "type" => "test"] } it { is_expected.to eq(args) } end - context 'when workers unique_args method returns nil' do + context "when workers unique_args method returns nil" do let(:worker_class) { UniqueJobWithNilUniqueArgs } - let(:args) { ['name', 2, 'whatever' => nil, 'type' => 'test'] } + let(:args) { ["name", 2, "whatever" => nil, "type" => "test"] } it { is_expected.to eq(nil) } end diff --git a/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb b/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb index 3e20f1435..f9e438aff 100644 --- a/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Unlockable, redis: :redis do def item_with_digest @@ -8,14 +8,14 @@ def item_with_digest item end let(:item) do - { 'class' => MyUniqueJob, - 'queue' => 'customqueue', - 'args' => [1, 2] } + { "class" => MyUniqueJob, + "queue" => "customqueue", + "args" => [1, 2] } end let(:unique_digest) { item_with_digest[SidekiqUniqueJobs::UNIQUE_DIGEST_KEY] } - describe '.unlock' do + describe ".unlock" do subject(:unlock) { described_class.unlock(item_with_digest) } let(:expected_keys) do @@ -34,7 +34,7 @@ def item_with_digest end end - describe '.delete' do + describe ".delete" do subject(:delete) { described_class.delete(item_with_digest) } specify do diff --git a/spec/unit/sidekiq_unique_jobs/util_spec.rb b/spec/unit/sidekiq_unique_jobs/util_spec.rb index f9c3e1692..4a46a47e5 100644 --- a/spec/unit/sidekiq_unique_jobs/util_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/util_spec.rb @@ -1,20 +1,20 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Util, redis: :redis do let(:item_hash) do { - 'class' => 'MyUniqueJob', - 'args' => [[1, 2]], - 'at' => 1_492_341_850.358196, - 'retry' => true, - 'queue' => 'customqueue', - 'lock' => :until_executed, - 'lock_expiration' => 7200, - 'retry_count' => 10, - 'jid' => jid, - 'created_at' => 1_492_341_790.358217, + "class" => "MyUniqueJob", + "args" => [[1, 2]], + "at" => 1_492_341_850.358196, + "retry" => true, + "queue" => "customqueue", + "lock" => :until_executed, + "lock_expiration" => 7200, + "retry_count" => 10, + "jid" => jid, + "created_at" => 1_492_341_790.358217, } end @@ -24,8 +24,8 @@ my_item end - let(:unique_digest) { item['unique_digest'] } - let(:jid) { 'e3049b05b0bd9c809182bbe0' } + let(:unique_digest) { item["unique_digest"] } + let(:jid) { "e3049b05b0bd9c809182bbe0" } let(:lock) { SidekiqUniqueJobs::Locksmith.new(item) } let(:expected_keys) do %W[ @@ -34,7 +34,7 @@ ] end - shared_context 'with an old lock' do + shared_context "with an old lock" do before do result = SidekiqUniqueJobs::Scripts.call( :acquire_lock, @@ -47,16 +47,16 @@ end end - describe '.keys' do + describe ".keys" do subject(:keys) { described_class.keys } - context 'when old lock exists' do - include_context 'with an old lock' + context "when old lock exists" do + include_context "with an old lock" it { is_expected.to match_array([unique_digest]) } end - context 'when new lock exists' do + context "when new lock exists" do before do lock.lock(0) end @@ -65,22 +65,22 @@ end end - describe '.del' do + describe ".del" do subject(:del) { described_class.del(pattern, 100) } - context 'when an old lock exists' do - include_context 'with an old lock' + context "when an old lock exists" do + include_context "with an old lock" it { expect(described_class.keys).to match_array([unique_digest]) } - context 'when pattern is a wildcard' do + context "when pattern is a wildcard" do let(:pattern) { described_class::SCAN_PATTERN } it { is_expected.to eq(1) } it { expect { del }.to change(described_class, :keys).to([]) } end - context 'when pattern is a specific key' do + context "when pattern is a specific key" do let(:pattern) { unique_digest } it { is_expected.to eq(1) } @@ -88,7 +88,7 @@ end end - context 'when a new lock exists' do + context "when a new lock exists" do before do lock.lock(0) end @@ -97,14 +97,14 @@ it { expect(described_class.keys).to match_array(expected_keys) } - context 'when pattern is a wildcard' do + context "when pattern is a wildcard" do let(:pattern) { described_class::SCAN_PATTERN } it { is_expected.to eq(2) } it { expect { del }.to change(described_class, :keys).to([]) } end - context 'when pattern is a specific key' do + context "when pattern is a specific key" do let(:pattern) { unique_digest } it { is_expected.to eq(2) } @@ -113,27 +113,27 @@ end end - describe '.prefix' do + describe ".prefix" do subject(:prefix) { described_class.send(:prefix, key) } - let(:key) { 'key' } + let(:key) { "key" } - context 'when prefix is configured' do - before { allow(SidekiqUniqueJobs.config).to receive(:unique_prefix).and_return('test-uniqueness') } + context "when prefix is configured" do + before { allow(SidekiqUniqueJobs.config).to receive(:unique_prefix).and_return("test-uniqueness") } - it { is_expected.to eq('test-uniqueness:key') } + it { is_expected.to eq("test-uniqueness:key") } - context 'when key is already prefixed' do - let(:key) { 'test-uniqueness:key' } + context "when key is already prefixed" do + let(:key) { "test-uniqueness:key" } - it { is_expected.to eq('test-uniqueness:key') } + it { is_expected.to eq("test-uniqueness:key") } end end - context 'when .unique_prefix is nil?' do + context "when .unique_prefix is nil?" do before { allow(SidekiqUniqueJobs.config).to receive(:unique_prefix).and_return(nil) } - it { is_expected.to eq('key') } + it { is_expected.to eq("key") } end end end diff --git a/spec/unit/sidekiq_unique_jobs_spec.rb b/spec/unit/sidekiq_unique_jobs_spec.rb index db18914d9..ea6528f01 100644 --- a/spec/unit/sidekiq_unique_jobs_spec.rb +++ b/spec/unit/sidekiq_unique_jobs_spec.rb @@ -1,31 +1,31 @@ # frozen_string_literal: true -require 'spec_helper' +require "spec_helper" RSpec.describe SidekiqUniqueJobs do - describe '.config' do + describe ".config" do subject(:config) { described_class.config } it { is_expected.to be_a(SidekiqUniqueJobs::Config) } its(:default_lock_timeout) { is_expected.to eq(0) } its(:enabled) { is_expected.to eq(true) } - its(:unique_prefix) { is_expected.to eq('uniquejobs') } + its(:unique_prefix) { is_expected.to eq("uniquejobs") } end - describe '.use_config' do - it 'changes configuration temporary' do - described_class.use_config(unique_prefix: 'bogus') do - expect(described_class.config.unique_prefix).to eq('bogus') + describe ".use_config" do + it "changes configuration temporary" do + described_class.use_config(unique_prefix: "bogus") do + expect(described_class.config.unique_prefix).to eq("bogus") end - expect(described_class.config.unique_prefix).to eq('uniquejobs') + expect(described_class.config.unique_prefix).to eq("uniquejobs") end end - describe '.configure' do - let(:options) { { unique_prefix: 'hi' } } + describe ".configure" do + let(:options) { { unique_prefix: "hi" } } - context 'when given a block' do + context "when given a block" do specify do expect { |block| described_class.configure(&block) }.to yield_control end @@ -38,15 +38,15 @@ end end - describe '.logger' do + describe ".logger" do subject { described_class.logger } - context 'without further configuration' do + context "without further configuration" do it { is_expected.to eq(Sidekiq.logger) } end - context 'when configured explicitly' do - let(:another_logger) { Logger.new('/dev/null') } + context "when configured explicitly" do + let(:another_logger) { Logger.new("/dev/null") } around do |exmpl| described_class.use_config(logger: another_logger) do @@ -58,11 +58,11 @@ end end - describe '.logger=' do + describe ".logger=" do let(:original_logger) { Sidekiq.logger } - let(:another_logger) { Logger.new('/dev/null') } + let(:another_logger) { Logger.new("/dev/null") } - it 'changes the SidekiqUniqueJobs.logger' do + it "changes the SidekiqUniqueJobs.logger" do expect { described_class.logger = another_logger } .to change(described_class, :logger) .from(original_logger) @@ -72,7 +72,7 @@ end end - describe '.redis_version' do + describe ".redis_version" do subject(:redis_version) { described_class.redis_version } it { is_expected.to be_a(String) } From 815c81237699b214dfd03402594499bf316d5d0e Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 1 Feb 2019 22:31:21 +0100 Subject: [PATCH 02/23] Tweak the newly added --- .yardopts | 2 +- lib/sidekiq_unique_jobs/digests.rb | 5 +++-- lib/tasks/changelog.rake | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.yardopts b/.yardopts index 94fe4e4f2..841e11a47 100644 --- a/.yardopts +++ b/.yardopts @@ -1 +1 @@ ---no-private --output-dir docs lib/stub_requests/**/*.rb --markup-provider=redcarpet --markup=markdown - README.md +--no-private --output-dir docs lib/**/*.rb --markup-provider=redcarpet --markup=markdown - README.md diff --git a/lib/sidekiq_unique_jobs/digests.rb b/lib/sidekiq_unique_jobs/digests.rb index d218d8e2e..80f01b096 100644 --- a/lib/sidekiq_unique_jobs/digests.rb +++ b/lib/sidekiq_unique_jobs/digests.rb @@ -25,8 +25,9 @@ def all(pattern: SCAN_PATTERN, count: DEFAULT_COUNT) # Paginate unique digests # # @param [String] pattern a pattern to match with - # @param [Integer] page the current cursor position - # @param [Integer] count the maximum number to match + # @param [Integer] cursor the maximum number to match + # @param [Integer] page_size the current cursor position + # # @return [Array] with unique digests def page(pattern: SCAN_PATTERN, cursor: 0, page_size: 100) redis do |conn| diff --git a/lib/tasks/changelog.rake b/lib/tasks/changelog.rake index e5f21b930..72ae7f0af 100644 --- a/lib/tasks/changelog.rake +++ b/lib/tasks/changelog.rake @@ -8,7 +8,7 @@ task :changelog do -u mhenrixon -p - stub_requests + sidekiq-unique-jobs --no-verbose --token ] From 7870ed16ad003301ced08bd75c3e2915e2604b2b Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 1 Feb 2019 22:31:33 +0100 Subject: [PATCH 03/23] Update changelog --- CHANGELOG.md | 864 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 704 insertions(+), 160 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39a632ff5..5fb6a8622 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,252 +1,796 @@ -## v6.0.8 +# Change Log -- Expire available keys after unlocking ([caused by #352](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/352)) +## [v6.0.8](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.8) (2019-01-10) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.7...v6.0.8) -## v6.0.7 +**Fixed bugs:** -- Fix a bug leaving jobs locked ([#352](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/352)) +- Close \#359 [\#364](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/364) ([mhenrixon](https://github.com/mhenrixon)) -## v6.0.6 +**Closed issues:** -- Fixes a bug with the command line utility ([#321](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/321)) -- Internal refactoring to improve performance ([#318](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/318)) -- Adds coverage for retrying jobs +- Automatic unlock of jobs [\#362](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/362) +- \(6.0.7\) `uniquejobs:{digest}:AVAILABLE` keys never expire [\#359](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/359) +- Strange behavior using strategy "reject" with "until\_executed" [\#358](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/358) +- Pinpointing issues with unique digests not being removed [\#353](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/353) -## v6.0.5 +**Merged pull requests:** -- Fixes a bug with keys not being deleted ([#317](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/317)) +- update changelog [\#356](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/356) ([camallen](https://github.com/camallen)) -## v6.0.4 +## [v6.0.7](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.7) (2018-11-29) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.11...v6.0.7) -- Prevent locks from stealing each other (#316) +**Fixed bugs:** -## v6.0.3 +- Version 5: Job ID Hash Entries Not Removed if Unique Key Expires [\#346](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/346) +- Move the lpush last [\#354](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/354) ([mhenrixon](https://github.com/mhenrixon)) -- Fixes a few hickups (#315) +**Closed issues:** -## v6.0.2 +- First job never unlocks the lock / Endless waiting [\#352](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/352) +- Version 5&6: uniqueness not respected for Job without params [\#349](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/349) -- Fixes sidekiq web pagination of unique digests -- Fixes lock_expiration usage (Lua doesn't support expire after persisting a key) +## [v5.0.11](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.11) (2018-11-19) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.6...v5.0.11) -## v6.0.1 +**Implemented enhancements:** -- Remove unused method that causes conflict with sidekiq/web +- More integration tests [\#329](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/329) ([mhenrixon](https://github.com/mhenrixon)) -## v6.0.0 +**Fixed bugs:** -- Complete rewrite of the locking mechanism -- Improved README -- Improved reliability -- Improved coverage -- Removed a ton of default configuration -- Removed support for ActiveJob -- Added WhileExecutingReject `unique: :while_executing_reject` -- Renamed `UntilTimeout` to `UntilExpired` -- Removed concurrency for now (a0cff5bc42edbe7190d6ede7e7f845074d2d7af6) -- Improved integration testing for locks -- Totally delete the hash that was growing out of proportion -- Adds a sidekiq web extension for viewing and deleting unique digests -- Renamed the configuration `unique:` to `lock:` (still backwards compatible) -- Added some very simplistic conflict strategies. +- Always Remove Job ID from uniquejobs Hash [\#347](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/347) ([chadrschroeder](https://github.com/chadrschroeder)) +- Convert expiration time to integer [\#330](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/330) ([dareddov](https://github.com/dareddov)) -## v5.1.0 +**Closed issues:** -- Refactoring the runtime locks (WhileExecuting) +- concurrent-ruby 1.1.1 is causing this gem to break [\#340](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/340) +- lock remains after job not properly finish [\#339](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/339) +- Using a different Redis instance [\#337](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/337) +- Using :until\_and\_while\_executing not yielding expected results [\#336](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/336) +- "payload is not unique", but cannot find digest or scheduled job [\#335](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/335) +- Confused with UntilExecuted documenation [\#326](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/326) +- Job never requeued after raising unhandled error with until\_and\_while\_executing? [\#322](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/322) -## v5.0.10 +**Merged pull requests:** -- Cleans up test setup and make tests more readable -- Allow raising all errors -- Log previously hidden errors -- Revert the changes of v5.0.5 (8a4b7648b8b0ee5d7dc1f5f5a036f41d52ad9a42) -- Allow name errors in unique args method to be raised +- Do not build keys on lua scripts [\#348](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/348) ([pacoguzman](https://github.com/pacoguzman)) +- fix CHANGELOG syntax [\#344](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/344) ([timoschilling](https://github.com/timoschilling)) +- Define Config class inside SidekiqUniqueJobs module [\#343](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/343) ([Slike9](https://github.com/Slike9)) +- fix readme testing section [\#333](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/333) ([edmartins](https://github.com/edmartins)) +- Fix typo in documentation \[ci-skip\] [\#327](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/327) ([mhenrixon](https://github.com/mhenrixon)) -## v5.0.9 -- [#229](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/#229) Use HSCAN for expiring keys -- [#232](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/#232) Fix testing helper +## [v6.0.6](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.6) (2018-08-09) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.5...v6.0.6) -## v5.0.8 -- Fixes [#220](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/220) +**Implemented enhancements:** -## v5.0.7 -- Fixes [#218](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/218) +- Adds coverage for job retries [\#321](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/321) ([mhenrixon](https://github.com/mhenrixon)) +- Internal refactoring [\#318](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/318) ([mhenrixon](https://github.com/mhenrixon)) -## v5.0.6 -- Allow across worker uniquenes: See https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/jobs/unique_acrosss_workers_job.rb for information +**Closed issues:** -## v5.0.5 -- Use a class level mutex for `while_executing` +- Unique UntilExecuted not working while the job is executing? [\#319](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/319) -## v5.0.4 -- Fixes a problem with installing the gem +## [v6.0.5](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.5) (2018-08-07) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.4...v6.0.5) -## v5.0.3 -- Removes test files and appraisals and such from the released gem version to speed up gem installs +**Fixed bugs:** -## v5.0.2 -- Added more helpful debug, warning and error messages for failures to collect unique arghuments +- Unlock instead of signal [\#317](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/317) ([mhenrixon](https://github.com/mhenrixon)) -## v5.0.1 +**Closed issues:** -- Added a command line util for cleaning out expired keys -- Use `SidekiqUniqueJobs.logger` instead of spreading out `Sidekiq.logger` everywhere. +- Why is lock\_timeout: nil VERY DANGEROUS? [\#313](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/313) -## v5.0.0 +## [v6.0.4](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.4) (2018-08-02) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.3...v6.0.4) -- Only support Sidekiq >= 4 -- Removed overrides and support for older Sidekiq testing -- Added coverage +**Fixed bugs:** -## v4.0.18 +- Fix the broken expiration [\#316](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/316) ([mhenrixon](https://github.com/mhenrixon)) -- Allow mock_redis to be used over redis -- Fixes some locking inconsistencies +**Closed issues:** -## v4.0.17 +- Question about until\_timeout with 6.0.0 [\#303](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/303) -- Always release lock in the lua script `release_lock.lua` and return success [#169](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/169) +## [v6.0.3](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.3) (2018-08-02) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.2...v6.0.3) -## v4.0.16 +**Fixed bugs:** -- Allow run & queue lock timeout (expiration) to be different [#164](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/164) -- Fix a bug with loading sidekiq test overrides ([#167](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/167) +- Enable replace strategy [\#315](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/315) ([mhenrixon](https://github.com/mhenrixon)) -## v4.0.15 +**Closed issues:** -- Close [#156](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/156) -- Close [#158](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/158) -- Style fixes and some minor adjustments to the console/cmd line app +- Sidekiq Web Pagination Broken [\#309](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/309) -## v4.0.13 +**Merged pull requests:** -- Allow deleting locks by jid +- Correct documentation typo \[ci skip\] [\#312](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/312) ([mhenrixon](https://github.com/mhenrixon)) -## v4.0.12 +## [v6.0.2](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.2) (2018-08-01) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.1...v6.0.2) -- Allow jobs to be pushed to processing -- Close [#150](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/150) -- Close [#151](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/151) -- Close [#146](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/146) -- Close [#136](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/136) -- Close [#133](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/133) +**Fixed bugs:** -## v4.0.11 +- Not unlocking automatically \(version 6.0.0rc5\) [\#293](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/293) +- Bug fixes [\#310](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/310) ([mhenrixon](https://github.com/mhenrixon)) -- Always load forwardable [#152](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/152#issuecomment-164199978) +## [v6.0.1](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.1) (2018-07-31) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0...v6.0.1) -## v4.0.10 +**Fixed bugs:** -- Fix [#152](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/152) -- Minor improvement to internal esthetics +- :until\_executed is throwing errors and not requeuing the job. [\#256](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/256) +- Remove unused method [\#307](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/307) ([mhenrixon](https://github.com/mhenrixon)) -## v4.0.9 +**Closed issues:** -- Add command line and console extensions for removal of unique jobs (c292d87) +- ArgumentError: sidekiq\_unique\_jobs/web breaks sidekiq Retries page [\#306](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/306) +- If the job dies, it doesn't remove the lock [\#304](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/304) -## v4.0.8 +**Merged pull requests:** -- Use unique arguments for the `WhileExecuting` lock ([#127](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/127) -- Delicensed code ([#132](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/132) -- Fix queuing unique jobs ([#138](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/138) +- Dead jobs [\#308](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/308) ([mhenrixon](https://github.com/mhenrixon)) +- Fix require path for sidekiq\_unique\_jobs/web [\#305](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/305) ([soundasleep](https://github.com/soundasleep)) -## v4.0.7 +## [v6.0.0](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0) (2018-07-27) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.rc8...v6.0.0) -- Use unique arguments for the `WhileExecuting` lock ([#127](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/127) -- See also https://github.com/mhenrixon/sidekiq-unique-jobs/releases/tag/v4.0.7 +## [v6.0.0.rc8](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.rc8) (2018-07-24) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.rc7...v6.0.0.rc8) -## v4.0.6 +**Implemented enhancements:** -- Removes enforced uniqueness for all jobs ([#127](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/127) +- Add RequeueWhileExecuting strategy [\#223](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/223) +- New feature: Replace original job if duplicate is added [\#177](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/177) +- Add a replace strategy for client locks [\#302](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/302) ([mhenrixon](https://github.com/mhenrixon)) -## v4.0.5 +**Merged pull requests:** -- Forces look for `Sidekiq::Testing` in Sidekiq without ancestors #129 +- Add more details about testing uniqueness [\#301](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/301) ([mhenrixon](https://github.com/mhenrixon)) +- Update README.md [\#300](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/300) ([pirj](https://github.com/pirj)) -## v4.0.4 +## [v6.0.0.rc7](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.rc7) (2018-07-23) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.rc6...v6.0.0.rc7) -- Fix usage with active job -- Get rid of unneeded configuration options `unique_args_enabled` (just use whatever unique argument that is configured). +**Implemented enhancements:** -## v4.0.3 +- Sidekiq web [\#297](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/297) ([mhenrixon](https://github.com/mhenrixon)) +- Document code [\#296](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/296) ([mhenrixon](https://github.com/mhenrixon)) +- Rename to `unique:` to `lock:` [\#295](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/295) ([mhenrixon](https://github.com/mhenrixon)) -- Remove `unique_lock` and use `unique: ` to set this like in `unique: :until_timeout` -- Warn when using `unique: true` and suggest to change it to what we need with a fallback. -- Create constants for hash keys to avoid having to fix spelling or for renaming keys only having to be done in one place and avoid having to type .freeze everywhere. -- Move all explicit logic out from the server middle ware and make it just call execute on the instance of the lock class (prepare for allowing custom locking classes to be used). -- Create a new job for scheduling jobs after it started executing but only allow one job to run at the same time. +**Closed issues:** -## v4.0.2 +- Unique Job not work while play with crontab [\#294](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/294) +- Making the GEM compatible with Ruby \< 2.3 [\#291](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/291) -- Fix a problem with an unresolved reference +**Merged pull requests:** -## v4.0.1 +- Adds changelog entry [\#299](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/299) ([mhenrixon](https://github.com/mhenrixon)) +- Fix README [\#298](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/298) ([mhenrixon](https://github.com/mhenrixon)) -- Get rid of development dependency on active support (causing trouble with jruby) +## [v6.0.0.rc6](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.rc6) (2018-07-15) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.rc5...v6.0.0.rc6) -## v4.0.0 +**Fixed bugs:** -- Improved uniqueness handling (complete refactoring, upgrade with caution) -- 100% breaking changes +- Don't unlock when worker raises an error [\#290](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/290) ([mhenrixon](https://github.com/mhenrixon)) -## v3.0.15 +**Closed issues:** -- Jobs only ever unlock themselves now (see #96 & #94 for info) thanks @pik -- Slight refactoring and internal renaming. Shouldn't affect anyone -- Run locks as an alternative when you only need to prevent the same job running twice but want to be able to schedule it multiple times. See #99 (thanks @pik) -- Fixes #90, #92, #93, #97, #98, #100, #101, #105 +- Locking with retries [\#289](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/289) -## v3.0.14 +**Merged pull requests:** -- Improve uniqueness check performance thanks @mpherham -- Remove locks in sidekiq fake testing mode -- Do not unlock jobs when sidekiq is shutting down +- Readme [\#288](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/288) ([mhenrixon](https://github.com/mhenrixon)) -## v3.0.13 +## [v6.0.0.rc5](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.rc5) (2018-06-30) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.rc4...v6.0.0.rc5) -- Improved testing capabilities (testing uniqueness should not work better) -- Configurable logging of duplicate payloads -- Now requires `sidekiq_unique_ext` and `sidekiq/api` by default -- Drop support for MRI 1.9 and sidekiq 2 +**Fixed bugs:** -## v3.0.11 +- bundle exec jobs console does not work [\#253](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/253) +- Rename command line binary [\#287](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/287) ([mhenrixon](https://github.com/mhenrixon)) -- Ensure threadsafety (thanks to adstage-david) +## [v6.0.0.rc4](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.rc4) (2018-06-30) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.rc3...v6.0.0.rc4) -## v3.0.9 -- Fixed that all jobs stopped processing +**Implemented enhancements:** -## v3.0.8 +- Prepare for v6 [\#286](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/286) ([mhenrixon](https://github.com/mhenrixon)) +- Only unlock not delete [\#285](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/285) ([mhenrixon](https://github.com/mhenrixon)) -- Unique extensions for Web GUI by @rickenharp. Uniqueness will now be removed when a job is. +## [v6.0.0.rc3](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.rc3) (2018-06-29) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.rc2...v6.0.0.rc3) -## v3.0.7 +**Fixed bugs:** -- Internal refactoring -- Improved coverage -- Rubocop style validation +- Fix waiting for locks [\#284](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/284) ([mhenrixon](https://github.com/mhenrixon)) -## v3.0.5 +## [v6.0.0.rc2](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.rc2) (2018-06-26) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.rc1...v6.0.0.rc2) -- Fixed the different test modes (major thanks to @salrepe) +**Implemented enhancements:** -## v3.0.2 +- Within tests: workers enqueued in the future don't clear their unique locks after being drained/executed [\#254](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/254) +- Unexpected behavior with until\_executed [\#250](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/250) -- Removed runtime dependency on mock_redis (add `gem 'mock_redis'` to your desired group to use it) +**Fixed bugs:** -## v2.7.0 +- Unique job needs to be unlocked manually? [\#261](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/261) +- Duplicate jobs getting created [\#257](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/257) +- Multiple non-unique jobs with until\_executed? [\#255](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/255) +- :until\_executing not unlocking when starting to run [\#245](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/245) +- Drop jobs hash [\#282](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/282) ([mhenrixon](https://github.com/mhenrixon)) -- Use mock_redis when testing in fake mode -- Replace minitest with rspec -- Add codeclimate badge -- Update travis with redis-server +**Closed issues:** -## v2.6.5 +- Difference between :until\_and\_while\_executing vs :until\_executed is not clear [\#249](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/249) +- Deprecated Documentation [\#246](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/246) +- Are we meant to manually expire the unique jobs hash? [\#234](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/234) +- How :until\_executing works ? Run job only once and discard new jobs while another job is executing [\#226](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/226) -- via @sax - possibility to set which arguments should be counted as unique - https://github.com/form26/sidekiq_unique_jobs/pull/12 -- via @eduardosasso - possibility to set which arguments should be counted as unique - https://github.com/form26/sidekiq_unique_jobs/pull/11 -- via @KensoDev - configuration of default expiration - https://github.com/form26/sidekiq_unique_jobs/pull/9 +**Merged pull requests:** -## v2.1.0 +- Remove some misleading information [\#283](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/283) ([mhenrixon](https://github.com/mhenrixon)) -Extracted the unique jobs portion from sidekiq main repo since @mperham dropped support for it. +## [v6.0.0.rc1](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.rc1) (2018-06-26) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.beta2...v6.0.0.rc1) + +**Implemented enhancements:** + +- Legacy support [\#280](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/280) +- Adds legacy support [\#281](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/281) ([mhenrixon](https://github.com/mhenrixon)) +- Adds guard-reek [\#279](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/279) ([mhenrixon](https://github.com/mhenrixon)) +- Fix UntilExpired [\#278](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/278) ([mhenrixon](https://github.com/mhenrixon)) + +**Fixed bugs:** + +- Fix UntilExpired [\#278](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/278) ([mhenrixon](https://github.com/mhenrixon)) + +## [v6.0.0.beta2](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.beta2) (2018-06-25) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.beta1...v6.0.0.beta2) + +**Implemented enhancements:** + +- Make locks more robust [\#277](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/277) ([mhenrixon](https://github.com/mhenrixon)) +- Rename UntilTimeout -\> UntilExpired [\#276](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/276) ([mhenrixon](https://github.com/mhenrixon)) + +## [v6.0.0.beta1](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.beta1) (2018-06-22) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v6.0.0.beta...v6.0.0.beta1) + +**Implemented enhancements:** + +- Code smells [\#275](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/275) ([mhenrixon](https://github.com/mhenrixon)) +- Reject while scheduling [\#273](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/273) ([mhenrixon](https://github.com/mhenrixon)) +- Improve testing [\#272](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/272) ([mhenrixon](https://github.com/mhenrixon)) + +## [v6.0.0.beta](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v6.0.0.beta) (2018-06-17) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.10...v6.0.0.beta) + +**Implemented enhancements:** + +- Until and while executing [\#271](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/271) ([mhenrixon](https://github.com/mhenrixon)) +- Solidify master [\#270](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/270) ([mhenrixon](https://github.com/mhenrixon)) +- Minor adjustments [\#268](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/268) ([mhenrixon](https://github.com/mhenrixon)) +- Use ruby 2.5.1 [\#267](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/267) ([mhenrixon](https://github.com/mhenrixon)) +- Add explicit concurrent-ruby dependency. [\#265](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/265) ([brettburley](https://github.com/brettburley)) + +**Fixed bugs:** + +- Allow `jobs keys` to default to listing all keys [\#252](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/252) ([soundasleep](https://github.com/soundasleep)) + +**Closed issues:** + +- Incomplete sentence in README [\#264](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/264) +- ActiveJob and Sidekiq::Worker [\#259](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/259) +- ActiveJob and Sidekiq::Worker [\#258](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/258) +- Non-unique jobs can be added even when `sidekiq\_options unique: :until\_executed` [\#251](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/251) +- Trouble with "inline" mode [\#243](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/243) +- Sidekiq::Worker.set not working with sidekiq-unique-jobs [\#242](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/242) +- sidekiq-unique-job with ActiveJob [\#238](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/238) +- Deadlock using :while\_executing? [\#233](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/233) + +**Merged pull requests:** + +- Improve documentation [\#269](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/269) ([mhenrixon](https://github.com/mhenrixon)) +- Remove unnecessary monkey patches for String [\#262](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/262) ([zormandi](https://github.com/zormandi)) +- README \> While Executing: remove unnecessary word [\#260](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/260) ([TimCannady](https://github.com/TimCannady)) +- Don't skip monkeypatches if ActiveSupport present [\#248](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/248) ([dleavitt](https://github.com/dleavitt)) +- Better runtime locks [\#241](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/241) ([mhenrixon](https://github.com/mhenrixon)) + +## [v5.0.10](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10) (2017-08-19) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.9...v5.0.10) + +**Closed issues:** + +- Version v5.0.5 might have introduced a breaking change in while\_executing and was not documented [\#230](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/230) +- String arguments not seen as unique [\#222](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/222) +- unique\_args method suppresses all `NameError` exceptions [\#219](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/219) + +**Merged pull requests:** + +- Various improvements [\#240](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/240) ([mhenrixon](https://github.com/mhenrixon)) +- Fix: uninitialized constant CustomQueueJob on rspec [\#239](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/239) ([dalpo](https://github.com/dalpo)) + +## [v5.0.9](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.9) (2017-07-06) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.8...v5.0.9) + +**Closed issues:** + +- The work of several unique sidekiq tasks within one queue [\#225](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/225) +- Missing documentation on activejob usage [\#221](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/221) + +**Merged pull requests:** + +- Your testing lib is broken and don't permit to test uniqueness of jobs [\#232](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/232) ([keysen](https://github.com/keysen)) +- Use hscan for Util\#expire [\#229](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/229) ([dmkc](https://github.com/dmkc)) +- Fixed documentation example about unique\_args [\#228](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/228) ([andresakata](https://github.com/andresakata)) +- Fix filename [\#224](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/224) ([ikataitsev](https://github.com/ikataitsev)) + +## [v5.0.8](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.8) (2017-05-03) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.7...v5.0.8) + +**Closed issues:** + +- Using JSON.parse in delete\_by\_value\_ext break compatiblity with other Sidekiq extensions [\#220](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/220) +- Is it possible to get the Job ID of original job? [\#217](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/217) + +## [v5.0.7](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.7) (2017-04-26) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.6...v5.0.7) + +**Closed issues:** + +- Can't delete Sidekiq::Job after 5.0.1 [\#218](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/218) +- Uniqueness across workers [\#210](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/210) + +## [v5.0.6](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.6) (2017-04-23) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.5...v5.0.6) + +**Closed issues:** + +- Different unique arguments depending on lock type [\#203](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/203) +- Strategy until\_and\_while\_executing not working properly [\#199](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/199) +- while\_executing working wrong [\#193](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/193) + +## [v5.0.5](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.5) (2017-04-23) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.4...v5.0.5) + +**Merged pull requests:** + +- Fixed typo on README.md [\#216](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/216) ([jsantos](https://github.com/jsantos)) + +## [v5.0.4](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.4) (2017-04-18) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.3...v5.0.4) + +## [v5.0.3](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.3) (2017-04-18) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.2...v5.0.3) + +## [v5.0.2](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.2) (2017-04-17) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.1...v5.0.2) + +**Closed issues:** + +- Uniqueness should not survive Class.jobs.clear [\#214](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/214) +- when arguments are empty then unique\_args proc/method is not executed [\#201](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/201) + +## [v5.0.1](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.1) (2017-04-16) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v5.0.0...v5.0.1) + +**Closed issues:** + +- Removing "uniquejobs" hash? [\#213](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/213) +- deprecation warnings with redis-namespace 2.0 [\#212](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/212) +- Unclear docs / examples for unique\_args [\#211](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/211) +- Jobs Console fails to launch [\#208](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/208) +- Util.del Redis::CommandError: ERR syntax error [\#207](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/207) +- version 4.0.19 [\#206](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/206) +- Job.delete does not remove lock in all circumstances [\#205](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/205) +- disappearing jobs - known issue in conjunction with other extensions? [\#202](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/202) +- Broken pipe @ io\_write - \ on sidekiq unique jobs [\#198](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/198) +- Doesn't play well with redis-namespace [\#196](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/196) +- SidekiqUniqueJobs::ScriptError [\#192](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/192) + +**Merged pull requests:** + +- Add the possibility to clear the hash [\#215](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/215) ([mhenrixon](https://github.com/mhenrixon)) + +## [v5.0.0](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.0) (2017-04-08) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.18...v5.0.0) + +**Fixed bugs:** + +- Can't enable testing with newer versions of sidekiq [\#175](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/175) +- strange behaviour [\#172](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/172) + +**Closed issues:** + +- Could not find a valid gem 'sidekiq-unique-jobs' \(= 3.0.15\) in any repository [\#197](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/197) +- `uniquejobs` hash doesn't get cleaned up [\#195](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/195) +- Code block under "Finer Control over Uniqueness" in your documentation might have the wrong option specified [\#191](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/191) +- not able to run test without live Redis [\#186](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/186) +- unique while not sucessfully completed? [\#185](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/185) +- Duplicate jobs when using :until\_and\_while\_executing [\#181](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/181) +- unique: :while\_executing doesn't remove lock when the Sidekiq node running the job shuts down and terminates the job prematurely [\#170](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/170) +- :while\_executing appears to be broken [\#159](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/159) +- Using ":until\_executing, :until\_executed, :until\_timeout, :until\_and\_while\_executing" all break Sidekiq::Testing [\#157](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/157) +- Way to remove lock in application code [\#147](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/147) + +**Merged pull requests:** + +- Increase sleep delay in WhileExecuting\#synchronize [\#204](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/204) ([dsander](https://github.com/dsander)) +- Ensure job ID removed from uniquejobs hash [\#200](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/200) ([carlosmartinez](https://github.com/carlosmartinez)) +- unique args need to be an array [\#194](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/194) ([pboling](https://github.com/pboling)) + +## [v4.0.18](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.18) (2016-07-24) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.17...v4.0.18) + +**Closed issues:** + +- ArgumentError: wrong number of arguments \(given 1, expected 2\) [\#190](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/190) +- Should be note on document only works on production mode [\#189](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/189) +- SidekiqUniqueJobs::ScriptError: release\_lock.lua NOSCRIPT No matching script. [\#187](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/187) +- sidekiq-unique-jobs kills sidekiq in production [\#183](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/183) +- Parameters turn into String [\#182](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/182) +- You really helped me today [\#180](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/180) +- 4.0.17 config [\#171](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/171) +- Problem with releasing uniquejobs locks after timeout expires [\#169](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/169) +- NOSCRIPT No matching script. Please use EVAL. [\#168](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/168) +- Broken compatibility with Sidekiq 3.4 [\#140](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/140) + +**Merged pull requests:** + +- missed space [\#188](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/188) ([TheBigSadowski](https://github.com/TheBigSadowski)) +- Convert unless if to just 1 if [\#179](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/179) ([otzy007](https://github.com/otzy007)) +- fix for \#168. Handle the NOSCRIPT by sending the script again [\#178](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/178) ([otzy007](https://github.com/otzy007)) +- Fixed gitter badge link [\#176](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/176) ([andrew](https://github.com/andrew)) + +## [v4.0.17](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.17) (2016-03-02) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.16...v4.0.17) + +**Closed issues:** + +- No place where I can say "Thank you" for all contributors [\#165](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/165) + +## [v4.0.16](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.16) (2016-02-17) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.15...v4.0.16) + +**Merged pull requests:** + +- Fix for sidekiq delete failing for version 3.4.x [\#167](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/167) ([theprogrammerin](https://github.com/theprogrammerin)) +- Run lock timeout configurable [\#164](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/164) ([Slania](https://github.com/Slania)) + +## [v4.0.15](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.15) (2016-02-16) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.13...v4.0.15) + +**Closed issues:** + +- Until timeout question [\#163](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/163) +- Error when run rspec [\#162](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/162) +- Unique job keys never dissapear [\#161](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/161) +- Uniqueness breaks jobs [\#160](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/160) +- Too many open files [\#155](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/155) + +**Merged pull requests:** + +- Add a Gitter chat badge to README.md [\#166](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/166) ([gitter-badger](https://github.com/gitter-badger)) +- Fix test overrides. [\#158](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/158) ([benseligman](https://github.com/benseligman)) +- Remove wrong Server::Middleware\#worker\_class override [\#156](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/156) ([vkuznetsov](https://github.com/vkuznetsov)) + +## [v4.0.13](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.13) (2015-12-16) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.12...v4.0.13) + +**Closed issues:** + +- Seeing this error with latest version 4.0.12 [\#154](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/154) +- Unique job showing weird behavior [\#153](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/153) + +## [v4.0.12](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.12) (2015-12-15) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.11...v4.0.12) + +**Closed issues:** + +- Can't schedule a job from another job [\#151](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/151) +- perform\_in not working in version 4.0.9 [\#150](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/150) +- `unique: until\_and\_while\_executing` not working as expected [\#146](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/146) +- while\_executing still runs duplicate tasks [\#136](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/136) +- Version 4 Upgrade [\#133](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/133) + +## [v4.0.11](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.11) (2015-12-12) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.10...v4.0.11) + +**Closed issues:** + +- Release a new version for Ruby \< 2.1 compatability [\#152](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/152) + +## [v4.0.10](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.10) (2015-12-12) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.9...v4.0.10) + +**Closed issues:** + +- Until Executed is taking waiting for unique\_expiration [\#149](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/149) +- Until Executed vs Unique Until And While Executing is confusing in README [\#148](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/148) +- sidekiq-unique-jobs not enabled from sidekiq workers [\#131](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/131) + +## [v4.0.9](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.9) (2015-11-14) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.8...v4.0.9) + +**Closed issues:** + +- Error when using unique\_args in 4.0.8 [\#145](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/145) +- Ignore lock when jobs spawned from another sidekiq worker [\#142](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/142) +- Two Rails apps on the same server, but only one Sidekiq instances is working correctly [\#141](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/141) +- ActiveRecord::RecordNotDestroyed: Failed to destroy the record [\#139](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/139) + +## [v4.0.8](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.8) (2015-10-31) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.7...v4.0.8) + +**Closed issues:** + +- Jobs not getting queued in v4 [\#138](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/138) +- Unique args being considered? [\#137](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/137) +- No mention how to test in README [\#135](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/135) +- License Difference [\#132](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/132) + +**Merged pull requests:** + +- Calculate worker's unique args when a proc or a symbol is specified [\#143](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/143) ([zeqfreed](https://github.com/zeqfreed)) +- Fix markdown link formatting [\#134](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/134) ([thbar](https://github.com/thbar)) + +## [v4.0.7](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.7) (2015-10-14) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.6...v4.0.7) + +**Closed issues:** + +- docs clarification [\#130](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/130) +- 4.\* is hurting background job workers performance [\#127](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/127) + +## [v4.0.6](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.6) (2015-10-14) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.5...v4.0.6) + +**Closed issues:** + +- NameError: uninitialized constant SidekiqUniqueJobs::RunLockFailed [\#126](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/126) + +## [v4.0.5](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.5) (2015-10-13) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.4...v4.0.5) + +**Closed issues:** + +- Rails + Sidekiq will go bezerk after sidekiq-unique-jobs testing check. [\#128](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/128) +- NoMethodError: undefined method `to\_sym' for true:TrueClass [\#125](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/125) +- Redis::CommandError: ERR unknown command 'eval' [\#124](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/124) + +**Merged pull requests:** + +- Forces to look for testing namespace in Sidekiq and not his ancestors [\#129](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/129) ([antek-drzewiecki](https://github.com/antek-drzewiecki)) +- Fix outdated phrasing and add test coverage to readme [\#123](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/123) ([albertyw](https://github.com/albertyw)) + +## [v4.0.4](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.4) (2015-10-09) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.3...v4.0.4) + +**Closed issues:** + +- Active job with unique args doesn't work [\#120](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/120) +- 4.0.1 =\> job no longer unique [\#117](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/117) +- Update Changelog and Tags [\#115](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/115) + +## [v4.0.3](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.3) (2015-10-08) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.2...v4.0.3) + +**Closed issues:** + +- unique\_unlock\_order - never option [\#122](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/122) +- Run 1 job and queue 1 [\#121](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/121) +- unique\_lock vs unique\_locks typo [\#119](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/119) +- 4.0.2 commited but not released to rubygems? [\#118](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/118) + +## [v4.0.2](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.2) (2015-10-06) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/4.0.1...v4.0.2) + +## [4.0.1](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/4.0.1) (2015-10-06) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v4.0.0...4.0.1) + +**Closed issues:** + +- Don't work with perform\_in [\#114](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/114) +- 3.0.15 apparently breaks inline testing [\#113](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/113) +- sidekiq\_unique record in Redis is not cleaned when foreman process is killed [\#112](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/112) +- Can't ensure unique job simultaneously. [\#111](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/111) +- Job considered as duplicate after completion only in production [\#110](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/110) +- Gem requires Redis 2.6+? [\#109](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/109) +- unable to re-schedule job at specific time [\#108](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/108) +- Documentation Not Clear [\#78](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/78) +- Runtime uniqueness when using :before\_yield as unlock order [\#72](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/72) +- Using with sidekiq delayed extensions [\#45](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/45) + +**Merged pull requests:** + +- Clean up version 4 upgrade instructions [\#116](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/116) ([albertyw](https://github.com/albertyw)) + +## [v4.0.0](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.0) (2015-10-05) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v3.0.11...v4.0.0) + +**Implemented enhancements:** + +- Duplicated Jobs With Nested Sidekiq Workers [\#10](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/10) + +**Closed issues:** + +- 3.0.14 Error: ERR wrong number of arguments for 'set' command \(Redis::CommandError\) [\#104](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/104) +- Testing [\#103](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/103) +- Active Job [\#102](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/102) +- Why is SidekiqUnique behaviour applied to regular Workers? [\#100](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/100) +- Confusing behavior when trying to `\[1,2,3\].each { |n| SomeJob.perform\_in\(n.seconds.from\_now, n\) }` never running, logging as duplicate value [\#98](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/98) +- Scheduled jobs are not unlocked when deleted [\#97](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/97) +- Testing functions should be moved out of production code [\#95](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/95) +- Jobs can unlock mutexes they don't own [\#94](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/94) +- Jobs scheduled in the future are never run [\#93](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/93) +- perform\_at and perform\_async do not unique if perform\_at is in the future. [\#91](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/91) +- Latest release is breaking [\#90](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/90) +- Optimize Redis usage [\#89](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/89) +- Unique jobs sets Sidekiq testing to inline! mode [\#88](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/88) +- Test suite unclear on what happens when duplicate job is attempted [\#84](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/84) +- Change log level to info rather than warn [\#80](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/80) +- Jobs are unlocked if they fail and are retried [\#77](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/77) +- Usage of sidekiq-unique-jobs with activejob [\#76](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/76) +- If a job is deleted from the enqueued list, it's still unique and new jobs can't be added. [\#74](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/74) +- Incorrect README re: uniqueness time? [\#73](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/73) +- Sidekiq::Testing inline detection assumes you're always using inline testing [\#71](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/71) +- unique\_args\_enabled has been deprecated, nothing in readme [\#70](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/70) +- The second job does not run, even if it has different arguments [\#69](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/69) +- Jobs not being executed anymore?? [\#65](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/65) +- mock\_redis and the mess [\#62](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/62) +- What is the exact behavior? [\#47](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/47) +- Throttling jobs [\#39](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/39) +- undefined method `get\_sidekiq\_options' for "MyScheduledWorker":String [\#27](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/27) +- Crash handling [\#14](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/14) +- Missing info from README [\#6](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/6) + +**Merged pull requests:** + +- Allow job with jid matching unique lock to pass unique check [\#105](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/105) ([deltaroe](https://github.com/deltaroe)) +- Prevent Jobs from deleting mutexes they don't own [\#96](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/96) ([pik](https://github.com/pik)) +- Add after unlock hook [\#92](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/92) ([HParker](https://github.com/HParker)) +- Do not unlock on sidekiq shutdown [\#87](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/87) ([deltaroe](https://github.com/deltaroe)) +- Remove no-op code, protect global space from test code [\#86](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/86) ([stevenjonescgm](https://github.com/stevenjonescgm)) +- Remove unique lock when executing and clearing jobs in sidekiq fake mode [\#83](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/83) ([crberube](https://github.com/crberube)) +- Fix tests. Tests with latest sidekiq versions and ruby versions [\#82](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/82) ([simonoff](https://github.com/simonoff)) +- Duplicate Payload logging configuration [\#81](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/81) ([jprincipe](https://github.com/jprincipe)) +- output log if not unique [\#79](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/79) ([sonots](https://github.com/sonots)) +- Checking Sidekiq::Testing.inline? on testing strategy and connector [\#75](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/75) ([Draiken](https://github.com/Draiken)) + +## [v3.0.11](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v3.0.11) (2014-12-15) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v3.0.10...v3.0.11) + +**Closed issues:** + +- ConnectionPool used incorrectly - causes deadlocks [\#66](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/66) +- undefined `configuration` when using .configure [\#64](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/64) + +**Merged pull requests:** + +- Use ConnectionPool blocks to ensure exclusive connection. Closes \#66. [\#67](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/67) ([adstage-david](https://github.com/adstage-david)) + +## [v3.0.10](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v3.0.10) (2014-11-19) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v3.0.9...v3.0.10) + +**Closed issues:** + +- LoadError: cannot load such file -- mock\_redis [\#60](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/60) +- The deprecation message is unclear and unnecessary [\#59](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/59) + +**Merged pull requests:** + +- Added method name to depreciation warning message [\#61](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/61) ([jamesbowles](https://github.com/jamesbowles)) + +## [v3.0.9](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v3.0.9) (2014-11-05) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v3.0.3...v3.0.9) + +**Closed issues:** + +- sidekiq-unique-jobs prevents not unique jobs creation event with sidekiq inline test mode [\#58](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/58) +- mock redis dependency [\#55](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/55) +- Unique key inconsistency between server and client [\#48](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/48) +- Example Test using Sidekiq::Testing.inline [\#44](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/44) +- Will a second job lose if the job is already queued, or is already scheduled? [\#43](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/43) +- Can you update the change log? [\#42](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/42) + +**Merged pull requests:** + +- Refactoring connectors to use them in client and server [\#56](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/56) ([salrepe](https://github.com/salrepe)) +- Fix dependency error in inline testing connector [\#54](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/54) ([salrepe](https://github.com/salrepe)) +- Add extension to Sidekiq API that is uniqueness-aware [\#52](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/52) ([rickenharp](https://github.com/rickenharp)) + +## [v3.0.3](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v3.0.3) (2014-11-03) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v3.0.2...v3.0.3) + +**Closed issues:** + +- is mock\_redis really a runtime dependency? [\#46](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/46) + +**Merged pull requests:** + +- Unlock testing inline jobs like normal ones [\#53](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/53) ([salrepe](https://github.com/salrepe)) +- Declare mock\_redis as development dependency instead of runtime one [\#51](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/51) ([phuongnd08](https://github.com/phuongnd08)) + +## [v3.0.2](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v3.0.2) (2014-06-08) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v3.0.1...v3.0.2) + +**Closed issues:** + +- Add unique job key to the message json [\#40](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/40) + +**Merged pull requests:** + +- Add the unique hash to the message for use by the workers. [\#41](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/41) ([sullimander](https://github.com/sullimander)) + +## [v3.0.1](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v3.0.1) (2014-06-08) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v2.7.0...v3.0.1) + +**Closed issues:** + +- Support for sidekiq 3? [\#34](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/34) +- Short jobs are not unique for the given time window [\#33](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/33) +- Not all sidekiq:sidekiq\_unique keys are removed from Redis [\#31](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/31) +- What does uniqueness mean in case of this gem? [\#30](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/30) +- Server middleware removes payload hash key before expiration [\#26](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/26) +- Lock remains when running with Sidekiq::Testing.inline! [\#23](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/23) +- What is the use case for the uniqueness window? [\#22](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/22) +- clarification on unique\_args [\#20](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/20) +- payload\_hash staying around [\#13](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/13) + +**Merged pull requests:** + +- Fix repo URLs for badges [\#38](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/38) ([felixbuenemann](https://github.com/felixbuenemann)) +- Clarify README about unique expiration [\#36](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/36) ([spacemunkay](https://github.com/spacemunkay)) +- Add option to make jobs unique on all queues [\#32](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/32) ([robinmessage](https://github.com/robinmessage)) +- Fix homepage in gemspec [\#29](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/29) ([tmaier](https://github.com/tmaier)) + +## [v2.7.0](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v2.7.0) (2013-11-24) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v2.3.2...v2.7.0) + +**Closed issues:** + +- Sidekiq tests failed when sidekiq-unique-jobs is used [\#24](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/24) +- Redis not mocked in testing [\#18](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/18) +- Scheduled Unique Jobs Not Being Enqueued [\#15](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/15) +- Retries duplicates unique jobs [\#5](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/5) +- Middleware not added to chain? [\#2](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/2) + +**Merged pull requests:** + +- Make unlock/yield order configurable. [\#21](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/21) ([endofunky](https://github.com/endofunky)) +- Rely on Sidekiq's String\#constantize extension instead of rolling our own [\#19](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/19) ([disbelief](https://github.com/disbelief)) +- Attempt to constantize String `worker\_class` arguments passed to client middleware [\#17](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/17) ([disbelief](https://github.com/disbelief)) +- Compatibility with Sidekiq 2.12.1 Scheduled Jobs [\#16](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/16) ([lsimoneau](https://github.com/lsimoneau)) +- Allow worker to specify which arguments to include in uniquing hash [\#12](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/12) ([sax](https://github.com/sax)) +- Add support for unique when using Sidekiq's delay function [\#11](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/11) ([eduardosasso](https://github.com/eduardosasso)) +- Adding the unique prefix option [\#8](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/8) ([KensoDev](https://github.com/KensoDev)) +- Remove unnecessary log messages [\#7](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/7) ([marclennox](https://github.com/marclennox)) + +## [v2.3.2](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v2.3.2) (2012-09-27) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v2.2.1...v2.3.2) + +**Closed issues:** + +- Scheduled workers [\#1](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/1) + +**Merged pull requests:** + +- Fix multiple bugs, cleaned up dependencies, and added a feature [\#4](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/4) ([kemper-blinq](https://github.com/kemper-blinq)) +- Dependency on sidekiq 2.2.0 and up [\#3](https://github.com/mhenrixon/sidekiq-unique-jobs/pull/3) ([philostler](https://github.com/philostler)) + +## [v2.2.1](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v2.2.1) (2012-08-19) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v2.2.0...v2.2.1) + +## [v2.2.0](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v2.2.0) (2012-08-19) +[Full Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v2.1.0...v2.2.0) + +## [v2.1.0](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v2.1.0) (2012-08-07) + + +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* From fabe4fe01f669e57bcc68fc987b2d8eeb93804a1 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 1 Feb 2019 22:31:39 +0100 Subject: [PATCH 04/23] Add docs --- docs/Array.html | 198 ++ docs/Hash.html | 378 ++++ docs/Sidekiq.html | 202 ++ docs/Sidekiq/Job.html | 147 ++ docs/Sidekiq/Job/UniqueExtension.html | 181 ++ docs/Sidekiq/JobSet.html | 147 ++ docs/Sidekiq/JobSet/UniqueExtension.html | 233 +++ docs/Sidekiq/Queue.html | 147 ++ docs/Sidekiq/Queue/UniqueExtension.html | 181 ++ docs/Sidekiq/ScheduledSet.html | 147 ++ .../Sidekiq/ScheduledSet/UniqueExtension.html | 179 ++ docs/Sidekiq/SortedEntry.html | 147 ++ docs/Sidekiq/SortedEntry/UniqueExtension.html | 179 ++ docs/Sidekiq/Worker.html | 126 ++ docs/Sidekiq/Worker/ClassMethods.html | 246 +++ docs/Sidekiq/Worker/Overrides.html | 120 ++ docs/Sidekiq/Worker/Overrides/Testing.html | 176 ++ docs/SidekiqUniqueJobs.html | 767 ++++++++ docs/SidekiqUniqueJobs/Cli.html | 415 ++++ docs/SidekiqUniqueJobs/Client.html | 115 ++ docs/SidekiqUniqueJobs/Client/Middleware.html | 353 ++++ docs/SidekiqUniqueJobs/Conflict.html | 229 +++ docs/SidekiqUniqueJobs/Connection.html | 240 +++ docs/SidekiqUniqueJobs/Digests.html | 699 +++++++ docs/SidekiqUniqueJobs/Job.html | 222 +++ docs/SidekiqUniqueJobs/Lock.html | 133 ++ docs/SidekiqUniqueJobs/Lock/BaseLock.html | 801 ++++++++ .../Lock/UntilAndWhileExecuting.html | 343 ++++ .../SidekiqUniqueJobs/Lock/UntilExecuted.html | 282 +++ .../Lock/UntilExecuting.html | 280 +++ docs/SidekiqUniqueJobs/Lock/UntilExpired.html | 367 ++++ .../Lock/WhileExecuting.html | 487 +++++ .../Lock/WhileExecutingReject.html | 375 ++++ docs/SidekiqUniqueJobs/Locksmith.html | 1082 +++++++++++ docs/SidekiqUniqueJobs/Logging.html | 779 ++++++++ docs/SidekiqUniqueJobs/Middleware.html | 335 ++++ docs/SidekiqUniqueJobs/Normalizer.html | 242 +++ docs/SidekiqUniqueJobs/OnConflict.html | 244 +++ docs/SidekiqUniqueJobs/OnConflict/Log.html | 272 +++ .../OnConflict/NullStrategy.html | 274 +++ docs/SidekiqUniqueJobs/OnConflict/Raise.html | 275 +++ docs/SidekiqUniqueJobs/OnConflict/Reject.html | 859 +++++++++ .../SidekiqUniqueJobs/OnConflict/Replace.html | 654 +++++++ .../OnConflict/Reschedule.html | 362 ++++ .../OnConflict/Strategy.html | 526 +++++ .../OptionsWithFallback.html | 770 ++++++++ docs/SidekiqUniqueJobs/ScriptError.html | 263 +++ docs/SidekiqUniqueJobs/Scripts.html | 935 +++++++++ docs/SidekiqUniqueJobs/Server.html | 115 ++ docs/SidekiqUniqueJobs/Server/Middleware.html | 355 ++++ .../SidekiqWorkerMethods.html | 704 +++++++ docs/SidekiqUniqueJobs/Timeout.html | 117 ++ .../SidekiqUniqueJobs/Timeout/Calculator.html | 766 ++++++++ docs/SidekiqUniqueJobs/UniqueArgs.html | 1704 +++++++++++++++++ docs/SidekiqUniqueJobs/UnknownLock.html | 149 ++ docs/SidekiqUniqueJobs/Unlockable.html | 318 +++ docs/SidekiqUniqueJobs/Util.html | 611 ++++++ docs/SidekiqUniqueJobs/Web.html | 275 +++ docs/SidekiqUniqueJobs/Web/Helpers.html | 393 ++++ docs/_index.html | 633 ++++++ docs/class_list.html | 51 + docs/css/common.css | 1 + docs/css/full_list.css | 58 + docs/css/style.css | 496 +++++ docs/file.README.html | 546 ++++++ docs/file_list.html | 56 + docs/frames.html | 17 + docs/index.html | 546 ++++++ docs/js/app.js | 292 +++ docs/js/full_list.js | 216 +++ docs/js/jquery.js | 4 + docs/method_list.html | 1291 +++++++++++++ docs/top-level-namespace.html | 112 ++ 73 files changed, 26940 insertions(+) create mode 100644 docs/Array.html create mode 100644 docs/Hash.html create mode 100644 docs/Sidekiq.html create mode 100644 docs/Sidekiq/Job.html create mode 100644 docs/Sidekiq/Job/UniqueExtension.html create mode 100644 docs/Sidekiq/JobSet.html create mode 100644 docs/Sidekiq/JobSet/UniqueExtension.html create mode 100644 docs/Sidekiq/Queue.html create mode 100644 docs/Sidekiq/Queue/UniqueExtension.html create mode 100644 docs/Sidekiq/ScheduledSet.html create mode 100644 docs/Sidekiq/ScheduledSet/UniqueExtension.html create mode 100644 docs/Sidekiq/SortedEntry.html create mode 100644 docs/Sidekiq/SortedEntry/UniqueExtension.html create mode 100644 docs/Sidekiq/Worker.html create mode 100644 docs/Sidekiq/Worker/ClassMethods.html create mode 100644 docs/Sidekiq/Worker/Overrides.html create mode 100644 docs/Sidekiq/Worker/Overrides/Testing.html create mode 100644 docs/SidekiqUniqueJobs.html create mode 100644 docs/SidekiqUniqueJobs/Cli.html create mode 100644 docs/SidekiqUniqueJobs/Client.html create mode 100644 docs/SidekiqUniqueJobs/Client/Middleware.html create mode 100644 docs/SidekiqUniqueJobs/Conflict.html create mode 100644 docs/SidekiqUniqueJobs/Connection.html create mode 100644 docs/SidekiqUniqueJobs/Digests.html create mode 100644 docs/SidekiqUniqueJobs/Job.html create mode 100644 docs/SidekiqUniqueJobs/Lock.html create mode 100644 docs/SidekiqUniqueJobs/Lock/BaseLock.html create mode 100644 docs/SidekiqUniqueJobs/Lock/UntilAndWhileExecuting.html create mode 100644 docs/SidekiqUniqueJobs/Lock/UntilExecuted.html create mode 100644 docs/SidekiqUniqueJobs/Lock/UntilExecuting.html create mode 100644 docs/SidekiqUniqueJobs/Lock/UntilExpired.html create mode 100644 docs/SidekiqUniqueJobs/Lock/WhileExecuting.html create mode 100644 docs/SidekiqUniqueJobs/Lock/WhileExecutingReject.html create mode 100644 docs/SidekiqUniqueJobs/Locksmith.html create mode 100644 docs/SidekiqUniqueJobs/Logging.html create mode 100644 docs/SidekiqUniqueJobs/Middleware.html create mode 100644 docs/SidekiqUniqueJobs/Normalizer.html create mode 100644 docs/SidekiqUniqueJobs/OnConflict.html create mode 100644 docs/SidekiqUniqueJobs/OnConflict/Log.html create mode 100644 docs/SidekiqUniqueJobs/OnConflict/NullStrategy.html create mode 100644 docs/SidekiqUniqueJobs/OnConflict/Raise.html create mode 100644 docs/SidekiqUniqueJobs/OnConflict/Reject.html create mode 100644 docs/SidekiqUniqueJobs/OnConflict/Replace.html create mode 100644 docs/SidekiqUniqueJobs/OnConflict/Reschedule.html create mode 100644 docs/SidekiqUniqueJobs/OnConflict/Strategy.html create mode 100644 docs/SidekiqUniqueJobs/OptionsWithFallback.html create mode 100644 docs/SidekiqUniqueJobs/ScriptError.html create mode 100644 docs/SidekiqUniqueJobs/Scripts.html create mode 100644 docs/SidekiqUniqueJobs/Server.html create mode 100644 docs/SidekiqUniqueJobs/Server/Middleware.html create mode 100644 docs/SidekiqUniqueJobs/SidekiqWorkerMethods.html create mode 100644 docs/SidekiqUniqueJobs/Timeout.html create mode 100644 docs/SidekiqUniqueJobs/Timeout/Calculator.html create mode 100644 docs/SidekiqUniqueJobs/UniqueArgs.html create mode 100644 docs/SidekiqUniqueJobs/UnknownLock.html create mode 100644 docs/SidekiqUniqueJobs/Unlockable.html create mode 100644 docs/SidekiqUniqueJobs/Util.html create mode 100644 docs/SidekiqUniqueJobs/Web.html create mode 100644 docs/SidekiqUniqueJobs/Web/Helpers.html create mode 100644 docs/_index.html create mode 100644 docs/class_list.html create mode 100644 docs/css/common.css create mode 100644 docs/css/full_list.css create mode 100644 docs/css/style.css create mode 100644 docs/file.README.html create mode 100644 docs/file_list.html create mode 100644 docs/frames.html create mode 100644 docs/index.html create mode 100644 docs/js/app.js create mode 100644 docs/js/full_list.js create mode 100644 docs/js/jquery.js create mode 100644 docs/method_list.html create mode 100644 docs/top-level-namespace.html diff --git a/docs/Array.html b/docs/Array.html new file mode 100644 index 000000000..e670a1992 --- /dev/null +++ b/docs/Array.html @@ -0,0 +1,198 @@ + + + + + + + Class: Array + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Array + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/core_ext.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #extract_options!Object + + + + + +

+ + + + +
+
+
+
+44
+45
+46
+47
+48
+49
+50
+
+
# File 'lib/sidekiq_unique_jobs/core_ext.rb', line 44
+
+def extract_options!
+  if last.is_a?(Hash) && last.instance_of?(Hash)
+    pop
+  else
+    {}
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Hash.html b/docs/Hash.html new file mode 100644 index 000000000..b5b870dd1 --- /dev/null +++ b/docs/Hash.html @@ -0,0 +1,378 @@ + + + + + + + Class: Hash + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Hash + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/core_ext.rb
+
+ +
+ +

Overview

+
+

:nocov:

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #slice(*keys) ⇒ Object + + + + + +

+ + + + +
+
+
+
+7
+8
+9
+10
+
+
# File 'lib/sidekiq_unique_jobs/core_ext.rb', line 7
+
+def slice(*keys)
+  keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
+  keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if key?(k) }
+end
+
+
+ +
+

+ + #slice!(*keys) ⇒ Object + + + + + +

+ + + + +
+
+
+
+30
+31
+32
+33
+34
+35
+36
+37
+38
+
+
# File 'lib/sidekiq_unique_jobs/core_ext.rb', line 30
+
+def slice!(*keys)
+  keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
+  omit = slice(*self.keys - keys)
+  hash = slice(*keys)
+  hash.default      = default
+  hash.default_proc = default_proc if default_proc
+  replace(hash)
+  omit
+end
+
+
+ +
+

+ + #stringify_keysObject + + + + + +

+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/sidekiq_unique_jobs/core_ext.rb', line 14
+
+def stringify_keys
+  transform_keys(&:to_s)
+end
+
+
+ +
+

+ + #transform_keysObject + + + + + +

+ + + + +
+
+
+
+20
+21
+22
+23
+24
+25
+26
+
+
# File 'lib/sidekiq_unique_jobs/core_ext.rb', line 20
+
+def transform_keys
+  result = {}
+  each_key do |key|
+    result[yield(key)] = self[key]
+  end
+  result
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq.html b/docs/Sidekiq.html new file mode 100644 index 000000000..ac383329d --- /dev/null +++ b/docs/Sidekiq.html @@ -0,0 +1,202 @@ + + + + + + + Module: Sidekiq + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Sidekiq + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/testing.rb,
+ lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+
+ +
+ +

Defined Under Namespace

+

+ + + Modules: Worker + + + + Classes: Job, JobSet, Queue, ScheduledSet, SortedEntry + + +

+ + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .use_options(tmp_config = {}) ⇒ Object + + + + + +

+ + + + +
+
+
+
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+
+
# File 'lib/sidekiq_unique_jobs/testing.rb', line 9
+
+def self.use_options(tmp_config = {})
+  old_config = default_worker_options
+  default_worker_options.clear
+  self.default_worker_options = tmp_config
+
+  yield
+ensure
+  default_worker_options.clear
+  self.default_worker_options = old_config
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/Job.html b/docs/Sidekiq/Job.html new file mode 100644 index 000000000..d7350c564 --- /dev/null +++ b/docs/Sidekiq/Job.html @@ -0,0 +1,147 @@ + + + + + + + Class: Sidekiq::Job + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Sidekiq::Job + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
UniqueExtension
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + Modules: UniqueExtension + + + + +

+ + + + + + + + + + + + + + +

Method Summary

+ +

Methods included from UniqueExtension

+

#delete_ext

+ + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/Job/UniqueExtension.html b/docs/Sidekiq/Job/UniqueExtension.html new file mode 100644 index 000000000..7c0746746 --- /dev/null +++ b/docs/Sidekiq/Job/UniqueExtension.html @@ -0,0 +1,181 @@ + + + + + + + Module: Sidekiq::Job::UniqueExtension + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Sidekiq::Job::UniqueExtension + + + +

+
+ + + + + + + + + +
+
Included in:
+
Sidekiq::Job
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #delete_extObject + + + + + +

+ + + + +
+
+
+
+59
+60
+61
+62
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 59
+
+def delete_ext
+  delete_orig
+  SidekiqUniqueJobs::Unlockable.unlock(item)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/JobSet.html b/docs/Sidekiq/JobSet.html new file mode 100644 index 000000000..b7fca6ffe --- /dev/null +++ b/docs/Sidekiq/JobSet.html @@ -0,0 +1,147 @@ + + + + + + + Class: Sidekiq::JobSet + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Sidekiq::JobSet + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
UniqueExtension
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + Modules: UniqueExtension + + + + +

+ + + + + + + + + + + + + + +

Method Summary

+ +

Methods included from UniqueExtension

+

#clear_ext, #delete_by_value_ext

+ + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/JobSet/UniqueExtension.html b/docs/Sidekiq/JobSet/UniqueExtension.html new file mode 100644 index 000000000..6ca1c9791 --- /dev/null +++ b/docs/Sidekiq/JobSet/UniqueExtension.html @@ -0,0 +1,233 @@ + + + + + + + Module: Sidekiq::JobSet::UniqueExtension + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Sidekiq::JobSet::UniqueExtension + + + +

+
+ + + + + + + + + +
+
Included in:
+
Sidekiq::JobSet
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #clear_extObject + + + + + +

+ + + + +
+
+
+
+102
+103
+104
+105
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 102
+
+def clear_ext
+  each(&:delete)
+  clear_orig
+end
+
+
+ +
+

+ + #delete_by_value_ext(name, value) ⇒ Object + + + + + +

+ + + + +
+
+
+
+107
+108
+109
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 107
+
+def delete_by_value_ext(name, value)
+  SidekiqUniqueJobs::Unlockable.unlock(Sidekiq.load_json(value)) if delete_by_value_orig(name, value)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/Queue.html b/docs/Sidekiq/Queue.html new file mode 100644 index 000000000..2fe2f4185 --- /dev/null +++ b/docs/Sidekiq/Queue.html @@ -0,0 +1,147 @@ + + + + + + + Class: Sidekiq::Queue + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Sidekiq::Queue + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
UniqueExtension
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + Modules: UniqueExtension + + + + +

+ + + + + + + + + + + + + + +

Method Summary

+ +

Methods included from UniqueExtension

+

#clear_ext

+ + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/Queue/UniqueExtension.html b/docs/Sidekiq/Queue/UniqueExtension.html new file mode 100644 index 000000000..d5cf5ed44 --- /dev/null +++ b/docs/Sidekiq/Queue/UniqueExtension.html @@ -0,0 +1,181 @@ + + + + + + + Module: Sidekiq::Queue::UniqueExtension + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Sidekiq::Queue::UniqueExtension + + + +

+
+ + + + + + + + + +
+
Included in:
+
Sidekiq::Queue
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #clear_extObject + + + + + +

+ + + + +
+
+
+
+77
+78
+79
+80
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 77
+
+def clear_ext
+  each(&:delete)
+  clear_orig
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/ScheduledSet.html b/docs/Sidekiq/ScheduledSet.html new file mode 100644 index 000000000..ffe874782 --- /dev/null +++ b/docs/Sidekiq/ScheduledSet.html @@ -0,0 +1,147 @@ + + + + + + + Class: Sidekiq::ScheduledSet + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Sidekiq::ScheduledSet + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
UniqueExtension
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + Modules: UniqueExtension + + + + +

+ + + + + + + + + + + + + + +

Method Summary

+ +

Methods included from UniqueExtension

+

#delete_ext

+ + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/ScheduledSet/UniqueExtension.html b/docs/Sidekiq/ScheduledSet/UniqueExtension.html new file mode 100644 index 000000000..2092f22c6 --- /dev/null +++ b/docs/Sidekiq/ScheduledSet/UniqueExtension.html @@ -0,0 +1,179 @@ + + + + + + + Module: Sidekiq::ScheduledSet::UniqueExtension + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Sidekiq::ScheduledSet::UniqueExtension + + + +

+
+ + + + + + + + + +
+
Included in:
+
Sidekiq::ScheduledSet
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #delete_extObject + + + + + +

+ + + + +
+
+
+
+43
+44
+45
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 43
+
+def delete_ext
+  SidekiqUniqueJobs::Unlockable.unlock(item) if delete_orig
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/SortedEntry.html b/docs/Sidekiq/SortedEntry.html new file mode 100644 index 000000000..56eaa0829 --- /dev/null +++ b/docs/Sidekiq/SortedEntry.html @@ -0,0 +1,147 @@ + + + + + + + Class: Sidekiq::SortedEntry + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: Sidekiq::SortedEntry + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
UniqueExtension
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + Modules: UniqueExtension + + + + +

+ + + + + + + + + + + + + + +

Method Summary

+ +

Methods included from UniqueExtension

+

#delete_ext

+ + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/SortedEntry/UniqueExtension.html b/docs/Sidekiq/SortedEntry/UniqueExtension.html new file mode 100644 index 000000000..6a72317de --- /dev/null +++ b/docs/Sidekiq/SortedEntry/UniqueExtension.html @@ -0,0 +1,179 @@ + + + + + + + Module: Sidekiq::SortedEntry::UniqueExtension + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Sidekiq::SortedEntry::UniqueExtension + + + +

+
+ + + + + + + + + +
+
Included in:
+
Sidekiq::SortedEntry
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #delete_extObject + + + + + +

+ + + + +
+
+
+
+17
+18
+19
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 17
+
+def delete_ext
+  SidekiqUniqueJobs::Unlockable.unlock(item) if delete_orig
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/Worker.html b/docs/Sidekiq/Worker.html new file mode 100644 index 000000000..a8a3a11d9 --- /dev/null +++ b/docs/Sidekiq/Worker.html @@ -0,0 +1,126 @@ + + + + + + + Module: Sidekiq::Worker + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Sidekiq::Worker + + + +

+
+ + + + + + +
+
Includes:
+
Overrides
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/testing.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + Modules: ClassMethods, Overrides + + + + +

+ + + + + + + + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/Worker/ClassMethods.html b/docs/Sidekiq/Worker/ClassMethods.html new file mode 100644 index 000000000..087333c2d --- /dev/null +++ b/docs/Sidekiq/Worker/ClassMethods.html @@ -0,0 +1,246 @@ + + + + + + + Module: Sidekiq::Worker::ClassMethods + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Sidekiq::Worker::ClassMethods + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/testing.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #clearObject + + + + + +

+ + + + +
+
+
+
+31
+32
+33
+34
+35
+36
+37
+38
+
+
# File 'lib/sidekiq_unique_jobs/testing.rb', line 31
+
+def clear
+  jobs.each do |job|
+    SidekiqUniqueJobs::Unlockable.delete(job)
+  end
+
+  Sidekiq::Queues[queue].clear
+  jobs.clear
+end
+
+
+ +
+

+ + #use_options(tmp_config = {}) ⇒ Object + + + + + +

+ + + + +
+
+
+
+22
+23
+24
+25
+26
+27
+28
+29
+
+
# File 'lib/sidekiq_unique_jobs/testing.rb', line 22
+
+def use_options(tmp_config = {})
+  old_config = get_sidekiq_options
+  sidekiq_options(tmp_config)
+
+  yield
+ensure
+  sidekiq_options(old_config)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/Worker/Overrides.html b/docs/Sidekiq/Worker/Overrides.html new file mode 100644 index 000000000..eaf5e49cf --- /dev/null +++ b/docs/Sidekiq/Worker/Overrides.html @@ -0,0 +1,120 @@ + + + + + + + Module: Sidekiq::Worker::Overrides + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Sidekiq::Worker::Overrides + + + +

+
+ + + + + + + + + +
+
Included in:
+
Sidekiq::Worker
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/testing.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + Modules: Testing + + + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/Sidekiq/Worker/Overrides/Testing.html b/docs/Sidekiq/Worker/Overrides/Testing.html new file mode 100644 index 000000000..f22edd9ae --- /dev/null +++ b/docs/Sidekiq/Worker/Overrides/Testing.html @@ -0,0 +1,176 @@ + + + + + + + Module: Sidekiq::Worker::Overrides::Testing + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: Sidekiq::Worker::Overrides::Testing + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/testing.rb
+
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #clear_all_extObject + + + + + +

+ + + + +
+
+
+
+53
+54
+55
+56
+
+
# File 'lib/sidekiq_unique_jobs/testing.rb', line 53
+
+def clear_all_ext
+  clear_all_orig
+  SidekiqUniqueJobs::Util.del("*", 1000)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs.html b/docs/SidekiqUniqueJobs.html new file mode 100644 index 000000000..e28372f83 --- /dev/null +++ b/docs/SidekiqUniqueJobs.html @@ -0,0 +1,767 @@ + + + + + + + Module: SidekiqUniqueJobs + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs + + + +

+
+ + + + + + +
+
Includes:
+
Connection
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs.rb,
+ lib/sidekiq_unique_jobs/cli.rb,
lib/sidekiq_unique_jobs/job.rb,
lib/sidekiq_unique_jobs/web.rb,
lib/sidekiq_unique_jobs/util.rb,
lib/sidekiq_unique_jobs/digests.rb,
lib/sidekiq_unique_jobs/logging.rb,
lib/sidekiq_unique_jobs/scripts.rb,
lib/sidekiq_unique_jobs/timeout.rb,
lib/sidekiq_unique_jobs/version.rb,
lib/sidekiq_unique_jobs/constants.rb,
lib/sidekiq_unique_jobs/locksmith.rb,
lib/sidekiq_unique_jobs/connection.rb,
lib/sidekiq_unique_jobs/exceptions.rb,
lib/sidekiq_unique_jobs/middleware.rb,
lib/sidekiq_unique_jobs/normalizer.rb,
lib/sidekiq_unique_jobs/unlockable.rb,
lib/sidekiq_unique_jobs/on_conflict.rb,
lib/sidekiq_unique_jobs/unique_args.rb,
lib/sidekiq_unique_jobs/web/helpers.rb,
lib/sidekiq_unique_jobs/lock/base_lock.rb,
lib/sidekiq_unique_jobs/on_conflict/log.rb,
lib/sidekiq_unique_jobs/client/middleware.rb,
lib/sidekiq_unique_jobs/on_conflict/raise.rb,
lib/sidekiq_unique_jobs/server/middleware.rb,
lib/sidekiq_unique_jobs/lock/until_expired.rb,
lib/sidekiq_unique_jobs/on_conflict/reject.rb,
lib/sidekiq_unique_jobs/timeout/calculator.rb,
lib/sidekiq_unique_jobs/lock/until_executed.rb,
lib/sidekiq_unique_jobs/on_conflict/replace.rb,
lib/sidekiq_unique_jobs/lock/until_executing.rb,
lib/sidekiq_unique_jobs/lock/while_executing.rb,
lib/sidekiq_unique_jobs/on_conflict/strategy.rb,
lib/sidekiq_unique_jobs/options_with_fallback.rb,
lib/sidekiq_unique_jobs/on_conflict/reschedule.rb,
lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb,
lib/sidekiq_unique_jobs/on_conflict/null_strategy.rb,
lib/sidekiq_unique_jobs/lock/while_executing_reject.rb,
lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb
+
+
+ +
+ +

Overview

+
+

Module with constants to avoid string duplication

+ + +
+
+
+ +

Author:

+ + +

Defined Under Namespace

+

+ + + Modules: Client, Connection, Digests, Job, Logging, Middleware, Normalizer, OnConflict, OptionsWithFallback, Scripts, Server, SidekiqWorkerMethods, Timeout, Unlockable, Util, Web + + + + Classes: Cli, Conflict, Lock, Locksmith, ScriptError, UniqueArgs, UnknownLock + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
Config = + +
+
Concurrent::MutableStruct.new(
+  :default_lock_timeout,
+  :enabled,
+  :unique_prefix,
+  :logger,
+)
+ +
VERSION = + +
+
"6.0.8"
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from Connection

+

#redis

+ + +
+

Class Method Details

+ + +
+

+ + .configObject + + + + + +

+
+

The current configuration (See: configure on how to configure)

+ + +
+
+
+ + +
+ + + + +
+
+
+
+53
+54
+55
+56
+57
+58
+59
+60
+61
+
+
# File 'lib/sidekiq_unique_jobs.rb', line 53
+
+def config
+  # Arguments here need to match the definition of the new class (see above)
+  @config ||= Config.new(
+    0,
+    true,
+    "uniquejobs",
+    Sidekiq.logger,
+  )
+end
+
+
+ +
+

+ + .configure(options = {}) { ... } ⇒ Object + + + + + +

+
+

Configure the gem

+ +

This is usually called once at startup of an application

+ + +
+
+
+

Parameters:

+
    + +
  • + + options + + + (Hash) + + + (defaults to: {}) + + + — +

    global gem options

    +
    + +
  • + +
+ + + + +

Options Hash (options):

+
    + +
  • + :default_lock_timeout + (Integer) + + + — default: + default is 0 + + + +
  • + +
  • + :enabled + (true, false) + + + — default: + default is true + + + +
  • + +
  • + :unique_prefix + (String) + + + — default: + default is 'uniquejobs' + + + +
  • + +
  • + :logger + (Logger) + + + — default: + default is Sidekiq.logger + + + +
  • + +
+ + +

Yields:

+
    + +
  • + + + + + + + +

    control to the caller when given block

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+95
+96
+97
+98
+99
+100
+101
+102
+103
+
+
# File 'lib/sidekiq_unique_jobs.rb', line 95
+
+def configure(options = {})
+  if block_given?
+    yield config
+  else
+    options.each do |key, val|
+      config.send("#{key}=", val)
+    end
+  end
+end
+
+
+ +
+

+ + .loggerLogger + + + + + +

+
+

The current logger

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Logger) + + + + — +

    the configured logger

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+65
+66
+67
+
+
# File 'lib/sidekiq_unique_jobs.rb', line 65
+
+def logger
+  config.logger
+end
+
+
+ +
+

+ + .logger=(other) ⇒ Object + + + + + +

+
+

Set a new logger

+ + +
+
+
+

Parameters:

+
    + +
  • + + other + + + (Logger) + + + + — +

    a new logger

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+71
+72
+73
+
+
# File 'lib/sidekiq_unique_jobs.rb', line 71
+
+def logger=(other)
+  config.logger = other
+end
+
+
+ +
+

+ + .redis_versionObject + + + + + +

+ + + + +
+
+
+
+105
+106
+107
+
+
# File 'lib/sidekiq_unique_jobs.rb', line 105
+
+def redis_version
+  @redis_version ||= redis { |conn| conn.info("server")["redis_version"] }
+end
+
+
+ +
+

+ + .use_config(tmp_config) { ... } ⇒ Object + + + + + +

+
+

Change global configuration while yielding

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    control to the caller

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (::ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+77
+78
+79
+80
+81
+82
+83
+84
+
+
# File 'lib/sidekiq_unique_jobs.rb', line 77
+
+def use_config(tmp_config)
+  raise ::ArgumentError, "#{name}.#{__method__} needs a block" unless block_given?
+
+  old_config = config.to_h
+  configure(tmp_config)
+  yield
+  configure(old_config)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Cli.html b/docs/SidekiqUniqueJobs/Cli.html new file mode 100644 index 000000000..0978acbd9 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Cli.html @@ -0,0 +1,415 @@ + + + + + + + Class: SidekiqUniqueJobs::Cli + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Cli + + + +

+
+ +
+
Inherits:
+
+ Thor + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/cli.rb
+
+ +
+ +

Overview

+
+

Command line interface for unique jobs

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + +
+

Class Method Details

+ + +
+ + + + + +
+
+
+
+12
+13
+14
+
+
# File 'lib/sidekiq_unique_jobs/cli.rb', line 12
+
+def self.banner(command, _namespace = nil, _subcommand = false)
+  "jobs #{@package_name} #{command.usage}"
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #consoleObject + + + + + +

+ + + + +
+
+
+
+39
+40
+41
+42
+43
+44
+45
+
+
# File 'lib/sidekiq_unique_jobs/cli.rb', line 39
+
+def console
+  say "Use `keys '*', 1000 to display the first 1000 unique keys matching '*'"
+  say "Use `del '*', 1000, true (default) to see how many keys would be deleted for the pattern '*'"
+  say "Use `del '*', 1000, false to delete the first 1000 keys matching '*'"
+  Object.include SidekiqUniqueJobs::Util
+  console_class.start
+end
+
+
+ +
+

+ + #del(pattern) ⇒ Object + + + + + +

+ + + + +
+
+
+
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+
+
# File 'lib/sidekiq_unique_jobs/cli.rb', line 27
+
+def del(pattern)
+  max_count = options[:count]
+  if options[:dry_run]
+    keys = Util.keys(pattern, max_count)
+    say "Would delete #{keys.size} keys matching '#{pattern}'"
+  else
+    deleted_count = Util.del(pattern, max_count)
+    say "Deleted #{deleted_count} keys matching '#{pattern}'"
+  end
+end
+
+
+ +
+

+ + #keys(pattern = "*") ⇒ Object + + + + + +

+ + + + +
+
+
+
+18
+19
+20
+21
+22
+
+
# File 'lib/sidekiq_unique_jobs/cli.rb', line 18
+
+def keys(pattern = "*")
+  keys = Util.keys(pattern, options[:count])
+  say "Found #{keys.size} keys matching '#{pattern}':"
+  print_in_columns(keys.sort) if keys.any?
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Client.html b/docs/SidekiqUniqueJobs/Client.html new file mode 100644 index 000000000..a3a30c03d --- /dev/null +++ b/docs/SidekiqUniqueJobs/Client.html @@ -0,0 +1,115 @@ + + + + + + + Module: SidekiqUniqueJobs::Client + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Client + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/client/middleware.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + + + Classes: Middleware + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Client/Middleware.html b/docs/SidekiqUniqueJobs/Client/Middleware.html new file mode 100644 index 000000000..c198e7ef5 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Client/Middleware.html @@ -0,0 +1,353 @@ + + + + + + + Class: SidekiqUniqueJobs::Client::Middleware + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Client::Middleware + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Logging, OptionsWithFallback
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/client/middleware.rb
+
+ +
+ +

Overview

+
+

The unique sidekiq middleware for the client push

+ + +
+
+
+ +

Author:

+ + +
+ + +

Constant Summary

+ +

Constants included + from OptionsWithFallback

+

OptionsWithFallback::LOCKS

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from OptionsWithFallback

+

#lock, #lock_class, #lock_type, #log_duplicate_payload?, #options, #unique_disabled?, #unique_enabled?, #unique_type

+ + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+ + +
+

Instance Method Details

+ + +
+

+ + #call(worker_class, item, queue, redis_pool = nil) { ... } ⇒ Object + + + + + +

+
+

Calls this client middleware + Used from Sidekiq.process_single

+ + +
+
+
+

Parameters:

+
    + +
  • + + worker_class + + + (String) + + + + — +

    name of the sidekiq worker class

    +
    + +
  • + +
  • + + item + + + (Hash) + + + + — +

    a sidekiq job hash

    +
    + +
  • + +
  • + + queue + + + (String) + + + + — +

    name of the queue

    +
    + +
  • + +
  • + + redis_pool + + + (Sidekiq::RedisConnection, ConnectionPool) + + + (defaults to: nil) + + + — +

    the redis connection

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    when uniqueness is disable or lock successful

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+21
+22
+23
+24
+25
+26
+27
+28
+
+
# File 'lib/sidekiq_unique_jobs/client/middleware.rb', line 21
+
+def call(worker_class, item, queue, redis_pool = nil)
+  @worker_class = worker_class
+  @item         = item
+  @queue        = queue
+  @redis_pool   = redis_pool
+
+  yield if success?
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Conflict.html b/docs/SidekiqUniqueJobs/Conflict.html new file mode 100644 index 000000000..83eac9684 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Conflict.html @@ -0,0 +1,229 @@ + + + + + + + Exception: SidekiqUniqueJobs::Conflict + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Exception: SidekiqUniqueJobs::Conflict + + + +

+
+ +
+
Inherits:
+
+ StandardError + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/exceptions.rb
+
+ +
+ +

Overview

+
+

Error raised when a Lua script fails to execute

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + +
+

Constructor Details

+ +
+

+ + #initialize(item) ⇒ Conflict + + + + + +

+
+

Returns a new instance of Conflict

+ + +
+
+
+ + +
+ + + + +
+
+
+
+8
+9
+10
+
+
# File 'lib/sidekiq_unique_jobs/exceptions.rb', line 8
+
+def initialize(item)
+  super("Item with the key: #{item[UNIQUE_DIGEST_KEY]} is already scheduled or processing")
+end
+
+
+ +
+ + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Connection.html b/docs/SidekiqUniqueJobs/Connection.html new file mode 100644 index 000000000..6dfe2f992 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Connection.html @@ -0,0 +1,240 @@ + + + + + + + Module: SidekiqUniqueJobs::Connection + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Connection + + + +

+
+ + + + + + + + + +
+
Included in:
+
SidekiqUniqueJobs, Digests, Locksmith, Scripts, Util
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/connection.rb
+
+ +
+ +

Overview

+
+

Shared module for dealing with redis connections

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #redis(redis_pool = nil) ⇒ Sidekiq::RedisConnection, ConnectionPool + + + + + +

+
+

Creates a connection to redis

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Sidekiq::RedisConnection, ConnectionPool) + + + + — +

    a connection to redis

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+14
+15
+16
+17
+18
+19
+20
+
+
# File 'lib/sidekiq_unique_jobs/connection.rb', line 14
+
+def redis(redis_pool = nil)
+  if redis_pool
+    redis_pool.with { |conn| yield conn }
+  else
+    Sidekiq.redis { |conn| yield conn }
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Digests.html b/docs/SidekiqUniqueJobs/Digests.html new file mode 100644 index 000000000..5b2313559 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Digests.html @@ -0,0 +1,699 @@ + + + + + + + Module: SidekiqUniqueJobs::Digests + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Digests + + + +

+
+ + + + +
+
Extended by:
+
Digests
+
+ + + +
+
Includes:
+
Connection, Logging
+
+ + + + +
+
Included in:
+
Digests
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/digests.rb
+
+ +
+ +

Overview

+
+

Utility module to help manage unique digests in redis.

+ + +
+
+
+ +

Author:

+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
DEFAULT_COUNT = + +
+
1_000
+ +
SCAN_PATTERN = + +
+
"*"
+ +
CHUNK_SIZE = + +
+
100
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from Connection

+

#redis

+ + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+ + +
+

Instance Method Details

+ + +
+

+ + #all(pattern: SCAN_PATTERN, count: DEFAULT_COUNT) ⇒ Array<String> + + + + + +

+
+

Return unique digests matching pattern

+ + +
+
+
+

Parameters:

+
    + +
  • + + pattern + + + (String) + + + + — +

    a pattern to match with

    +
    + +
  • + +
  • + + count + + + (Integer) + + + + — +

    the maximum number to match

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Array<String>) + + + + — +

    with unique digests

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+21
+22
+23
+
+
# File 'lib/sidekiq_unique_jobs/digests.rb', line 21
+
+def all(pattern: SCAN_PATTERN, count: DEFAULT_COUNT)
+  redis { |conn| conn.sscan_each(UNIQUE_SET, match: pattern, count: count).to_a }
+end
+
+
+ +
+

+ + #countInteger + + + + + +

+
+

Get a total count of unique digests

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    number of digests

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+46
+47
+48
+
+
# File 'lib/sidekiq_unique_jobs/digests.rb', line 46
+
+def count
+  redis { |conn| conn.scard(UNIQUE_SET) }
+end
+
+
+ +
+

+ + #del(digest: nil, pattern: nil, count: DEFAULT_COUNT) ⇒ Array<String> + + + + + +

+
+

Deletes unique digest either by a digest or pattern

+ + +
+
+
+

Parameters:

+
    + +
  • + + digest + + + (String) + + + + — +

    the full digest to delete

    +
    + +
  • + +
  • + + pattern + + + (String) + + + + — +

    a key pattern to match with

    +
    + +
  • + +
  • + + count + + + (Integer) + + + + — +

    the maximum number

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Array<String>) + + + + — +

    with unique digests

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +

    when both pattern and digest are nil

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+57
+58
+59
+60
+61
+62
+
+
# File 'lib/sidekiq_unique_jobs/digests.rb', line 57
+
+def del(digest: nil, pattern: nil, count: DEFAULT_COUNT)
+  return delete_by_pattern(pattern, count: count) if pattern
+  return delete_by_digest(digest) if digest
+
+  raise ArgumentError, "either digest or pattern need to be provided"
+end
+
+
+ +
+

+ + #page(pattern: SCAN_PATTERN, cursor: 0, page_size: 100) ⇒ Array<String> + + + + + +

+
+

Paginate unique digests

+ + +
+
+
+

Parameters:

+
    + +
  • + + pattern + + + (String) + + + + — +

    a pattern to match with

    +
    + +
  • + +
  • + + cursor + + + (Integer) + + + + — +

    the maximum number to match

    +
    + +
  • + +
  • + + page_size + + + (Integer) + + + + — +

    the current cursor position

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Array<String>) + + + + — +

    with unique digests

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+
+
# File 'lib/sidekiq_unique_jobs/digests.rb', line 32
+
+def page(pattern: SCAN_PATTERN, cursor: 0, page_size: 100)
+  redis do |conn|
+    total_size, digests = conn.multi do
+      conn.scard(UNIQUE_SET)
+      conn.sscan(UNIQUE_SET, cursor, match: pattern, count: page_size)
+    end
+
+    [total_size, digests[0], digests[1]]
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Job.html b/docs/SidekiqUniqueJobs/Job.html new file mode 100644 index 000000000..51be59a80 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Job.html @@ -0,0 +1,222 @@ + + + + + + + Module: SidekiqUniqueJobs::Job + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Job + + + +

+
+ + + + +
+
Extended by:
+
Job
+
+ + + + + + +
+
Included in:
+
Job
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/job.rb
+
+ +
+ +

Overview

+
+

Utility class to append uniqueness to the sidekiq job hash

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ +
    + +
  • + + + #add_uniqueness(item) ⇒ void + + + + + + + + + + + + + +

    Adds timeout, expiration, unique_args, unique_prefix and unique_digest to the sidekiq job hash.

    +
    + +
  • + + +
+ + + + +
+

Instance Method Details

+ + +
+

+ + #add_uniqueness(item) ⇒ void + + + + + +

+
+

This method returns an undefined value.

Adds timeout, expiration, unique_args, unique_prefix and unique_digest to the sidekiq job hash

+ + +
+
+
+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+
+
# File 'lib/sidekiq_unique_jobs/job.rb', line 12
+
+def add_uniqueness(item)
+  add_timeout_and_expiration(item)
+  add_unique_args_and_digest(item)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock.html b/docs/SidekiqUniqueJobs/Lock.html new file mode 100644 index 000000000..f0c681ba0 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Lock.html @@ -0,0 +1,133 @@ + + + + + + + Class: SidekiqUniqueJobs::Lock + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Lock + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/lock/base_lock.rb,
+ lib/sidekiq_unique_jobs/lock/until_expired.rb,
lib/sidekiq_unique_jobs/lock/until_executed.rb,
lib/sidekiq_unique_jobs/lock/until_executing.rb,
lib/sidekiq_unique_jobs/lock/while_executing.rb,
lib/sidekiq_unique_jobs/lock/while_executing_reject.rb,
lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb
+
+
+ +
+ +

Defined Under Namespace

+

+ + + + + Classes: BaseLock, UntilAndWhileExecuting, UntilExecuted, UntilExecuting, UntilExpired, WhileExecuting, WhileExecutingReject + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/BaseLock.html b/docs/SidekiqUniqueJobs/Lock/BaseLock.html new file mode 100644 index 000000000..ed6659fd0 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Lock/BaseLock.html @@ -0,0 +1,801 @@ + + + + + + + Class: SidekiqUniqueJobs::Lock::BaseLock + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Lock::BaseLock + Abstract + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
SidekiqUniqueJobs::Logging
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/lock/base_lock.rb
+
+ +
+ +

Overview

+
+
+ This class is abstract. +
+
+

Abstract base class for locks

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from SidekiqUniqueJobs::Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +
+

+ + #initialize(item, callback, redis_pool = nil) ⇒ BaseLock + + + + + +

+
+

Returns a new instance of BaseLock

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    the Sidekiq job hash

    +
    + +
  • + +
  • + + callback + + + (Proc) + + + + — +

    the callback to use after unlock

    +
    + +
  • + +
  • + + redis_pool + + + (Sidekiq::RedisConnection, ConnectionPool) + + + (defaults to: nil) + + + — +

    the redis connection

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+
+
# File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 15
+
+def initialize(item, callback, redis_pool = nil)
+  @item       = item
+  @callback   = callback
+  @redis_pool = redis_pool
+  add_uniqueness_when_missing # Used to ease testing
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #deleteObject + + + + + +

+
+

Deletes the job from redis if it is locked.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+50
+51
+52
+
+
# File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 50
+
+def delete
+  locksmith.delete # Soft delete (don't forcefully remove when expiration is set)
+end
+
+
+ +
+

+ + #delete!Object + + + + + +

+
+

Forcefully deletes the job from redis. + This is good for jobs when a previous lock was not unlocked

+ + +
+
+
+ + +
+ + + + +
+
+
+
+56
+57
+58
+
+
# File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 56
+
+def delete!
+  locksmith.delete! # Force delete the lock
+end
+
+
+ +
+

+ + #executeObject + + + + + +

+
+

Execute the job in the Sidekiq server processor

+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (NotImplementedError) + + + + — +

    needs to be implemented in child class

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+38
+39
+40
+
+
# File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 38
+
+def execute
+  raise NotImplementedError, "##{__method__} needs to be implemented in #{self.class}"
+end
+
+
+ +
+

+ + #lockString + + + + + +

+
+

Handles locking of sidekiq jobs. + Will call a conflict strategy if lock can't be achieved.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    the sidekiq job id

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+
+
# File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 25
+
+def lock
+  @attempt = 0
+  return item[JID_KEY] if locked?
+
+  if (token = locksmith.lock(item[LOCK_TIMEOUT_KEY]))
+    token
+  else
+    call_strategy
+  end
+end
+
+
+ +
+

+ + #locked?true, false + + + + + +

+
+

Checks if the item has achieved a lock

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true) + + + + — +

    when this jid has locked the job

    +
    + +
  • + +
  • + + + (false) + + + + — +

    when this jid has not locked the job

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+63
+64
+65
+
+
# File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 63
+
+def locked?
+  locksmith.locked?(item[JID_KEY])
+end
+
+
+ +
+

+ + #unlockString, false + + + + + +

+
+

Unlocks the job from redis

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    sidekiq job id when successful

    +
    + +
  • + +
  • + + + (false) + + + + — +

    when unsuccessful

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+45
+46
+47
+
+
# File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 45
+
+def unlock
+  locksmith.unlock(item[JID_KEY]) # Only signal to release the lock
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/UntilAndWhileExecuting.html b/docs/SidekiqUniqueJobs/Lock/UntilAndWhileExecuting.html new file mode 100644 index 000000000..ac4d83b2b --- /dev/null +++ b/docs/SidekiqUniqueJobs/Lock/UntilAndWhileExecuting.html @@ -0,0 +1,343 @@ + + + + + + + Class: SidekiqUniqueJobs::Lock::UntilAndWhileExecuting + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Lock::UntilAndWhileExecuting + + + +

+
+ +
+
Inherits:
+
+ BaseLock + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb
+
+ +
+ +

Overview

+
+

Locks jobs while the job is executing in the server process

+ +
    +
  • Locks on perform_in or perform_async (see UntilExecuting)
  • +
  • Unlocks before yielding to the worker's perform method (see UntilExecuting)
  • +
  • Locks before yielding to the worker's perform method (see WhileExecuting)
  • +
  • Unlocks after yielding to the worker's perform method (see WhileExecuting)
  • +
+ +

See BaseLock#lock for more information about the client. +See #execute for more information about the server

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods inherited from BaseLock

+

#delete, #delete!, #initialize, #lock, #locked?, #unlock

+ + + + + + + + + +

Methods included from SidekiqUniqueJobs::Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +

This class inherits a constructor from SidekiqUniqueJobs::Lock::BaseLock

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #execute { ... } ⇒ Object + + + + + +

+
+

Executes in the Sidekiq server process

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    to the worker class perform method

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+18
+19
+20
+21
+22
+23
+24
+
+
# File 'lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb', line 18
+
+def execute
+  return unless locked?
+
+  unlock
+
+  runtime_lock.execute { yield }
+end
+
+
+ +
+

+ + #runtime_lockObject + + + + + +

+ + + + +
+
+
+
+26
+27
+28
+
+
# File 'lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb', line 26
+
+def runtime_lock
+  @runtime_lock ||= SidekiqUniqueJobs::Lock::WhileExecuting.new(item, callback, redis_pool)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/UntilExecuted.html b/docs/SidekiqUniqueJobs/Lock/UntilExecuted.html new file mode 100644 index 000000000..709d242f5 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Lock/UntilExecuted.html @@ -0,0 +1,282 @@ + + + + + + + Class: SidekiqUniqueJobs::Lock::UntilExecuted + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Lock::UntilExecuted + + + +

+
+ +
+
Inherits:
+
+ BaseLock + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/lock/until_executed.rb
+
+ +
+ +

Overview

+
+

Locks jobs until the server is done executing the job

+ +
    +
  • Locks on perform_in or perform_async
  • +
  • Unlocks after yielding to the worker's perform method
  • +
+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods inherited from BaseLock

+

#delete, #delete!, #initialize, #lock, #locked?, #unlock

+ + + + + + + + + +

Methods included from SidekiqUniqueJobs::Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +

This class inherits a constructor from SidekiqUniqueJobs::Lock::BaseLock

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #execute { ... } ⇒ Object + + + + + +

+
+

Executes in the Sidekiq server process

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    to the worker class perform method

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+15
+16
+17
+18
+19
+
+
# File 'lib/sidekiq_unique_jobs/lock/until_executed.rb', line 15
+
+def execute
+  return unless locked?
+
+  with_cleanup { yield }
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/UntilExecuting.html b/docs/SidekiqUniqueJobs/Lock/UntilExecuting.html new file mode 100644 index 000000000..56bc38212 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Lock/UntilExecuting.html @@ -0,0 +1,280 @@ + + + + + + + Class: SidekiqUniqueJobs::Lock::UntilExecuting + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Lock::UntilExecuting + + + +

+
+ +
+
Inherits:
+
+ BaseLock + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/lock/until_executing.rb
+
+ +
+ +

Overview

+
+

Locks jobs until #execute starts

+ +
    +
  • Locks on perform_in or perform_async
  • +
  • Unlocks before yielding to the worker's perform method
  • +
+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods inherited from BaseLock

+

#delete, #delete!, #initialize, #lock, #locked?, #unlock

+ + + + + + + + + +

Methods included from SidekiqUniqueJobs::Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +

This class inherits a constructor from SidekiqUniqueJobs::Lock::BaseLock

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #execute { ... } ⇒ Object + + + + + +

+
+

Executes in the Sidekiq server process

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    to the worker class perform method

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+13
+14
+15
+16
+
+
# File 'lib/sidekiq_unique_jobs/lock/until_executing.rb', line 13
+
+def execute
+  unlock_with_callback
+  yield
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/UntilExpired.html b/docs/SidekiqUniqueJobs/Lock/UntilExpired.html new file mode 100644 index 000000000..2087cad2b --- /dev/null +++ b/docs/SidekiqUniqueJobs/Lock/UntilExpired.html @@ -0,0 +1,367 @@ + + + + + + + Class: SidekiqUniqueJobs::Lock::UntilExpired + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Lock::UntilExpired + + + +

+
+ +
+
Inherits:
+
+ BaseLock + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/lock/until_expired.rb
+
+ +
+ +

Overview

+
+

Locks jobs until the lock has expired

+ +
    +
  • Locks on perform_in or perform_async
  • +
  • Unlocks when the expiration is hit
  • +
+ +

See BaseLock#lock for more information about the client. +See #execute for more information about the server

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods inherited from BaseLock

+

#delete, #delete!, #initialize, #lock, #locked?

+ + + + + + + + + +

Methods included from SidekiqUniqueJobs::Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +

This class inherits a constructor from SidekiqUniqueJobs::Lock::BaseLock

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #execute { ... } ⇒ Object + + + + + +

+
+

Executes in the Sidekiq server process

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    to the worker class perform method

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+22
+23
+24
+25
+26
+27
+
+
# File 'lib/sidekiq_unique_jobs/lock/until_expired.rb', line 22
+
+def execute
+  return unless locked?
+
+  yield
+  # this lock does not handle after_unlock since we don't know when that would happen
+end
+
+
+ +
+

+ + #unlocktrue + + + + + +

+
+

Prevents these locks from being unlocked

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true) + + + + — +

    always returns true

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+16
+17
+18
+
+
# File 'lib/sidekiq_unique_jobs/lock/until_expired.rb', line 16
+
+def unlock
+  true
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/WhileExecuting.html b/docs/SidekiqUniqueJobs/Lock/WhileExecuting.html new file mode 100644 index 000000000..382e9c755 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Lock/WhileExecuting.html @@ -0,0 +1,487 @@ + + + + + + + Class: SidekiqUniqueJobs::Lock::WhileExecuting + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Lock::WhileExecuting + + + +

+
+ +
+
Inherits:
+
+ BaseLock + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/lock/while_executing.rb
+
+ +
+ +

Overview

+
+

Locks jobs while the job is executing in the server process

+ +
    +
  • Locks before yielding to the worker's perform method
  • +
  • Unlocks after yielding to the worker's perform method
  • +
+ +

See #lock for more information about the client. +See #execute for more information about the server

+ + +
+
+
+ +

Author:

+ + +
+

Direct Known Subclasses

+

WhileExecutingReject

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods inherited from BaseLock

+

#delete, #delete!, #locked?, #unlock

+ + + + + + + + + +

Methods included from SidekiqUniqueJobs::Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +
+

+ + #initialize(item, callback, redis_pool = nil) ⇒ WhileExecuting + + + + + +

+
+

Returns a new instance of WhileExecuting

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    the Sidekiq job hash

    +
    + +
  • + +
  • + + callback + + + (Proc) + + + + — +

    callback to call after unlock

    +
    + +
  • + +
  • + + redis_pool + + + (Sidekiq::RedisConnection, ConnectionPool) + + + (defaults to: nil) + + + — +

    the redis connection

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+19
+20
+21
+22
+
+
# File 'lib/sidekiq_unique_jobs/lock/while_executing.rb', line 19
+
+def initialize(item, callback, redis_pool = nil)
+  super(item, callback, redis_pool)
+  append_unique_key_suffix
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #execute { ... } ⇒ Object + + + + + +

+
+

Executes in the Sidekiq server process. + These jobs are locked in the server process not from the client

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    to the worker class perform method

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+34
+35
+36
+37
+38
+
+
# File 'lib/sidekiq_unique_jobs/lock/while_executing.rb', line 34
+
+def execute
+  return strategy.call unless locksmith.lock(item[LOCK_TIMEOUT_KEY])
+
+  with_cleanup { yield }
+end
+
+
+ +
+

+ + #locktrue + + + + + +

+
+

Simulate that a client lock was achieved. + These locks should only ever be created in the server process.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true) + + + + — +

    always returns true

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/sidekiq_unique_jobs/lock/while_executing.rb', line 27
+
+def lock
+  true
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/WhileExecutingReject.html b/docs/SidekiqUniqueJobs/Lock/WhileExecutingReject.html new file mode 100644 index 000000000..78187b4bd --- /dev/null +++ b/docs/SidekiqUniqueJobs/Lock/WhileExecutingReject.html @@ -0,0 +1,375 @@ + + + + + + + Class: SidekiqUniqueJobs::Lock::WhileExecutingReject + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Lock::WhileExecutingReject + + + +

+
+ +
+
Inherits:
+
+ WhileExecuting + + + show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/lock/while_executing_reject.rb
+
+ +
+ +

Overview

+
+

Locks jobs while executing + Locks from the server process + Unlocks after the server is done processing

+ +

See SidekiqUniqueJobs::Lock::WhileExecuting#lock for more information about the client. +See #execute for more information about the server

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods inherited from WhileExecuting

+

#initialize, #lock

+ + + + + + + + + +

Methods inherited from BaseLock

+

#delete, #delete!, #initialize, #lock, #locked?, #unlock

+ + + + + + + + + +

Methods included from SidekiqUniqueJobs::Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +

This class inherits a constructor from SidekiqUniqueJobs::Lock::WhileExecuting

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #execute { ... } ⇒ Object + + + + + +

+
+

Executes in the Sidekiq server process

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    to the worker class perform method

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+16
+17
+18
+19
+20
+
+
# File 'lib/sidekiq_unique_jobs/lock/while_executing_reject.rb', line 16
+
+def execute
+  return strategy.call unless locksmith.lock(item[LOCK_TIMEOUT_KEY])
+
+  with_cleanup { yield }
+end
+
+
+ +
+

+ + #strategyOnConflict::Reject + + + + + +

+
+

Overridden with a forced OnConflict::Reject strategy

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+24
+25
+26
+
+
# File 'lib/sidekiq_unique_jobs/lock/while_executing_reject.rb', line 24
+
+def strategy
+  @strategy ||= OnConflict.find_strategy(:reject).new(item)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Locksmith.html b/docs/SidekiqUniqueJobs/Locksmith.html new file mode 100644 index 000000000..8bb710a8d --- /dev/null +++ b/docs/SidekiqUniqueJobs/Locksmith.html @@ -0,0 +1,1082 @@ + + + + + + + Class: SidekiqUniqueJobs::Locksmith + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Locksmith + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Connection
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/locksmith.rb
+
+ +
+ +

Overview

+
+

Lock manager class that handles all the various locks

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from Connection

+

#redis

+
+

Constructor Details

+ +
+

+ + #initialize(item, redis_pool = nil) ⇒ Locksmith + + + + + +

+
+

Returns a new instance of Locksmith

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    a Sidekiq job hash

    +
    + +
  • + +
  • + + redis_pool + + + (Sidekiq::RedisConnection, ConnectionPool) + + + (defaults to: nil) + + + — +

    the redis connection

    +
    + +
  • + +
+ + + + +

Options Hash (item):

+
    + +
  • + :lock_expiration + (Integer) + + + + + —

    the configured expiration

    +
    + +
  • + +
  • + :jid + (String) + + + + + —

    the sidekiq job id

    +
    + +
  • + +
  • + :unique_digest + (String) + + + + + —

    the unique digest (See: UniqueArgs#unique_digest)

    +
    + +
  • + +
+ + + + + +
+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+21
+
+
# File 'lib/sidekiq_unique_jobs/locksmith.rb', line 15
+
+def initialize(item, redis_pool = nil)
+  @concurrency   = 1 # removed in a0cff5bc42edbe7190d6ede7e7f845074d2d7af6
+  @expiration    = item[LOCK_EXPIRATION_KEY]
+  @jid           = item[JID_KEY]
+  @unique_digest = item[UNIQUE_DIGEST_KEY]
+  @redis_pool    = redis_pool
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #available_countInteger + + + + + +

+
+

The number of available resourced for this lock

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    the number of available resources

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+31
+32
+33
+34
+35
+
+
# File 'lib/sidekiq_unique_jobs/locksmith.rb', line 31
+
+def available_count
+  return concurrency unless exists?
+
+  redis(redis_pool) { |conn| conn.llen(available_key) }
+end
+
+
+ +
+

+ + #deleteObject + + + + + +

+
+

Deletes the lock unless it has an expiration set

+ + +
+
+
+ + +
+ + + + +
+
+
+
+38
+39
+40
+41
+42
+
+
# File 'lib/sidekiq_unique_jobs/locksmith.rb', line 38
+
+def delete
+  return if expiration
+
+  delete!
+end
+
+
+ +
+

+ + #delete!Object + + + + + +

+
+

Deletes the lock regardless of if it has an expiration set

+ + +
+
+
+ + +
+ + + + +
+
+
+
+45
+46
+47
+48
+49
+50
+51
+
+
# File 'lib/sidekiq_unique_jobs/locksmith.rb', line 45
+
+def delete!
+  Scripts.call(
+    :delete,
+    redis_pool,
+    keys: [exists_key, grabbed_key, available_key, version_key, UNIQUE_SET, unique_digest],
+  )
+end
+
+
+ +
+

+ + #exists?true, false + + + + + +

+
+

Checks if the exists key is created in redis

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+25
+26
+27
+
+
# File 'lib/sidekiq_unique_jobs/locksmith.rb', line 25
+
+def exists?
+  redis(redis_pool) { |conn| conn.exists(exists_key) }
+end
+
+
+ +
+

+ + #lock(timeout = nil) { ... } ⇒ Object + + + + Also known as: + wait + + + + +

+
+

Create a lock for the item

+ + +
+
+
+

Parameters:

+
    + +
  • + + timeout + + + (Integer) + + + (defaults to: nil) + + + — +

    the number of seconds to wait for a lock. +nil means wait indefinitely

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    the block to execute if a lock is successful

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + + + + + +

    the Sidekiq job_id (jid)

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+
+
# File 'lib/sidekiq_unique_jobs/locksmith.rb', line 58
+
+def lock(timeout = nil, &block)
+  Scripts.call(:lock, redis_pool,
+               keys: [exists_key, grabbed_key, available_key, UNIQUE_SET, unique_digest],
+               argv: [jid, expiration])
+
+  grab_token(timeout) do |token|
+    touch_grabbed_token(token)
+    return_token_or_block_value(token, &block)
+  end
+end
+
+
+ +
+

+ + #locked?(token = nil) ⇒ true, false + + + + + +

+
+

Checks if this instance is considered locked

+ + +
+
+
+

Parameters:

+
    + +
  • + + token + + + (String) + + + (defaults to: nil) + + + — +

    the unique token to check for a lock. +nil will default to the jid provided in the initializer

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+98
+99
+100
+101
+
+
# File 'lib/sidekiq_unique_jobs/locksmith.rb', line 98
+
+def locked?(token = nil)
+  token ||= jid
+  redis(redis_pool) { |conn| conn.hexists(grabbed_key, token) }
+end
+
+
+ +
+

+ + #unlock(token = nil) ⇒ false, String + + + + + +

+
+

Removes the lock keys from Redis if locked by the provided jid/token

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (false) + + + + — +

    unless locked?

    +
    + +
  • + +
  • + + + (String) + + + + — +

    Sidekiq job_id (jid) if successful

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+73
+74
+75
+76
+77
+78
+
+
# File 'lib/sidekiq_unique_jobs/locksmith.rb', line 73
+
+def unlock(token = nil)
+  token ||= jid
+  return false unless locked?(token)
+
+  unlock!(token)
+end
+
+
+ +
+

+ + #unlock!(token = nil) ⇒ false, String + + + + + +

+
+

Removes the lock keys from Redis

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (false) + + + + — +

    unless locked?

    +
    + +
  • + +
  • + + + (String) + + + + — +

    Sidekiq job_id (jid) if successful

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+
+
# File 'lib/sidekiq_unique_jobs/locksmith.rb', line 83
+
+def unlock!(token = nil)
+  token ||= jid
+
+  Scripts.call(
+    :unlock,
+    redis_pool,
+    keys: [exists_key, grabbed_key, available_key, version_key, UNIQUE_SET, unique_digest],
+    argv: [token, expiration],
+  )
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Logging.html b/docs/SidekiqUniqueJobs/Logging.html new file mode 100644 index 000000000..387d4e2f1 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Logging.html @@ -0,0 +1,779 @@ + + + + + + + Module: SidekiqUniqueJobs::Logging + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Logging + + + +

+
+ + + + + + + + + +
+
Included in:
+
Client::Middleware, Digests, SidekiqUniqueJobs::Lock::BaseLock, OnConflict::Log, OnConflict::Strategy, Server::Middleware, UniqueArgs, Util
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/logging.rb
+
+ +
+ +

Overview

+
+

Utility module for reducing the number of uses of logger.

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #log_debug(message_or_exception = nil) { ... } ⇒ Object + + + + + +

+
+

Logs a message at debug level

+ + +
+
+
+

Parameters:

+
    + +
  • + + message_or_exception + + + (String, Exception) + + + (defaults to: nil) + + + — +

    the message or exception to log

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    the message or exception to use for log message +Used for compatibility with logger

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+17
+18
+19
+
+
# File 'lib/sidekiq_unique_jobs/logging.rb', line 17
+
+def log_debug(message_or_exception = nil, &block)
+  logger.debug(message_or_exception, &block)
+end
+
+
+ +
+

+ + #log_error(message_or_exception = nil) { ... } ⇒ Object + + + + + +

+
+

Logs a message at error level

+ + +
+
+
+

Parameters:

+
    + +
  • + + message_or_exception + + + (String, Exception) + + + (defaults to: nil) + + + — +

    the message or exception to log

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    the message or exception to use for log message +Used for compatibility with logger

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+41
+42
+43
+
+
# File 'lib/sidekiq_unique_jobs/logging.rb', line 41
+
+def log_error(message_or_exception = nil, &block)
+  logger.error(message_or_exception, &block)
+end
+
+
+ +
+

+ + #log_fatal(message_or_exception = nil) { ... } ⇒ Object + + + + + +

+
+

Logs a message at fatal level

+ + +
+
+
+

Parameters:

+
    + +
  • + + message_or_exception + + + (String, Exception) + + + (defaults to: nil) + + + — +

    the message or exception to log

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    the message or exception to use for log message +Used for compatibility with logger

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+49
+50
+51
+
+
# File 'lib/sidekiq_unique_jobs/logging.rb', line 49
+
+def log_fatal(message_or_exception = nil, &block)
+  logger.fatal(message_or_exception, &block)
+end
+
+
+ +
+

+ + #log_info(message_or_exception = nil) { ... } ⇒ Object + + + + + +

+
+

Logs a message at info level

+ + +
+
+
+

Parameters:

+
    + +
  • + + message_or_exception + + + (String, Exception) + + + (defaults to: nil) + + + — +

    the message or exception to log

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    the message or exception to use for log message +Used for compatibility with logger

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+25
+26
+27
+
+
# File 'lib/sidekiq_unique_jobs/logging.rb', line 25
+
+def log_info(message_or_exception = nil, &block)
+  logger.info(message_or_exception, &block)
+end
+
+
+ +
+

+ + #log_warn(message_or_exception = nil) { ... } ⇒ Object + + + + + +

+
+

Logs a message at warn level

+ + +
+
+
+

Parameters:

+
    + +
  • + + message_or_exception + + + (String, Exception) + + + (defaults to: nil) + + + — +

    the message or exception to log

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    the message or exception to use for log message +Used for compatibility with logger

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+33
+34
+35
+
+
# File 'lib/sidekiq_unique_jobs/logging.rb', line 33
+
+def log_warn(message_or_exception = nil, &block)
+  logger.warn(message_or_exception, &block)
+end
+
+
+ +
+

+ + #loggerObject + + + + + +

+
+

A convenience method for using the configured logger

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/sidekiq_unique_jobs/logging.rb', line 9
+
+def logger
+  SidekiqUniqueJobs.logger
+end
+
+
+ +
+

+ + #logging_context(middleware_class, job_hash) ⇒ Object + + + + + +

+ + + + +
+
+
+
+53
+54
+55
+56
+
+
# File 'lib/sidekiq_unique_jobs/logging.rb', line 53
+
+def logging_context(middleware_class, job_hash)
+  digest = job_hash["unique_digest"]
+  "#{middleware_class} #{"DIG-#{digest}" if digest}"
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Middleware.html b/docs/SidekiqUniqueJobs/Middleware.html new file mode 100644 index 000000000..f13fc9b50 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Middleware.html @@ -0,0 +1,335 @@ + + + + + + + Module: SidekiqUniqueJobs::Middleware + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Middleware + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/middleware.rb
+
+ +
+ +

Overview

+
+

Provides the sidekiq middleware that makes the gem work

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #configure_client_middlewareObject + + + + + +

+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+
+
# File 'lib/sidekiq_unique_jobs/middleware.rb', line 37
+
+def configure_client_middleware
+  Sidekiq.configure_client do |config|
+    config.client_middleware do |chain|
+      require "sidekiq_unique_jobs/client/middleware"
+      chain.add SidekiqUniqueJobs::Client::Middleware
+    end
+  end
+end
+
+
+ +
+

+ + #configure_middlewareObject + + + + + +

+ + + + +
+
+
+
+18
+19
+20
+21
+
+
# File 'lib/sidekiq_unique_jobs/middleware.rb', line 18
+
+def configure_middleware
+  configure_server_middleware
+  configure_client_middleware
+end
+
+
+ +
+

+ + #configure_server_middlewareObject + + + + + +

+ + + + +
+
+
+
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+
+
# File 'lib/sidekiq_unique_jobs/middleware.rb', line 23
+
+def configure_server_middleware
+  Sidekiq.configure_server do |config|
+    config.client_middleware do |chain|
+      require "sidekiq_unique_jobs/client/middleware"
+      chain.add SidekiqUniqueJobs::Client::Middleware
+    end
+
+    config.server_middleware do |chain|
+      require "sidekiq_unique_jobs/server/middleware"
+      chain.add SidekiqUniqueJobs::Server::Middleware
+    end
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Normalizer.html b/docs/SidekiqUniqueJobs/Normalizer.html new file mode 100644 index 000000000..621959ec6 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Normalizer.html @@ -0,0 +1,242 @@ + + + + + + + Module: SidekiqUniqueJobs::Normalizer + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Normalizer + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/normalizer.rb
+
+ +
+ +

Overview

+
+

Normalizes hashes by dumping them to json and loading them from json

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .jsonify(args) ⇒ Hash + + + + + +

+
+

Changes hash to a json compatible hash

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Hash) + + + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Hash) + + + + — +

    a json compatible hash

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+13
+14
+15
+
+
# File 'lib/sidekiq_unique_jobs/normalizer.rb', line 13
+
+def self.jsonify(args)
+  Sidekiq.load_json(Sidekiq.dump_json(args))
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict.html b/docs/SidekiqUniqueJobs/OnConflict.html new file mode 100644 index 000000000..e0cdcd608 --- /dev/null +++ b/docs/SidekiqUniqueJobs/OnConflict.html @@ -0,0 +1,244 @@ + + + + + + + Module: SidekiqUniqueJobs::OnConflict + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::OnConflict + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/on_conflict.rb,
+ lib/sidekiq_unique_jobs/on_conflict/log.rb,
lib/sidekiq_unique_jobs/on_conflict/raise.rb,
lib/sidekiq_unique_jobs/on_conflict/reject.rb,
lib/sidekiq_unique_jobs/on_conflict/replace.rb,
lib/sidekiq_unique_jobs/on_conflict/strategy.rb,
lib/sidekiq_unique_jobs/on_conflict/reschedule.rb,
lib/sidekiq_unique_jobs/on_conflict/null_strategy.rb
+
+
+ +
+ +

Overview

+
+

Provides lock conflict resolutions

+ + +
+
+
+ +

Author:

+ + +

Defined Under Namespace

+

+ + + + + Classes: Log, NullStrategy, Raise, Reject, Replace, Reschedule, Strategy + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
STRATEGIES = + +
+
{
+  log: OnConflict::Log,
+  raise: OnConflict::Raise,
+  reject: OnConflict::Reject,
+  replace: OnConflict::Replace,
+  reschedule: OnConflict::Reschedule,
+}.freeze
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .find_strategy(strategy) ⇒ Object + + + + + +

+
+

returns OnConflict::NullStrategy when no other could be found

+ + +
+
+
+ + +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict.rb', line 27
+
+def self.find_strategy(strategy)
+  STRATEGIES.fetch(strategy.to_s.to_sym) { OnConflict::NullStrategy }
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Log.html b/docs/SidekiqUniqueJobs/OnConflict/Log.html new file mode 100644 index 000000000..184cb8e26 --- /dev/null +++ b/docs/SidekiqUniqueJobs/OnConflict/Log.html @@ -0,0 +1,272 @@ + + + + + + + Class: SidekiqUniqueJobs::OnConflict::Log + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::OnConflict::Log + + + +

+
+ +
+
Inherits:
+
+ Strategy + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Logging
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/on_conflict/log.rb
+
+ +
+ +

Overview

+
+

Strategy to log information about conflict

+ + +
+
+
+ +

Author:

+ + +
+ + + + + +

Instance Attribute Summary

+ +

Attributes inherited from Strategy

+

#item

+ + + +

+ Instance Method Summary + collapse +

+ +
    + +
  • + + + #call ⇒ Object + + + + + + + + + + + + + +

    Logs an informational message about that the job was not unique.

    +
    + +
  • + + +
+ + + + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+ + + + + + + + + +

Methods inherited from Strategy

+

#initialize, #replace?

+
+

Constructor Details

+ +

This class inherits a constructor from SidekiqUniqueJobs::OnConflict::Strategy

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #callObject + + + + + +

+
+

Logs an informational message about that the job was not unique

+ + +
+
+
+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+16
+17
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/log.rb', line 12
+
+def call
+  log_info(
+    "skipping job with id (#{item[JID_KEY]}) " \
+    "because unique_digest: (#{item[UNIQUE_DIGEST_KEY]}) already exists",
+  )
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/NullStrategy.html b/docs/SidekiqUniqueJobs/OnConflict/NullStrategy.html new file mode 100644 index 000000000..18e9ad498 --- /dev/null +++ b/docs/SidekiqUniqueJobs/OnConflict/NullStrategy.html @@ -0,0 +1,274 @@ + + + + + + + Class: SidekiqUniqueJobs::OnConflict::NullStrategy + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::OnConflict::NullStrategy + + + +

+
+ +
+
Inherits:
+
+ Strategy + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/on_conflict/null_strategy.rb
+
+ +
+ +

Overview

+
+

Default conflict strategy class that does nothing

+ + +
+
+
+ +

Author:

+ + +
+ + + + + +

Instance Attribute Summary

+ +

Attributes inherited from Strategy

+

#item

+ + + +

+ Instance Method Summary + collapse +

+ +
    + +
  • + + + #call ⇒ nil + + + + + + + + + + + + + +

    Do nothing on conflict.

    +
    + +
  • + + +
+ + + + + + + + + + + +

Methods inherited from Strategy

+

#initialize, #replace?

+ + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +

This class inherits a constructor from SidekiqUniqueJobs::OnConflict::Strategy

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #callnil + + + + + +

+
+

Do nothing on conflict

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (nil) + + + +
  • + +
+ +
+ + + + +
+
+
+
+11
+12
+13
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/null_strategy.rb', line 11
+
+def call
+  # NOOP
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Raise.html b/docs/SidekiqUniqueJobs/OnConflict/Raise.html new file mode 100644 index 000000000..b2ed7fac7 --- /dev/null +++ b/docs/SidekiqUniqueJobs/OnConflict/Raise.html @@ -0,0 +1,275 @@ + + + + + + + Class: SidekiqUniqueJobs::OnConflict::Raise + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::OnConflict::Raise + + + +

+
+ +
+
Inherits:
+
+ Strategy + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/on_conflict/raise.rb
+
+ +
+ +

Overview

+
+

Strategy to raise an error on conflict

+ + +
+
+
+ +

Author:

+ + +
+ + + + + +

Instance Attribute Summary

+ +

Attributes inherited from Strategy

+

#item

+ + + +

+ Instance Method Summary + collapse +

+ +
    + +
  • + + + #call ⇒ Object + + + + + + + + + + + + + +

    Raise an error on conflict.

    +
    + +
  • + + +
+ + + + + + + + + + + +

Methods inherited from Strategy

+

#initialize, #replace?

+ + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +

This class inherits a constructor from SidekiqUniqueJobs::OnConflict::Strategy

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #callObject + + + + + +

+
+

Raise an error on conflict. + This will cause Sidekiq to retry the job

+ + +
+
+
+ +

Raises:

+ + +
+ + + + +
+
+
+
+12
+13
+14
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/raise.rb', line 12
+
+def call
+  raise SidekiqUniqueJobs::Conflict, item
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Reject.html b/docs/SidekiqUniqueJobs/OnConflict/Reject.html new file mode 100644 index 000000000..7bacc5318 --- /dev/null +++ b/docs/SidekiqUniqueJobs/OnConflict/Reject.html @@ -0,0 +1,859 @@ + + + + + + + Class: SidekiqUniqueJobs::OnConflict::Reject + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::OnConflict::Reject + + + +

+
+ +
+
Inherits:
+
+ Strategy + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/on_conflict/reject.rb
+
+ +
+ +

Overview

+
+

Strategy to send jobs to dead queue

+ + +
+
+
+ +

Author:

+ + +
+ + + + + +

Instance Attribute Summary

+ +

Attributes inherited from Strategy

+

#item

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods inherited from Strategy

+

#initialize, #replace?

+ + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +

This class inherits a constructor from SidekiqUniqueJobs::OnConflict::Strategy

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #callObject + + + + + +

+
+

Send jobs to dead queue

+ + +
+
+
+ + +
+ + + + +
+
+
+
+10
+11
+12
+13
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 10
+
+def call
+  log_debug { "Rejecting job with jid: #{item[JID_KEY]}" }
+  send_to_deadset
+end
+
+
+ +
+

+ + #current_timeObject + + + + + +

+ + + + +
+
+
+
+63
+64
+65
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 63
+
+def current_time
+  @current_time ||= Time.now.to_f
+end
+
+
+ +
+

+ + #deadsetObject + + + + + +

+ + + + +
+
+
+
+49
+50
+51
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 49
+
+def deadset
+  @deadset ||= Sidekiq::DeadSet.new
+end
+
+
+ +
+

+ + #deadset_killObject + + + + + +

+ + + + +
+
+
+
+29
+30
+31
+32
+33
+34
+35
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 29
+
+def deadset_kill
+  if kill_with_options?
+    kill_job_with_options
+  else
+    kill_job_without_options
+  end
+end
+
+
+ +
+

+ + #deadset_kill?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+25
+26
+27
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 25
+
+def deadset_kill?
+  deadset.respond_to?(:kill)
+end
+
+
+ +
+

+ + #kill_job_with_optionsObject + + + + + +

+ + + + +
+
+
+
+45
+46
+47
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 45
+
+def kill_job_with_options
+  deadset.kill(payload, notify_failure: false)
+end
+
+
+ +
+

+ + #kill_job_without_optionsObject + + + + + +

+ + + + +
+
+
+
+41
+42
+43
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 41
+
+def kill_job_without_options
+  deadset.kill(payload)
+end
+
+
+ +
+

+ + #kill_with_options?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 37
+
+def kill_with_options?
+  Sidekiq::DeadSet.instance_method(:kill).arity > 1
+end
+
+
+ +
+

+ + #payloadObject + + + + + +

+ + + + +
+
+
+
+67
+68
+69
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 67
+
+def payload
+  @payload ||= Sidekiq.dump_json(item)
+end
+
+
+ +
+

+ + #push_to_deadsetObject + + + + + +

+ + + + +
+
+
+
+53
+54
+55
+56
+57
+58
+59
+60
+61
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 53
+
+def push_to_deadset
+  Sidekiq.redis do |conn|
+    conn.multi do
+      conn.zadd("dead", current_time, payload)
+      conn.zremrangebyscore("dead", "-inf", current_time - Sidekiq::DeadSet.timeout)
+      conn.zremrangebyrank("dead", 0, -Sidekiq::DeadSet.max_jobs)
+    end
+  end
+end
+
+
+ +
+

+ + #send_to_deadsetObject + + + + + +

+ + + + +
+
+
+
+15
+16
+17
+18
+19
+20
+21
+22
+23
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 15
+
+def send_to_deadset
+  log_info { "Adding dead #{item[CLASS_KEY]} job #{item[JID_KEY]}" }
+
+  if deadset_kill?
+    deadset_kill
+  else
+    push_to_deadset
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Replace.html b/docs/SidekiqUniqueJobs/OnConflict/Replace.html new file mode 100644 index 000000000..6b472e2f6 --- /dev/null +++ b/docs/SidekiqUniqueJobs/OnConflict/Replace.html @@ -0,0 +1,654 @@ + + + + + + + Class: SidekiqUniqueJobs::OnConflict::Replace + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::OnConflict::Replace + + + +

+
+ +
+
Inherits:
+
+ Strategy + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/on_conflict/replace.rb
+
+ +
+ +

Overview

+
+

Strategy to replace the job on conflict

+ + +
+
+
+ +

Author:

+ + +
+ + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #queue ⇒ Object + + + + + + + + + readonly + + + + + + + + + +

    Returns the value of attribute queue.

    +
    + +
  • + + +
  • + + + #unique_digest ⇒ Object + + + + + + + + + readonly + + + + + + + + + +

    Returns the value of attribute unique_digest.

    +
    + +
  • + + +
+ + + + + +

Attributes inherited from Strategy

+

#item

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods inherited from Strategy

+

#replace?

+ + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +
+

+ + #initialize(item) ⇒ Replace + + + + + +

+
+

Returns a new instance of Replace

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    sidekiq job hash

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+16
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 12
+
+def initialize(item)
+  super
+  @queue         = item[QUEUE_KEY]
+  @unique_digest = item[UNIQUE_DIGEST_KEY]
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #queueObject (readonly) + + + + + +

+
+

Returns the value of attribute queue

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 9
+
+def queue
+  @queue
+end
+
+
+ + + +
+

+ + #unique_digestObject (readonly) + + + + + +

+
+

Returns the value of attribute unique_digest

+ + +
+
+
+ + +
+ + + + +
+
+
+
+9
+10
+11
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 9
+
+def unique_digest
+  @unique_digest
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #call { ... } ⇒ Object + + + + + +

+
+

Replace the old job in the queue

+ + +
+
+
+ +

Yields:

+
    + +
  • + + + + + + + +

    to retry the lock after deleting the old one

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+20
+21
+22
+23
+24
+25
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 20
+
+def call(&block)
+  return unless delete_job_by_digest
+
+  delete_lock
+  block&.call
+end
+
+
+ +
+

+ + #delete_job_by_digestObject + + + + + +

+
+

Delete the job from either schedule, retry or the queue

+ + +
+
+
+ + +
+ + + + +
+
+
+
+28
+29
+30
+31
+32
+33
+34
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 28
+
+def delete_job_by_digest
+  Scripts.call(
+    :delete_job_by_digest,
+    nil,
+    keys: ["#{QUEUE_KEY}:#{queue}", SCHEDULE_SET, RETRY_SET], argv: [unique_digest],
+  )
+end
+
+
+ +
+

+ + #delete_lockObject + + + + + +

+
+

Delete the keys belonging to the job

+ + +
+
+
+ + +
+ + + + +
+
+
+
+37
+38
+39
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 37
+
+def delete_lock
+  Scripts.call(:delete_by_digest, nil, keys: [UNIQUE_SET, unique_digest])
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Reschedule.html b/docs/SidekiqUniqueJobs/OnConflict/Reschedule.html new file mode 100644 index 000000000..6d4b9746e --- /dev/null +++ b/docs/SidekiqUniqueJobs/OnConflict/Reschedule.html @@ -0,0 +1,362 @@ + + + + + + + Class: SidekiqUniqueJobs::OnConflict::Reschedule + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::OnConflict::Reschedule + + + +

+
+ +
+
Inherits:
+
+ Strategy + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
SidekiqWorkerMethods
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/on_conflict/reschedule.rb
+
+ +
+ +

Overview

+
+

Strategy to reschedule job on conflict

+ + +
+
+
+ +

Author:

+ + +
+ + + + + +

Instance Attribute Summary

+ +

Attributes inherited from Strategy

+

#item

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from SidekiqWorkerMethods

+

#after_unlock_hook, #default_worker_options, #sidekiq_worker_class?, #worker_class, #worker_class_constantize, #worker_method_defined?, #worker_options

+ + + + + + + + + +

Methods inherited from Strategy

+

#replace?

+ + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +
+

+ + #initialize(item) ⇒ Reschedule + + + + + +

+
+

Returns a new instance of Reschedule

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    sidekiq job hash

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+12
+13
+14
+15
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reschedule.rb', line 12
+
+def initialize(item)
+  super
+  @worker_class = item[CLASS_KEY]
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #callObject + + + + + +

+
+

Create a new job from the current one. + This will mess up sidekiq stats because a new job is created

+ + +
+
+
+ + +
+ + + + +
+
+
+
+19
+20
+21
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/reschedule.rb', line 19
+
+def call
+  worker_class&.perform_in(5, *item[ARGS_KEY]) if sidekiq_worker_class?
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Strategy.html b/docs/SidekiqUniqueJobs/OnConflict/Strategy.html new file mode 100644 index 000000000..0f415ff6f --- /dev/null +++ b/docs/SidekiqUniqueJobs/OnConflict/Strategy.html @@ -0,0 +1,526 @@ + + + + + + + Class: SidekiqUniqueJobs::OnConflict::Strategy + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::OnConflict::Strategy + Abstract + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Logging
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/on_conflict/strategy.rb
+
+ +
+ +

Overview

+
+
+ This class is abstract. +
+
+

Abstract conflict strategy class

+ + +
+
+
+ +

Author:

+ + +
+

Direct Known Subclasses

+

Log, NullStrategy, Raise, Reject, Replace, Reschedule

+
+ + + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #item ⇒ Hash + + + + + + + + + readonly + + + + + + + + + +

    The sidekiq job hash.

    +
    + +
  • + + +
+ + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +
+

+ + #initialize(item) ⇒ Strategy + + + + + +

+
+

Returns a new instance of Strategy

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    the Sidekiq job hash

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+17
+18
+19
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/strategy.rb', line 17
+
+def initialize(item)
+  @item = item
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #itemHash (readonly) + + + + + +

+
+

The sidekiq job hash

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Hash) + + + + — +

    the Sidekiq job hash

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+14
+15
+16
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/strategy.rb', line 14
+
+def item
+  @item
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #callObject + + + + + +

+
+

Use strategy on conflict

+ + +
+
+
+ +

Raises:

+
    + +
  • + + + (NotImplementedError) + + + + — +

    needs to be implemented in child class

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+23
+24
+25
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/strategy.rb', line 23
+
+def call
+  raise NotImplementedError, "needs to be implemented in child class"
+end
+
+
+ +
+

+ + #replace?Boolean + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/sidekiq_unique_jobs/on_conflict/strategy.rb', line 27
+
+def replace?
+  is_a?(Replace)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OptionsWithFallback.html b/docs/SidekiqUniqueJobs/OptionsWithFallback.html new file mode 100644 index 000000000..0d530df56 --- /dev/null +++ b/docs/SidekiqUniqueJobs/OptionsWithFallback.html @@ -0,0 +1,770 @@ + + + + + + + Module: SidekiqUniqueJobs::OptionsWithFallback + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::OptionsWithFallback + + + +

+
+ + + + + + + + + +
+
Included in:
+
Client::Middleware, Server::Middleware
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/options_with_fallback.rb
+
+ +
+ +

Overview

+
+

Module containing methods shared between client and server middleware

+ +

Requires the following methods to be defined in the including class

+ +
    +
  1. item (required)
  2. +
  3. options (can be nil)
  4. +
  5. worker_class (required, can be anything)
  6. +
+ + +
+
+
+ +

Author:

+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
LOCKS = + +
+
{
+  until_and_while_executing: SidekiqUniqueJobs::Lock::UntilAndWhileExecuting,
+  until_executed: SidekiqUniqueJobs::Lock::UntilExecuted,
+  until_executing: SidekiqUniqueJobs::Lock::UntilExecuting,
+  until_expired: SidekiqUniqueJobs::Lock::UntilExpired,
+  until_timeout: SidekiqUniqueJobs::Lock::UntilExpired,
+  while_executing: SidekiqUniqueJobs::Lock::WhileExecuting,
+  while_executing_reject: SidekiqUniqueJobs::Lock::WhileExecutingReject,
+}.freeze
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #lockSidekiqUniqueJobs::Lock::BaseLock + + + + + +

+
+

Check if we should log duplicate payloads

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+44
+45
+46
+
+
# File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 44
+
+def lock
+  @lock ||= lock_class.new(item, after_unlock_hook, @redis_pool)
+end
+
+
+ +
+

+ + #lock_classSidekiqUniqueJobs::Lock::BaseLock + + + + + +

+
+

Check if we should log duplicate payloads

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 50
+
+def lock_class
+  @lock_class ||= begin
+    LOCKS.fetch(lock_type.to_sym) do
+      raise UnknownLock, "No implementation for `lock: :#{lock_type}`"
+    end
+  end
+end
+
+
+ +
+

+ + #lock_typeSymbol + + + + + +

+
+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Symbol) + + + +
  • + +
+ +
+ + + + +
+
+
+
+59
+60
+61
+
+
# File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 59
+
+def lock_type
+  @lock_type ||= options[LOCK_KEY] || item[LOCK_KEY] || unique_type
+end
+
+
+ +
+

+ + #log_duplicate_payload?Boolean + + + + + +

+
+

Check if we should log duplicate payloads

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+38
+39
+40
+
+
# File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 38
+
+def log_duplicate_payload?
+  options[LOG_DUPLICATE_KEY] || item[LOG_DUPLICATE_KEY]
+end
+
+
+ +
+

+ + #optionsObject + + + + + +

+ + + + +
+
+
+
+67
+68
+69
+70
+71
+72
+73
+
+
# File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 67
+
+def options
+  @options ||= begin
+    opts = default_worker_options.dup
+    opts.merge!(worker_options) if sidekiq_worker_class?
+    (opts || {}).stringify_keys
+  end
+end
+
+
+ +
+

+ + #unique_disabled?Boolean + + + + + +

+
+

Check if unique has been disabled

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + +
  • + +
+ +
+ + + + +
+
+
+
+33
+34
+35
+
+
# File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 33
+
+def unique_disabled?
+  !unique_enabled?
+end
+
+
+ +
+

+ + #unique_enabled?true, false + + + + + +

+
+

Check if unique has been enabled

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + + — +

    indicate if the gem has been enabled

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+28
+29
+30
+
+
# File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 28
+
+def unique_enabled?
+  SidekiqUniqueJobs.config.enabled && lock_type
+end
+
+
+ +
+

+ + #unique_typeObject + + + + + +

+ + + + +
+
+
+
+63
+64
+65
+
+
# File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 63
+
+def unique_type
+  options[UNIQUE_KEY] || item[UNIQUE_KEY]
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/ScriptError.html b/docs/SidekiqUniqueJobs/ScriptError.html new file mode 100644 index 000000000..5b70fc592 --- /dev/null +++ b/docs/SidekiqUniqueJobs/ScriptError.html @@ -0,0 +1,263 @@ + + + + + + + Exception: SidekiqUniqueJobs::ScriptError + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Exception: SidekiqUniqueJobs::ScriptError + + + +

+
+ +
+
Inherits:
+
+ StandardError + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/exceptions.rb
+
+ +
+ +

Overview

+
+

Error raised from OnConflict::Raise

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + +
+

Constructor Details

+ +
+

+ + #initialize(file_name:, source_exception:) ⇒ ScriptError + + + + + +

+
+

Returns a new instance of ScriptError

+ + +
+
+
+

Parameters:

+
    + +
  • + + file_name + + + (Symbol) + + + + — +

    the name of the lua script

    +
    + +
  • + +
  • + + source_exception + + + (Redis::CommandError) + + + + — +

    exception to handle

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+19
+20
+21
+
+
# File 'lib/sidekiq_unique_jobs/exceptions.rb', line 19
+
+def initialize(file_name:, source_exception:)
+  super("Problem compiling #{file_name}. Message: #{source_exception.message}")
+end
+
+
+ +
+ + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Scripts.html b/docs/SidekiqUniqueJobs/Scripts.html new file mode 100644 index 000000000..26ff09cad --- /dev/null +++ b/docs/SidekiqUniqueJobs/Scripts.html @@ -0,0 +1,935 @@ + + + + + + + Module: SidekiqUniqueJobs::Scripts + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Scripts + + + +

+
+ + + + + + +
+
Includes:
+
Connection
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/scripts.rb
+
+ +
+ +

Overview

+
+

Interface to dealing with .lua files

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from Connection

+

#redis

+ + +
+

Class Method Details

+ + +
+

+ + .call(file_name, redis_pool, options = {}) ⇒ Object + + + + + +

+
+ +
+ Note: +

this method is recursive if we need to load a lua script +that wasn't previously loaded.

+
+
+ +

Call a lua script with the provided file_name

+ + +
+
+
+

Parameters:

+
    + +
  • + + file_name + + + (Symbol) + + + + — +

    the name of the lua script

    +
    + +
  • + +
  • + + redis_pool + + + (Sidekiq::RedisConnection, ConnectionPool) + + + + — +

    the redis connection

    +
    + +
  • + +
  • + + options + + + (Hash) + + + (defaults to: {}) + + + — +

    arguments to pass to the script file

    +
    + +
  • + +
+ + + + + + + + +

Options Hash (options):

+
    + +
  • + :keys + (Array) + + + + + —

    the array of keys to pass to the script

    +
    + +
  • + +
  • + :argv + (Array) + + + + + —

    the array of arguments to pass to the script

    +
    + +
  • + +
+ + + +
+ + + + +
+
+
+
+27
+28
+29
+30
+31
+32
+33
+
+
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 27
+
+def call(file_name, redis_pool, options = {})
+  execute_script(file_name, redis_pool, options)
+rescue Redis::CommandError => ex
+  handle_error(ex, file_name) do
+    call(file_name, redis_pool, options)
+  end
+end
+
+
+ +
+

+ + .execute_script(file_name, redis_pool, options = {}) ⇒ Object + + + + + +

+
+

Execute the script file

+ + +
+
+
+

Parameters:

+
    + +
  • + + file_name + + + (Symbol) + + + + — +

    the name of the lua script

    +
    + +
  • + +
  • + + redis_pool + + + (Sidekiq::RedisConnection, ConnectionPool) + + + + — +

    the redis connection

    +
    + +
  • + +
  • + + options + + + (Hash) + + + (defaults to: {}) + + + — +

    arguments to pass to the script file

    +
    + +
  • + +
+ + + + + + + + +

Options Hash (options):

+
    + +
  • + :keys + (Array) + + + + + —

    the array of keys to pass to the script

    +
    + +
  • + +
  • + :argv + (Array) + + + + + —

    the array of arguments to pass to the script

    +
    + +
  • + +
+ + + +
+ + + + +
+
+
+
+41
+42
+43
+44
+45
+46
+
+
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 41
+
+def execute_script(file_name, redis_pool, options = {})
+  redis(redis_pool) do |conn|
+    sha = script_sha(conn, file_name)
+    conn.evalsha(sha, options)
+  end
+end
+
+
+ +
+

+ + .handle_error(ex, file_name) ⇒ Object + + + + + +

+
+

Return sha of already loaded lua script or load it and return the sha

+ + +
+
+
+

Parameters:

+
    + +
  • + + ex + + + (Redis::CommandError) + + + + — +

    exception to handle

    +
    + +
  • + +
  • + + file_name + + + (Symbol) + + + + — +

    the name of the lua script

    +
    + +
  • + +
+ +

Raises:

+
    + +
  • + + + (ScriptError) + + + + — +

    when the error isn't handled

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+66
+67
+68
+69
+70
+71
+72
+73
+
+
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 66
+
+def handle_error(ex, file_name)
+  if ex.message == "NOSCRIPT No matching script. Please use EVAL."
+    SCRIPT_SHAS.delete(file_name)
+    return yield if block_given?
+  end
+
+  raise ScriptError, file_name: file_name, source_exception: ex
+end
+
+
+ +
+

+ + .script_path(file_name) ⇒ Pathname + + + + + +

+
+

Construct a Pathname to a lua script

+ + +
+
+
+

Parameters:

+
    + +
  • + + file_name + + + (Symbol) + + + + — +

    the name of the lua script

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Pathname) + + + + — +

    the full path to the gems lua script

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+85
+86
+87
+
+
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 85
+
+def script_path(file_name)
+  LUA_PATHNAME.join("#{file_name}.lua")
+end
+
+
+ +
+

+ + .script_sha(conn, file_name) ⇒ String + + + + + +

+
+

Return sha of already loaded lua script or load it and return the sha

+ + +
+
+
+

Parameters:

+
    + +
  • + + conn + + + (Sidekiq::RedisConnection) + + + + — +

    the redis connection

    +
    + +
  • + +
  • + + file_name + + + (Symbol) + + + + — +

    the name of the lua script

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    sha of the script file

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+52
+53
+54
+55
+56
+57
+58
+59
+60
+
+
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 52
+
+def script_sha(conn, file_name)
+  if (sha = SCRIPT_SHAS.get(file_name))
+    return sha
+  end
+
+  sha = conn.script(:load, script_source(file_name))
+  SCRIPT_SHAS.put(file_name, sha)
+  sha
+end
+
+
+ +
+

+ + .script_source(file_name) ⇒ String + + + + + +

+
+

Reads the lua file from disk

+ + +
+
+
+

Parameters:

+
    + +
  • + + file_name + + + (Symbol) + + + + — +

    the name of the lua script

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    the content of the lua file

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+78
+79
+80
+
+
# File 'lib/sidekiq_unique_jobs/scripts.rb', line 78
+
+def script_source(file_name)
+  script_path(file_name).read
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Server.html b/docs/SidekiqUniqueJobs/Server.html new file mode 100644 index 000000000..5013c3e4d --- /dev/null +++ b/docs/SidekiqUniqueJobs/Server.html @@ -0,0 +1,115 @@ + + + + + + + Module: SidekiqUniqueJobs::Server + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Server + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/server/middleware.rb
+
+ +
+ +

Defined Under Namespace

+

+ + + + + Classes: Middleware + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Server/Middleware.html b/docs/SidekiqUniqueJobs/Server/Middleware.html new file mode 100644 index 000000000..2ab4144b7 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Server/Middleware.html @@ -0,0 +1,355 @@ + + + + + + + Class: SidekiqUniqueJobs::Server::Middleware + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Server::Middleware + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Logging, OptionsWithFallback
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/server/middleware.rb
+
+ +
+ +

Overview

+
+

The unique sidekiq middleware for the server processor

+ + +
+
+
+ +

Author:

+ + +
+ + +

Constant Summary

+ +

Constants included + from OptionsWithFallback

+

OptionsWithFallback::LOCKS

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from OptionsWithFallback

+

#lock, #lock_class, #lock_type, #log_duplicate_payload?, #options, #unique_disabled?, #unique_enabled?, #unique_type

+ + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+ + +
+

Instance Method Details

+ + +
+

+ + #call(worker_class, item, queue) { ... } ⇒ Object + + + + + +

+
+

Runs the server middleware + Used from Sidekiq::Processor#process

+ + +
+
+
+

Parameters:

+
    + +
  • + + worker_class + + + (Sidekiq::Worker) + + + +
  • + +
  • + + item + + + (Hash) + + + + — +

    a sidekiq job hash

    +
    + +
  • + +
  • + + queue + + + (String) + + + + — +

    name of the queue

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +

    when uniqueness is disabled

    +
    + +
  • + +
  • + + + + + + + +

    when the lock class executes successfully

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+
+
# File 'lib/sidekiq_unique_jobs/server/middleware.rb', line 19
+
+def call(worker_class, item, queue)
+  @worker_class = worker_class
+  @item         = item
+  @queue        = queue
+  return yield if unique_disabled?
+
+  SidekiqUniqueJobs::Job.add_uniqueness(item)
+  Sidekiq::Logging.with_context(logging_context(self.class, item)) do
+    lock.execute do
+      yield
+    end
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/SidekiqWorkerMethods.html b/docs/SidekiqUniqueJobs/SidekiqWorkerMethods.html new file mode 100644 index 000000000..5857e43a7 --- /dev/null +++ b/docs/SidekiqUniqueJobs/SidekiqWorkerMethods.html @@ -0,0 +1,704 @@ + + + + + + + Module: SidekiqUniqueJobs::SidekiqWorkerMethods + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::SidekiqWorkerMethods + + + +

+
+ + + + + + + + + +
+
Included in:
+
OnConflict::Reschedule, Timeout::Calculator, UniqueArgs
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb
+
+ +
+ +

Overview

+
+

Module with convenience methods for the Sidekiq::Worker class

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #after_unlock_hookProc + + + + + +

+
+

The hook to call after a successful unlock

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Proc) + + + +
  • + +
+ +
+ + + + +
+
+
+
+37
+38
+39
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 37
+
+def after_unlock_hook
+  -> { worker_class.after_unlock if worker_method_defined?(:after_unlock) }
+end
+
+
+ +
+

+ + #default_worker_optionsObject + + + + + +

+ + + + +
+
+
+
+58
+59
+60
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 58
+
+def default_worker_options
+  Sidekiq.default_worker_options
+end
+
+
+ +
+

+ + #sidekiq_worker_class?true, false + + + + + +

+
+

Tests that the

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true) + + + + — +

    if worker_class responds to get_sidekiq_options

    +
    + +
  • + +
  • + + + (false) + + + + — +

    if worker_class does not respond to get_sidekiq_options

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+25
+26
+27
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 25
+
+def sidekiq_worker_class?
+  worker_method_defined?(:get_sidekiq_options)
+end
+
+
+ +
+

+ + #worker_classSidekiq::Worker + + + + + +

+
+

The Sidekiq::Worker implementation

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+31
+32
+33
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 31
+
+def worker_class
+  @_worker_class ||= worker_class_constantize # rubocop:disable Naming/MemoizedInstanceVariableName
+end
+
+
+ +
+

+ + #worker_class_constantize(klazz = @worker_class) ⇒ Sidekiq::Worker + + + + + +

+
+

Attempt to constantize a string worker_class argument, always +failing back to the original argument when the constant can't be found

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 45
+
+def worker_class_constantize(klazz = @worker_class)
+  return klazz unless klazz.is_a?(String)
+
+  Object.const_get(klazz)
+rescue NameError => ex
+  case ex.message
+  when /uninitialized constant/
+    klazz
+  else
+    raise
+  end
+end
+
+
+ +
+

+ + #worker_method_defined?(method_sym) ⇒ true, false + + + + + +

+
+

Avoids duplicating worker_class.respond_to? in multiple places

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+10
+11
+12
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 10
+
+def worker_method_defined?(method_sym)
+  worker_class.respond_to?(method_sym)
+end
+
+
+ +
+

+ + #worker_optionsHash + + + + + +

+
+

Wraps #get_sidekiq_options to always work with a hash

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Hash) + + + + — +

    of the worker class sidekiq options

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+16
+17
+18
+19
+20
+
+
# File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 16
+
+def worker_options
+  return {} unless sidekiq_worker_class?
+
+  worker_class.get_sidekiq_options.stringify_keys
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Timeout.html b/docs/SidekiqUniqueJobs/Timeout.html new file mode 100644 index 000000000..8c2591c52 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Timeout.html @@ -0,0 +1,117 @@ + + + + + + + Module: SidekiqUniqueJobs::Timeout + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Timeout + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/timeout.rb,
+ lib/sidekiq_unique_jobs/timeout/calculator.rb
+
+
+ +
+ +

Defined Under Namespace

+

+ + + + + Classes: Calculator + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Timeout/Calculator.html b/docs/SidekiqUniqueJobs/Timeout/Calculator.html new file mode 100644 index 000000000..3f2c1514f --- /dev/null +++ b/docs/SidekiqUniqueJobs/Timeout/Calculator.html @@ -0,0 +1,766 @@ + + + + + + + Class: SidekiqUniqueJobs::Timeout::Calculator + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::Timeout::Calculator + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
SidekiqWorkerMethods
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/timeout/calculator.rb
+
+ +
+ +

Overview

+
+

Calculates timeout and expiration

+ + +
+
+
+ +

Author:

+ + +
+ + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #item ⇒ Object + + + + + + + + + readonly + + + + + + + + + +
    + +
  • + + +
+ + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from SidekiqWorkerMethods

+

#after_unlock_hook, #default_worker_options, #sidekiq_worker_class?, #worker_class, #worker_class_constantize, #worker_method_defined?, #worker_options

+
+

Constructor Details

+ +
+

+ + #initialize(item) ⇒ Calculator + + + + + +

+
+

Returns a new instance of Calculator

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    the Sidekiq job hash

    +
    + +
  • + +
+ + + + +

Options Hash (item):

+
    + +
  • + :lock_expiration + (Integer, nil) + + + + + —

    the configured lock expiration

    +
    + +
  • + +
  • + :lock_timeout + (Integer, nil) + + + + + —

    the configured lock timeout

    +
    + +
  • + +
  • + :class + (String) + + + + + —

    the class of the sidekiq worker

    +
    + +
  • + +
  • + :at + (Float) + + + + + —

    the unix time the job is scheduled at

    +
    + +
  • + +
+ + + +
+ + + + +
+
+
+
+19
+20
+21
+22
+
+
# File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 19
+
+def initialize(item)
+  @item         = item
+  @worker_class = item[CLASS_KEY]
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #itemObject (readonly) + + + + + +

+ + + + +
+
+
+
+12
+13
+14
+
+
# File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 12
+
+def item
+  @item
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #default_lock_timeoutObject + + + + + +

+
+

The default lock_timeout of this gem

+ + +
+
+
+ + +
+ + + + +
+
+
+
+58
+59
+60
+
+
# File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 58
+
+def default_lock_timeout
+  SidekiqUniqueJobs.config.default_lock_timeout
+end
+
+
+ +
+

+ + #lock_expirationObject + + + + + +

+
+

The configured lock_expiration

+ + +
+
+
+ + +
+ + + + +
+
+
+
+39
+40
+41
+42
+43
+44
+45
+
+
# File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 39
+
+def lock_expiration
+  @lock_expiration ||= begin
+    expiration = item[LOCK_EXPIRATION_KEY]
+    expiration ||= worker_options[LOCK_EXPIRATION_KEY]
+    expiration && expiration.to_i + time_until_scheduled
+  end
+end
+
+
+ +
+

+ + #lock_timeoutObject + + + + + +

+
+

The configured lock_timeout

+ + +
+
+
+ + +
+ + + + +
+
+
+
+48
+49
+50
+51
+52
+53
+54
+55
+
+
# File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 48
+
+def lock_timeout
+  @lock_timeout = begin
+    timeout = default_worker_options[LOCK_TIMEOUT_KEY]
+    timeout = default_lock_timeout if default_lock_timeout
+    timeout = worker_options[LOCK_TIMEOUT_KEY] if worker_options.key?(LOCK_TIMEOUT_KEY)
+    timeout
+  end
+end
+
+
+ +
+

+ + #scheduled_atFloat + + + + + +

+
+

The time a job is scheduled

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Float) + + + + — +

    the exact unix time the job is scheduled at

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+34
+35
+36
+
+
# File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 34
+
+def scheduled_at
+  @scheduled_at ||= item[AT_KEY]
+end
+
+
+ +
+

+ + #time_until_scheduledInteger + + + + + +

+
+

The time until a job is scheduled

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    the number of seconds until job is scheduled

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+26
+27
+28
+29
+30
+
+
# File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 26
+
+def time_until_scheduled
+  return 0 unless scheduled_at
+
+  scheduled_at.to_i - Time.now.utc.to_i
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/UniqueArgs.html b/docs/SidekiqUniqueJobs/UniqueArgs.html new file mode 100644 index 000000000..0590c4007 --- /dev/null +++ b/docs/SidekiqUniqueJobs/UniqueArgs.html @@ -0,0 +1,1704 @@ + + + + + + + Class: SidekiqUniqueJobs::UniqueArgs + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: SidekiqUniqueJobs::UniqueArgs + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + +
+
Includes:
+
Logging, SidekiqWorkerMethods
+
+ + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/unique_args.rb
+
+ +
+ +

Overview

+
+

Handles uniqueness of sidekiq arguments

+ + +
+
+
+ +

Author:

+ + +
+ + + +

Instance Attribute Summary collapse

+
    + +
  • + + + #item ⇒ Hash + + + + + + + + + readonly + + + + + + + + + +

    The sidekiq job hash.

    +
    + +
  • + + +
+ + + + + +

+ Class Method Summary + collapse +

+ + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from SidekiqWorkerMethods

+

#after_unlock_hook, #default_worker_options, #sidekiq_worker_class?, #worker_class, #worker_class_constantize, #worker_method_defined?, #worker_options

+ + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+
+

Constructor Details

+ +
+

+ + #initialize(item) ⇒ UniqueArgs + + + + + +

+
+

Returns a new instance of UniqueArgs

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    a Sidekiq job hash

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+26
+27
+28
+29
+30
+31
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 26
+
+def initialize(item)
+  @item         = item
+  @worker_class = item[CLASS_KEY]
+
+  add_uniqueness_to_item
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #itemHash (readonly) + + + + + +

+
+

The sidekiq job hash

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Hash) + + + + — +

    the Sidekiq job hash

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+23
+24
+25
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 23
+
+def item
+  @item
+end
+
+
+ +
+ + +
+

Class Method Details

+ + +
+

+ + .digest(item) ⇒ String + + + + + +

+
+

Convenience method for returning a digest

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    a Sidekiq job hash

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    a unique digest

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+17
+18
+19
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 17
+
+def self.digest(item)
+  new(item).unique_digest
+end
+
+
+ +
+ +
+

Instance Method Details

+ + +
+

+ + #add_uniqueness_to_itemvoid + + + + + +

+
+

This method returns an undefined value.

Appends the keys unique_prefix, unique_args and #unique_digest to the sidekiq job hash #item

+ + +
+
+
+ + +
+ + + + +
+
+
+
+35
+36
+37
+38
+39
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 35
+
+def add_uniqueness_to_item
+  item[UNIQUE_PREFIX_KEY] ||= unique_prefix
+  item[UNIQUE_ARGS_KEY]     = unique_args(item[ARGS_KEY])
+  item[UNIQUE_DIGEST_KEY]   = unique_digest
+end
+
+
+ +
+

+ + #create_digestString + + + + + +

+
+

Creates a namespaced unique digest based on the #digestable_hash and the #unique_prefix

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    a unique digest

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+49
+50
+51
+52
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 49
+
+def create_digest
+  digest = Digest::MD5.hexdigest(Sidekiq.dump_json(digestable_hash))
+  "#{unique_prefix}:#{digest}"
+end
+
+
+ +
+

+ + #default_unique_args_methodObject + + + + + +

+
+

The global worker options defined in Sidekiq directly

+ + +
+
+
+ + +
+ + + + +
+
+
+
+145
+146
+147
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 145
+
+def default_unique_args_method
+  Sidekiq.default_worker_options.stringify_keys[UNIQUE_ARGS_KEY]
+end
+
+
+ +
+

+ + #digestable_hashHash + + + + + +

+
+

Filter a hash to use for digest

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Hash) + + + + — +

    to use for digest

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+62
+63
+64
+65
+66
+67
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 62
+
+def digestable_hash
+  @item.slice(CLASS_KEY, QUEUE_KEY, UNIQUE_ARGS_KEY).tap do |hash|
+    hash.delete(QUEUE_KEY) if unique_across_queues?
+    hash.delete(CLASS_KEY) if unique_across_workers?
+  end
+end
+
+
+ +
+

+ + #filter_by_proc(args) ⇒ Array + + + + + +

+
+

Filters unique arguments by proc configured in the sidekiq worker

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array) + + + + — +

    the arguments passed to the sidekiq worker

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Array) + + + + — +

    with the filtered arguments

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+120
+121
+122
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 120
+
+def filter_by_proc(args)
+  unique_args_method.call(args)
+end
+
+
+ +
+

+ + #filter_by_symbol(args) ⇒ Array + + + + + +

+
+

Filters unique arguments by method configured in the sidekiq worker

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array) + + + + — +

    the arguments passed to the sidekiq worker

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+128
+129
+130
+131
+132
+133
+134
+135
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 128
+
+def filter_by_symbol(args)
+  return args unless worker_method_defined?(unique_args_method)
+
+  worker_class.send(unique_args_method, args)
+rescue ArgumentError => ex
+  log_fatal(ex)
+  args
+end
+
+
+ +
+

+ + #filtered_args(args) ⇒ Array + + + + + +

+
+

Filters unique arguments by proc or symbol

+ + +
+
+
+

Parameters:

+
    + +
  • + + args + + + (Array) + + + + — +

    the arguments passed to the sidekiq worker

    +
    + +
  • + +
+ +

Returns:

+ + +
+ + + + +
+
+
+
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 101
+
+def filtered_args(args)
+  return args if args.empty?
+
+  json_args = Normalizer.jsonify(args)
+
+  case unique_args_method
+  when Proc
+    filter_by_proc(json_args)
+  when Symbol
+    filter_by_symbol(json_args)
+  else
+    log_debug("#{__method__} arguments not filtered (using all arguments for uniqueness)")
+    json_args
+  end
+end
+
+
+ +
+

+ + #unique_across_queues?true, false + + + + + +

+
+

Checks if we should disregard the queue when creating the unique digest

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+79
+80
+81
+82
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 79
+
+def unique_across_queues?
+  item[UNIQUE_ACROSS_QUEUES_KEY] || worker_options[UNIQUE_ACROSS_QUEUES_KEY] ||
+    item[UNIQUE_ON_ALL_QUEUES_KEY] || worker_options[UNIQUE_ON_ALL_QUEUES_KEY] # TODO: Remove in v 6.1
+end
+
+
+ +
+

+ + #unique_across_workers?true, false + + + + + +

+
+

Checks if we should disregard the worker when creating the unique digest

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+86
+87
+88
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 86
+
+def unique_across_workers?
+  item[UNIQUE_ACROSS_WORKERS_KEY] || worker_options[UNIQUE_ACROSS_WORKERS_KEY]
+end
+
+
+ +
+

+ + #unique_args(args) ⇒ Array + + + + + +

+
+

The unique arguments to use for creating a lock

+ + +
+
+
+ +

Returns:

+ + +
+ + + + +
+
+
+
+71
+72
+73
+74
+75
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 71
+
+def unique_args(args)
+  return filtered_args(args) if unique_args_enabled?
+
+  args
+end
+
+
+ +
+

+ + #unique_args_enabled?true, false + + + + + +

+
+

Checks if the worker class has been enabled for unique_args?

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (true, false) + + + +
  • + +
+ +
+ + + + +
+
+
+
+92
+93
+94
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 92
+
+def unique_args_enabled?
+  unique_args_method # && !unique_args_method.is_a?(Boolean)
+end
+
+
+ +
+

+ + #unique_args_methodObject + + + + + +

+
+

The method to use for filtering unique arguments

+ + +
+
+
+ + +
+ + + + +
+
+
+
+138
+139
+140
+141
+142
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 138
+
+def unique_args_method
+  @unique_args_method ||= worker_options[UNIQUE_ARGS_KEY]
+  @unique_args_method ||= :unique_args if worker_method_defined?(:unique_args)
+  @unique_args_method ||= default_unique_args_method
+end
+
+
+ +
+

+ + #unique_digestString + + + + + +

+
+

Memoized unique_digest

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    a unique digest

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+43
+44
+45
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 43
+
+def unique_digest
+  @unique_digest ||= create_digest
+end
+
+
+ +
+

+ + #unique_prefixString + + + + + +

+
+

A prefix to use as namespace for the #unique_digest

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    a unique digest

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+56
+57
+58
+
+
# File 'lib/sidekiq_unique_jobs/unique_args.rb', line 56
+
+def unique_prefix
+  worker_options[UNIQUE_PREFIX_KEY] || SidekiqUniqueJobs.config.unique_prefix
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/UnknownLock.html b/docs/SidekiqUniqueJobs/UnknownLock.html new file mode 100644 index 000000000..ebdb5fc99 --- /dev/null +++ b/docs/SidekiqUniqueJobs/UnknownLock.html @@ -0,0 +1,149 @@ + + + + + + + Exception: SidekiqUniqueJobs::UnknownLock + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Exception: SidekiqUniqueJobs::UnknownLock + + + +

+
+ +
+
Inherits:
+
+ StandardError + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/exceptions.rb
+
+ +
+ +

Overview

+
+

Error raised from OptionsWithFallback#lock_class

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Unlockable.html b/docs/SidekiqUniqueJobs/Unlockable.html new file mode 100644 index 000000000..0fa9f952d --- /dev/null +++ b/docs/SidekiqUniqueJobs/Unlockable.html @@ -0,0 +1,318 @@ + + + + + + + Module: SidekiqUniqueJobs::Unlockable + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Unlockable + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/unlockable.rb
+
+ +
+ +

Overview

+
+

Utility module to help manage unique keys in redis. +Useful for deleting keys that for whatever reason wasn't deleted

+ + +
+
+
+ +

Author:

+ + +
+ + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .delete(item) ⇒ Object + + + + + +

+
+

Deletes a lock regardless of if it was locked or not.

+ +

This is good for situations when a job is locked by another item

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    a Sidekiq job hash

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+22
+23
+24
+25
+
+
# File 'lib/sidekiq_unique_jobs/unlockable.rb', line 22
+
+def delete(item)
+  SidekiqUniqueJobs::UniqueArgs.digest(item)
+  SidekiqUniqueJobs::Locksmith.new(item).delete!
+end
+
+
+ +
+

+ + .unlock(item) ⇒ Object + + + + + +

+
+

Unlocks a job.

+ + +
+
+
+

Parameters:

+
    + +
  • + + item + + + (Hash) + + + + — +

    a Sidekiq job hash

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+13
+14
+15
+16
+
+
# File 'lib/sidekiq_unique_jobs/unlockable.rb', line 13
+
+def unlock(item)
+  SidekiqUniqueJobs::UniqueArgs.digest(item)
+  SidekiqUniqueJobs::Locksmith.new(item).unlock
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Util.html b/docs/SidekiqUniqueJobs/Util.html new file mode 100644 index 000000000..6d5ad3bfa --- /dev/null +++ b/docs/SidekiqUniqueJobs/Util.html @@ -0,0 +1,611 @@ + + + + + + + Module: SidekiqUniqueJobs::Util + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Util + + + +

+
+ + + + +
+
Extended by:
+
Util
+
+ + + +
+
Includes:
+
Connection, Logging
+
+ + + + +
+
Included in:
+
Util
+
+ + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/util.rb
+
+ +
+ +

Overview

+
+

Utility module to help manage unique keys in redis. +Useful for deleting keys that for whatever reason wasn't deleted

+ + +
+
+
+ +

Author:

+ + +
+ +

+ Constant Summary + collapse +

+ +
+ +
DEFAULT_COUNT = + +
+
1_000
+ +
SCAN_PATTERN = + +
+
"*"
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods included from Connection

+

#redis

+ + + + + + + + + +

Methods included from Logging

+

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

+ + +
+

Instance Method Details

+ + +
+

+ + #del(pattern = SCAN_PATTERN, count = 0) ⇒ Integer + + + + + +

+
+

Deletes unique keys from redis

+ + +
+
+
+

Parameters:

+
    + +
  • + + pattern + + + (String) + + + (defaults to: SCAN_PATTERN) + + + — +

    a pattern to scan for in redis

    +
    + +
  • + +
  • + + count + + + (Integer) + + + (defaults to: 0) + + + — +

    the maximum number of keys to delete

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +

    the number of keys deleted

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+
+
# File 'lib/sidekiq_unique_jobs/util.rb', line 46
+
+def del(pattern = SCAN_PATTERN, count = 0)
+  raise ArgumentError, "Please provide a number of keys to delete greater than zero" if count.zero?
+
+  pattern = suffix(pattern)
+
+  log_debug { "Deleting keys by: #{pattern}" }
+  keys, time = timed { keys(pattern, count) }
+  key_size   = keys.size
+  log_debug { "#{key_size} keys found in #{time} sec." }
+  _, time = timed { batch_delete(keys) }
+  log_debug { "Deleted #{key_size} keys in #{time} sec." }
+
+  key_size
+end
+
+
+ +
+

+ + #keys(pattern = SCAN_PATTERN, count = DEFAULT_COUNT) ⇒ Array<String> + + + + + +

+
+

Find unique keys in redis

+ + +
+
+
+

Parameters:

+
    + +
  • + + pattern + + + (String) + + + (defaults to: SCAN_PATTERN) + + + — +

    a pattern to scan for in redis

    +
    + +
  • + +
  • + + count + + + (Integer) + + + (defaults to: DEFAULT_COUNT) + + + — +

    the maximum number of keys to delete

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Array<String>) + + + + — +

    an array with active unique keys

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+21
+22
+23
+24
+25
+
+
# File 'lib/sidekiq_unique_jobs/util.rb', line 21
+
+def keys(pattern = SCAN_PATTERN, count = DEFAULT_COUNT)
+  return redis(&:keys) if pattern.nil?
+
+  redis { |conn| conn.scan_each(match: prefix(pattern), count: count).to_a }
+end
+
+
+ +
+

+ + #keys_with_ttl(pattern = SCAN_PATTERN, count = DEFAULT_COUNT) ⇒ Hash<String, Integer> + + + + + +

+
+

Find unique keys with ttl

+ + +
+
+
+

Parameters:

+
    + +
  • + + pattern + + + (String) + + + (defaults to: SCAN_PATTERN) + + + — +

    a pattern to scan for in redis

    +
    + +
  • + +
  • + + count + + + (Integer) + + + (defaults to: DEFAULT_COUNT) + + + — +

    the maximum number of keys to delete

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Hash<String, Integer>) + + + + — +

    a hash with active unique keys and corresponding ttl

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+31
+32
+33
+34
+35
+36
+37
+38
+39
+
+
# File 'lib/sidekiq_unique_jobs/util.rb', line 31
+
+def keys_with_ttl(pattern = SCAN_PATTERN, count = DEFAULT_COUNT)
+  hash = {}
+  redis do |conn|
+    conn.scan_each(match: prefix(pattern), count: count).each do |key|
+      hash[key] = conn.ttl(key)
+    end
+  end
+  hash
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Web.html b/docs/SidekiqUniqueJobs/Web.html new file mode 100644 index 000000000..6e5d3bb11 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Web.html @@ -0,0 +1,275 @@ + + + + + + + Module: SidekiqUniqueJobs::Web + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Web + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/web.rb,
+ lib/sidekiq_unique_jobs/web/helpers.rb
+
+
+ +
+ +

Overview

+
+

Utility module to help manage unique keys in redis. +Useful for deleting keys that for whatever reason wasn't deleted

+ + +
+
+
+ +

Author:

+ + +

Defined Under Namespace

+

+ + + Modules: Helpers + + + + +

+ + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .registered(app) ⇒ Object + + + + + +

+
+

rubocop:disable Metrics/MethodLength

+ + +
+
+
+ + +
+ + + + +
+
+
+
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+
+
# File 'lib/sidekiq_unique_jobs/web.rb', line 17
+
+def self.registered(app) # rubocop:disable Metrics/MethodLength
+  app.helpers do
+    include Web::Helpers
+  end
+
+  app.get "/unique_digests" do
+    @filter         = params[:filter] || "*"
+    @filter         = "*" if @filter == ""
+    @count          = (params[:count] || 100).to_i
+    @current_cursor = params[:cursor]
+    @prev_cursor    = params[:prev_cursor]
+    @total_size, @next_cursor, @unique_digests =
+      Digests.page(pattern: @filter, cursor: @current_cursor, page_size: @count)
+
+    erb(unique_template(:unique_digests))
+  end
+
+  app.get "/unique_digests/:digest" do
+    @digest = params[:digest]
+    @unique_keys = Util.keys("#{@digest}*", 1000)
+
+    erb(unique_template(:unique_digest))
+  end
+
+  app.get "/unique_digests/:digest/delete" do
+    Digests.del(digest: params[:digest])
+    redirect_to :unique_digests
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Web/Helpers.html b/docs/SidekiqUniqueJobs/Web/Helpers.html new file mode 100644 index 000000000..92f52afe4 --- /dev/null +++ b/docs/SidekiqUniqueJobs/Web/Helpers.html @@ -0,0 +1,393 @@ + + + + + + + Module: SidekiqUniqueJobs::Web::Helpers + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SidekiqUniqueJobs::Web::Helpers + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/sidekiq_unique_jobs/web/helpers.rb
+
+ +
+ + + +

+ Constant Summary + collapse +

+ +
+ +
VIEW_PATH = + +
+
File.expand_path("../web/views", __dir__)
+ +
SAFE_CPARAMS = + +
+
%w[cursor prev_cursor].freeze
+ +
+ + + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + +
+

Instance Method Details

+ + +
+

+ + #cparams(options) ⇒ Object + + + + + +

+ + + + +
+
+
+
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+
+
# File 'lib/sidekiq_unique_jobs/web/helpers.rb', line 14
+
+def cparams(options)
+  # stringify
+  options.keys.each do |key|
+    options[key.to_s] = options.delete(key)
+  end
+
+  params.merge(options).map do |key, value|
+    next unless SAFE_CPARAMS.include?(key)
+
+    "#{key}=#{CGI.escape(value.to_s)}"
+  end.compact.join("&")
+end
+
+
+ +
+

+ + #redirect_to(subpath) ⇒ Object + + + + + +

+ + + + +
+
+
+
+27
+28
+29
+30
+31
+32
+33
+34
+35
+
+
# File 'lib/sidekiq_unique_jobs/web/helpers.rb', line 27
+
+def redirect_to(subpath)
+  if respond_to?(:to)
+    # Sinatra-based web UI
+    redirect to(subpath)
+  else
+    # Non-Sinatra based web UI (Sidekiq 4.2+)
+    redirect "#{root_path}#{subpath}"
+  end
+end
+
+
+ +
+

+ + #safe_relative_time(time) ⇒ Object + + + + + +

+ + + + +
+
+
+
+37
+38
+39
+40
+41
+42
+43
+44
+45
+
+
# File 'lib/sidekiq_unique_jobs/web/helpers.rb', line 37
+
+def safe_relative_time(time)
+  time = if time.is_a?(Numeric)
+           Time.at(time)
+         else
+           Time.parse(time)
+         end
+
+  relative_time(time)
+end
+
+
+ +
+

+ + #unique_template(name) ⇒ Object + + + + + +

+ + + + +
+
+
+
+8
+9
+10
+
+
# File 'lib/sidekiq_unique_jobs/web/helpers.rb', line 8
+
+def unique_template(name)
+  File.open(File.join(VIEW_PATH, "#{name}.erb")).read
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/_index.html b/docs/_index.html new file mode 100644 index 000000000..c542a51b8 --- /dev/null +++ b/docs/_index.html @@ -0,0 +1,633 @@ + + + + + + + Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
+ + +

Documentation by YARD 0.9.18

+
+

Alphabetic Index

+ +

File Listing

+ + +
+

Namespace Listing A-Z

+ + + + + + + + +
+ + +
    +
  • A
  • + +
+ + +
    +
  • B
  • +
      + +
    • + BaseLock + + (SidekiqUniqueJobs::Lock) + +
    • + +
    +
+ + +
    +
  • C
  • +
      + +
    • + Calculator + + (SidekiqUniqueJobs::Timeout) + +
    • + +
    • + ClassMethods + + (Sidekiq::Worker) + +
    • + +
    • + Cli + + (SidekiqUniqueJobs) + +
    • + +
    • + Client + + (SidekiqUniqueJobs) + +
    • + +
    • + Conflict + + (SidekiqUniqueJobs) + +
    • + +
    • + Connection + + (SidekiqUniqueJobs) + +
    • + +
    +
+ + +
    +
  • D
  • +
      + +
    • + Digests + + (SidekiqUniqueJobs) + +
    • + +
    +
+ + +
    +
  • H
  • +
      + +
    • + Hash + +
    • + +
    • + Helpers + + (SidekiqUniqueJobs::Web) + +
    • + +
    +
+ + +
    +
  • J
  • +
      + +
    • + Job + + (Sidekiq) + +
    • + +
    • + Job + + (SidekiqUniqueJobs) + +
    • + +
    • + JobSet + + (Sidekiq) + +
    • + +
    +
+ + +
    +
  • L
  • +
      + +
    • + Lock + + (SidekiqUniqueJobs) + +
    • + +
    • + Locksmith + + (SidekiqUniqueJobs) + +
    • + +
    • + Log + + (SidekiqUniqueJobs::OnConflict) + +
    • + +
    • + Logging + + (SidekiqUniqueJobs) + +
    • + +
    +
+ + +
+ + +
    +
  • M
  • +
      + +
    • + Middleware + + (SidekiqUniqueJobs) + +
    • + +
    • + Middleware + + (SidekiqUniqueJobs::Server) + +
    • + +
    • + Middleware + + (SidekiqUniqueJobs::Client) + +
    • + +
    +
+ + +
    +
  • N
  • + +
+ + + + + +
    +
  • Q
  • +
      + +
    • + Queue + + (Sidekiq) + +
    • + +
    +
+ + +
    +
  • R
  • +
      + +
    • + Raise + + (SidekiqUniqueJobs::OnConflict) + +
    • + +
    • + Reject + + (SidekiqUniqueJobs::OnConflict) + +
    • + +
    • + Replace + + (SidekiqUniqueJobs::OnConflict) + +
    • + +
    • + Reschedule + + (SidekiqUniqueJobs::OnConflict) + +
    • + +
    +
+ + + + + +
    +
  • T
  • +
      + +
    • + Testing + + (Sidekiq::Worker::Overrides) + +
    • + +
    • + Timeout + + (SidekiqUniqueJobs) + +
    • + +
    +
+ + + + + +
+ + + + +
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/docs/class_list.html b/docs/class_list.html new file mode 100644 index 000000000..1d16a2e12 --- /dev/null +++ b/docs/class_list.html @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + Class List + + + +
+
+

Class List

+ + + +
+ + +
+ + diff --git a/docs/css/common.css b/docs/css/common.css new file mode 100644 index 000000000..cf25c4523 --- /dev/null +++ b/docs/css/common.css @@ -0,0 +1 @@ +/* Override this file with custom rules */ \ No newline at end of file diff --git a/docs/css/full_list.css b/docs/css/full_list.css new file mode 100644 index 000000000..742b72fa6 --- /dev/null +++ b/docs/css/full_list.css @@ -0,0 +1,58 @@ +body { + margin: 0; + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + height: 101%; + overflow-x: hidden; + background: #fafafa; +} + +h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } +.clear { clear: both; } +.fixed_header { position: fixed; background: #fff; width: 100%; padding-bottom: 10px; margin-top: 0; top: 0; z-index: 9999; height: 70px; } +#search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } +#content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } +#full_list { padding: 0; list-style: none; margin-left: 0; margin-top: 80px; font-size: 1.1em; } +#full_list ul { padding: 0; } +#full_list li { padding: 0; margin: 0; list-style: none; } +#full_list li .item { padding: 5px 5px 5px 12px; } +#noresults { padding: 7px 12px; background: #fff; } +#content.insearch #noresults { margin-left: 7px; } +li.collapsed ul { display: none; } +li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } +li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; } +li { color: #888; cursor: pointer; } +li.deprecated { text-decoration: line-through; font-style: italic; } +li.odd { background: #f0f0f0; } +li.even { background: #fafafa; } +.item:hover { background: #ddd; } +li small:before { content: "("; } +li small:after { content: ")"; } +li small.search_info { display: none; } +a, a:visited { text-decoration: none; color: #05a; } +li.clicked > .item { background: #05a; color: #ccc; } +li.clicked > .item a, li.clicked > .item a:visited { color: #eee; } +li.clicked > .item a.toggle { opacity: 0.5; background-position: bottom right; } +li.collapsed.clicked a.toggle { background-position: top right; } +#search input { border: 1px solid #bbb; border-radius: 3px; } +#full_list_nav { margin-left: 10px; font-size: 0.9em; display: block; color: #aaa; } +#full_list_nav a, #nav a:visited { color: #358; } +#full_list_nav a:hover { background: transparent; color: #5af; } +#full_list_nav span:after { content: ' | '; } +#full_list_nav span:last-child:after { content: ''; } + +#content h1 { margin-top: 0; } +li { white-space: nowrap; cursor: normal; } +li small { display: block; font-size: 0.8em; } +li small:before { content: ""; } +li small:after { content: ""; } +li small.search_info { display: none; } +#search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; } +#content.insearch #search { background-position: center right; } +#search input { width: 110px; } + +#full_list.insearch ul { display: block; } +#full_list.insearch .item { display: none; } +#full_list.insearch .found { display: block; padding-left: 11px !important; } +#full_list.insearch li a.toggle { display: none; } +#full_list.insearch li small.search_info { display: block; } diff --git a/docs/css/style.css b/docs/css/style.css new file mode 100644 index 000000000..44d87e0d4 --- /dev/null +++ b/docs/css/style.css @@ -0,0 +1,496 @@ +html { + width: 100%; + height: 100%; +} +body { + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + width: 100%; + margin: 0; + padding: 0; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; +} + +#nav { + position: relative; + width: 100%; + height: 100%; + border: 0; + border-right: 1px dotted #eee; + overflow: auto; +} +.nav_wrap { + margin: 0; + padding: 0; + width: 20%; + height: 100%; + position: relative; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; + flex-shrink: 0; + -webkit-flex-shrink: 0; + -ms-flex: 1 0; +} +#resizer { + position: absolute; + right: -5px; + top: 0; + width: 10px; + height: 100%; + cursor: col-resize; + z-index: 9999; +} +#main { + flex: 5 1; + -webkit-flex: 5 1; + -ms-flex: 5 1; + outline: none; + position: relative; + background: #fff; + padding: 1.2em; + padding-top: 0.2em; +} + +@media (max-width: 920px) { + .nav_wrap { width: 100%; top: 0; right: 0; overflow: visible; position: absolute; } + #resizer { display: none; } + #nav { + z-index: 9999; + background: #fff; + display: none; + position: absolute; + top: 40px; + right: 12px; + width: 500px; + max-width: 80%; + height: 80%; + overflow-y: scroll; + border: 1px solid #999; + border-collapse: collapse; + box-shadow: -7px 5px 25px #aaa; + border-radius: 2px; + } +} + +@media (min-width: 920px) { + body { height: 100%; overflow: hidden; } + #main { height: 100%; overflow: auto; } + #search { display: none; } +} + +#main img { max-width: 100%; } +h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; } +h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; } +h1.title { margin-bottom: 10px; } +h1.alphaindex { margin-top: 0; font-size: 22px; } +h2 { + padding: 0; + padding-bottom: 3px; + border-bottom: 1px #aaa solid; + font-size: 1.4em; + margin: 1.8em 0 0.5em; + position: relative; +} +h2 small { font-weight: normal; font-size: 0.7em; display: inline; position: absolute; right: 0; } +h2 small a { + display: block; + height: 20px; + border: 1px solid #aaa; + border-bottom: 0; + border-top-left-radius: 5px; + background: #f8f8f8; + position: relative; + padding: 2px 7px; +} +.clear { clear: both; } +.inline { display: inline; } +.inline p:first-child { display: inline; } +.docstring, .tags, #filecontents { font-size: 15px; line-height: 1.5145em; } +.docstring p > code, .docstring p > tt, .tags p > code, .tags p > tt { + color: #c7254e; background: #f9f2f4; padding: 2px 4px; font-size: 1em; + border-radius: 4px; +} +.docstring h1, .docstring h2, .docstring h3, .docstring h4 { padding: 0; border: 0; border-bottom: 1px dotted #bbb; } +.docstring h1 { font-size: 1.2em; } +.docstring h2 { font-size: 1.1em; } +.docstring h3, .docstring h4 { font-size: 1em; border-bottom: 0; padding-top: 10px; } +.summary_desc .object_link a, .docstring .object_link a { + font-family: monospace; font-size: 1.05em; + color: #05a; background: #EDF4FA; padding: 2px 4px; font-size: 1em; + border-radius: 4px; +} +.rdoc-term { padding-right: 25px; font-weight: bold; } +.rdoc-list p { margin: 0; padding: 0; margin-bottom: 4px; } +.summary_desc pre.code .object_link a, .docstring pre.code .object_link a { + padding: 0px; background: inherit; color: inherit; border-radius: inherit; +} + +/* style for */ +#filecontents table, .docstring table { border-collapse: collapse; } +#filecontents table th, #filecontents table td, +.docstring table th, .docstring table td { border: 1px solid #ccc; padding: 8px; padding-right: 17px; } +#filecontents table tr:nth-child(odd), +.docstring table tr:nth-child(odd) { background: #eee; } +#filecontents table tr:nth-child(even), +.docstring table tr:nth-child(even) { background: #fff; } +#filecontents table th, .docstring table th { background: #fff; } + +/* style for
    */ +#filecontents li > p, .docstring li > p { margin: 0px; } +#filecontents ul, .docstring ul { padding-left: 20px; } +/* style for
    */ +#filecontents dl, .docstring dl { border: 1px solid #ccc; } +#filecontents dt, .docstring dt { background: #ddd; font-weight: bold; padding: 3px 5px; } +#filecontents dd, .docstring dd { padding: 5px 0px; margin-left: 18px; } +#filecontents dd > p, .docstring dd > p { margin: 0px; } + +.note { + color: #222; + margin: 20px 0; + padding: 10px; + border: 1px solid #eee; + border-radius: 3px; + display: block; +} +.docstring .note { + border-left-color: #ccc; + border-left-width: 5px; +} +.note.todo { background: #ffffc5; border-color: #ececaa; } +.note.returns_void { background: #efefef; } +.note.deprecated { background: #ffe5e5; border-color: #e9dada; } +.note.title.deprecated { background: #ffe5e5; border-color: #e9dada; } +.note.private { background: #ffffc5; border-color: #ececaa; } +.note.title { padding: 3px 6px; font-size: 0.9em; font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; display: inline; } +.summary_signature + .note.title { margin-left: 7px; } +h1 .note.title { font-size: 0.5em; font-weight: normal; padding: 3px 5px; position: relative; top: -3px; text-transform: capitalize; } +.note.title { background: #efefef; } +.note.title.constructor { color: #fff; background: #6a98d6; border-color: #6689d6; } +.note.title.writeonly { color: #fff; background: #45a638; border-color: #2da31d; } +.note.title.readonly { color: #fff; background: #6a98d6; border-color: #6689d6; } +.note.title.private { background: #d5d5d5; border-color: #c5c5c5; } +.note.title.not_defined_here { background: transparent; border: none; font-style: italic; } +.discussion .note { margin-top: 6px; } +.discussion .note:first-child { margin-top: 0; } + +h3.inherited { + font-style: italic; + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-weight: normal; + padding: 0; + margin: 0; + margin-top: 12px; + margin-bottom: 3px; + font-size: 13px; +} +p.inherited { + padding: 0; + margin: 0; + margin-left: 25px; +} + +.box_info dl { + margin: 0; + border: 0; + width: 100%; + font-size: 1em; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; +} +.box_info dl dt { + flex-shrink: 0; + -webkit-flex-shrink: 1; + -ms-flex-shrink: 1; + width: 100px; + text-align: right; + font-weight: bold; + border: 1px solid #aaa; + border-width: 1px 0px 0px 1px; + padding: 6px 0; + padding-right: 10px; +} +.box_info dl dd { + flex-grow: 1; + -webkit-flex-grow: 1; + -ms-flex: 1; + max-width: 420px; + padding: 6px 0; + padding-right: 20px; + border: 1px solid #aaa; + border-width: 1px 1px 0 0; + overflow: hidden; + position: relative; +} +.box_info dl:last-child > * { + border-bottom: 1px solid #aaa; +} +.box_info dl:nth-child(odd) > * { background: #eee; } +.box_info dl:nth-child(even) > * { background: #fff; } +.box_info dl > * { margin: 0; } + +ul.toplevel { list-style: none; padding-left: 0; font-size: 1.1em; } +.index_inline_list { padding-left: 0; font-size: 1.1em; } + +.index_inline_list li { + list-style: none; + display: inline-block; + padding: 0 12px; + line-height: 30px; + margin-bottom: 5px; +} + +dl.constants { margin-left: 10px; } +dl.constants dt { font-weight: bold; font-size: 1.1em; margin-bottom: 5px; } +dl.constants.compact dt { display: inline-block; font-weight: normal } +dl.constants dd { width: 75%; white-space: pre; font-family: monospace; margin-bottom: 18px; } +dl.constants .docstring .note:first-child { margin-top: 5px; } + +.summary_desc { + margin-left: 32px; + display: block; + font-family: sans-serif; + font-size: 1.1em; + margin-top: 8px; + line-height: 1.5145em; + margin-bottom: 0.8em; +} +.summary_desc tt { font-size: 0.9em; } +dl.constants .note { padding: 2px 6px; padding-right: 12px; margin-top: 6px; } +dl.constants .docstring { margin-left: 32px; font-size: 0.9em; font-weight: normal; } +dl.constants .tags { padding-left: 32px; font-size: 0.9em; line-height: 0.8em; } +dl.constants .discussion *:first-child { margin-top: 0; } +dl.constants .discussion *:last-child { margin-bottom: 0; } + +.method_details { border-top: 1px dotted #ccc; margin-top: 25px; padding-top: 0; } +.method_details.first { border: 0; margin-top: 5px; } +.method_details.first h3.signature { margin-top: 1em; } +p.signature, h3.signature { + font-size: 1.1em; font-weight: normal; font-family: Monaco, Consolas, Courier, monospace; + padding: 6px 10px; margin-top: 1em; + background: #E8F4FF; border: 1px solid #d8d8e5; border-radius: 5px; +} +p.signature tt, +h3.signature tt { font-family: Monaco, Consolas, Courier, monospace; } +p.signature .overload, +h3.signature .overload { display: block; } +p.signature .extras, +h3.signature .extras { font-weight: normal; font-family: sans-serif; color: #444; font-size: 1em; } +p.signature .not_defined_here, +h3.signature .not_defined_here, +p.signature .aliases, +h3.signature .aliases { display: block; font-weight: normal; font-size: 0.9em; font-family: sans-serif; margin-top: 0px; color: #555; } +p.signature .aliases .names, +h3.signature .aliases .names { font-family: Monaco, Consolas, Courier, monospace; font-weight: bold; color: #000; font-size: 1.2em; } + +.tags .tag_title { font-size: 1.05em; margin-bottom: 0; font-weight: bold; } +.tags .tag_title tt { color: initial; padding: initial; background: initial; } +.tags ul { margin-top: 5px; padding-left: 30px; list-style: square; } +.tags ul li { margin-bottom: 3px; } +.tags ul .name { font-family: monospace; font-weight: bold; } +.tags ul .note { padding: 3px 6px; } +.tags { margin-bottom: 12px; } + +.tags .examples .tag_title { margin-bottom: 10px; font-weight: bold; } +.tags .examples .inline p { padding: 0; margin: 0; font-weight: bold; font-size: 1em; } +.tags .examples .inline p:before { content: "▸"; font-size: 1em; margin-right: 5px; } + +.tags .overload .overload_item { list-style: none; margin-bottom: 25px; } +.tags .overload .overload_item .signature { + padding: 2px 8px; + background: #F1F8FF; border: 1px solid #d8d8e5; border-radius: 3px; +} +.tags .overload .signature { margin-left: -15px; font-family: monospace; display: block; font-size: 1.1em; } +.tags .overload .docstring { margin-top: 15px; } + +.defines { display: none; } + +#method_missing_details .notice.this { position: relative; top: -8px; color: #888; padding: 0; margin: 0; } + +.showSource { font-size: 0.9em; } +.showSource a, .showSource a:visited { text-decoration: none; color: #666; } + +#content a, #content a:visited { text-decoration: none; color: #05a; } +#content a:hover { background: #ffffa5; } + +ul.summary { + list-style: none; + font-family: monospace; + font-size: 1em; + line-height: 1.5em; + padding-left: 0px; +} +ul.summary a, ul.summary a:visited { + text-decoration: none; font-size: 1.1em; +} +ul.summary li { margin-bottom: 5px; } +.summary_signature { padding: 4px 8px; background: #f8f8f8; border: 1px solid #f0f0f0; border-radius: 5px; } +.summary_signature:hover { background: #CFEBFF; border-color: #A4CCDA; cursor: pointer; } +.summary_signature.deprecated { background: #ffe5e5; border-color: #e9dada; } +ul.summary.compact li { display: inline-block; margin: 0px 5px 0px 0px; line-height: 2.6em;} +ul.summary.compact .summary_signature { padding: 5px 7px; padding-right: 4px; } +#content .summary_signature:hover a, +#content .summary_signature:hover a:visited { + background: transparent; + color: #049; +} + +p.inherited a { font-family: monospace; font-size: 0.9em; } +p.inherited { word-spacing: 5px; font-size: 1.2em; } + +p.children { font-size: 1.2em; } +p.children a { font-size: 0.9em; } +p.children strong { font-size: 0.8em; } +p.children strong.modules { padding-left: 5px; } + +ul.fullTree { display: none; padding-left: 0; list-style: none; margin-left: 0; margin-bottom: 10px; } +ul.fullTree ul { margin-left: 0; padding-left: 0; list-style: none; } +ul.fullTree li { text-align: center; padding-top: 18px; padding-bottom: 12px; background: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAHtJREFUeNqMzrEJAkEURdGzuhgZbSoYWcAWoBVsB4JgZAGmphsZCZYzTQgWNCYrDN9RvMmHx+X916SUBFbo8CzD1idXrLErw1mQttgXtyrOcQ/Ny5p4Qh+2XqLYYazsPWNTiuMkRxa4vcV+evuNAUOLIx5+c2hyzv7hNQC67Q+/HHmlEwAAAABJRU5ErkJggg==) no-repeat top center; } +ul.fullTree li:first-child { padding-top: 0; background: transparent; } +ul.fullTree li:last-child { padding-bottom: 0; } +.showAll ul.fullTree { display: block; } +.showAll .inheritName { display: none; } + +#search { position: absolute; right: 12px; top: 0px; z-index: 9000; } +#search a { + display: block; float: left; + padding: 4px 8px; text-decoration: none; color: #05a; fill: #05a; + border: 1px solid #d8d8e5; + border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; + background: #F1F8FF; + box-shadow: -1px 1px 3px #ddd; +} +#search a:hover { background: #f5faff; color: #06b; fill: #06b; } +#search a.active { + background: #568; padding-bottom: 20px; color: #fff; fill: #fff; + border: 1px solid #457; + border-top-left-radius: 5px; border-top-right-radius: 5px; +} +#search a.inactive { color: #999; fill: #999; } +.inheritanceTree, .toggleDefines { + float: right; + border-left: 1px solid #aaa; + position: absolute; top: 0; right: 0; + height: 100%; + background: #f6f6f6; + padding: 5px; + min-width: 55px; + text-align: center; +} + +#menu { font-size: 1.3em; color: #bbb; } +#menu .title, #menu a { font-size: 0.7em; } +#menu .title a { font-size: 1em; } +#menu .title { color: #555; } +#menu a, #menu a:visited { color: #333; text-decoration: none; border-bottom: 1px dotted #bbd; } +#menu a:hover { color: #05a; } + +#footer { margin-top: 15px; border-top: 1px solid #ccc; text-align: center; padding: 7px 0; color: #999; } +#footer a, #footer a:visited { color: #444; text-decoration: none; border-bottom: 1px dotted #bbd; } +#footer a:hover { color: #05a; } + +#listing ul.alpha { font-size: 1.1em; } +#listing ul.alpha { margin: 0; padding: 0; padding-bottom: 10px; list-style: none; } +#listing ul.alpha li.letter { font-size: 1.4em; padding-bottom: 10px; } +#listing ul.alpha ul { margin: 0; padding-left: 15px; } +#listing ul small { color: #666; font-size: 0.7em; } + +li.r1 { background: #f0f0f0; } +li.r2 { background: #fafafa; } + +#content ul.summary li.deprecated .summary_signature a, +#content ul.summary li.deprecated .summary_signature a:visited { text-decoration: line-through; font-style: italic; } + +#toc { + position: relative; + float: right; + overflow-x: auto; + right: -3px; + margin-left: 20px; + margin-bottom: 20px; + padding: 20px; padding-right: 30px; + max-width: 300px; + z-index: 5000; + background: #fefefe; + border: 1px solid #ddd; + box-shadow: -2px 2px 6px #bbb; +} +#toc .title { margin: 0; } +#toc ol { padding-left: 1.8em; } +#toc li { font-size: 1.1em; line-height: 1.7em; } +#toc > ol > li { font-size: 1.1em; font-weight: bold; } +#toc ol > ol { font-size: 0.9em; } +#toc ol ol > ol { padding-left: 2.3em; } +#toc ol + li { margin-top: 0.3em; } +#toc.hidden { padding: 10px; background: #fefefe; box-shadow: none; } +#toc.hidden:hover { background: #fafafa; } +#filecontents h1 + #toc.nofloat { margin-top: 0; } +@media (max-width: 560px) { + #toc { + margin-left: 0; + margin-top: 16px; + float: none; + max-width: none; + } +} + +/* syntax highlighting */ +.source_code { display: none; padding: 3px 8px; border-left: 8px solid #ddd; margin-top: 5px; } +#filecontents pre.code, .docstring pre.code, .source_code pre { font-family: monospace; } +#filecontents pre.code, .docstring pre.code { display: block; } +.source_code .lines { padding-right: 12px; color: #555; text-align: right; } +#filecontents pre.code, .docstring pre.code, +.tags pre.example { + padding: 9px 14px; + margin-top: 4px; + border: 1px solid #e1e1e8; + background: #f7f7f9; + border-radius: 4px; + font-size: 1em; + overflow-x: auto; + line-height: 1.2em; +} +pre.code { color: #000; tab-size: 2; } +pre.code .info.file { color: #555; } +pre.code .val { color: #036A07; } +pre.code .tstring_content, +pre.code .heredoc_beg, pre.code .heredoc_end, +pre.code .qwords_beg, pre.code .qwords_end, pre.code .qwords_sep, +pre.code .words_beg, pre.code .words_end, pre.code .words_sep, +pre.code .qsymbols_beg, pre.code .qsymbols_end, pre.code .qsymbols_sep, +pre.code .symbols_beg, pre.code .symbols_end, pre.code .symbols_sep, +pre.code .tstring, pre.code .dstring { color: #036A07; } +pre.code .fid, pre.code .rubyid_new, pre.code .rubyid_to_s, +pre.code .rubyid_to_sym, pre.code .rubyid_to_f, +pre.code .dot + pre.code .id, +pre.code .rubyid_to_i pre.code .rubyid_each { color: #0085FF; } +pre.code .comment { color: #0066FF; } +pre.code .const, pre.code .constant { color: #585CF6; } +pre.code .label, +pre.code .symbol { color: #C5060B; } +pre.code .kw, +pre.code .rubyid_require, +pre.code .rubyid_extend, +pre.code .rubyid_include { color: #0000FF; } +pre.code .ivar { color: #318495; } +pre.code .gvar, +pre.code .rubyid_backref, +pre.code .rubyid_nth_ref { color: #6D79DE; } +pre.code .regexp, .dregexp { color: #036A07; } +pre.code a { border-bottom: 1px dotted #bbf; } +/* inline code */ +*:not(pre) > code { + padding: 1px 3px 1px 3px; + border: 1px solid #E1E1E8; + background: #F7F7F9; + border-radius: 4px; +} + +/* Color fix for links */ +#content .summary_desc pre.code .id > .object_link a, /* identifier */ +#content .docstring pre.code .id > .object_link a { color: #0085FF; } +#content .summary_desc pre.code .const > .object_link a, /* constant */ +#content .docstring pre.code .const > .object_link a { color: #585CF6; } diff --git a/docs/file.README.html b/docs/file.README.html new file mode 100644 index 000000000..dea57474f --- /dev/null +++ b/docs/file.README.html @@ -0,0 +1,546 @@ + + + + + + + File: README + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
    + + +

    SidekiqUniqueJobs Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs Build Status Code Climate Test Coverage

    + +

    Table of contents

    + + + +

    Introduction

    + +

    The goal of this gem is to ensure your Sidekiq jobs are unique. We do this by creating unique keys in Redis based on how you configure uniqueness.

    + +

    Documentation

    + +

    This is the documentation for the master branch. You can find the documentation for each release by navigating to its tag: https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10.

    + +

    Below are links to the latest major versions (4 & 5):

    + + + +

    Requirements

    + +

    See https://github.com/mperham/sidekiq#requirements for what is required. Starting from 5.0.0 only sidekiq >= 4 is supported and support for MRI <= 2.1 is dropped. ActiveJob is not supported

    + +

    Version 6 requires Redis >= 3 and pure Sidekiq, no ActiveJob supported anymore. See About ActiveJob for why.

    + +

    Installation

    + +

    Add this line to your application's Gemfile:

    + +
    gem 'sidekiq-unique-jobs'
    +
    + +

    And then execute:

    + +
    $ bundle
    +
    + +

    Or install it yourself as:

    + +
    $ gem install sidekiq-unique-jobs
    +
    + +

    Support Me

    + +

    Want to show me some ❤️ for the hard work I do on this gem? You can use the following PayPal link https://paypal.me/mhenrixon. Any amount is welcome and let me tell you it feels good to be appreciated. Even a dollar makes me super excited about all of this.

    + +

    General Information

    + +

    See Interaction w/ Sidekiq on how the gem interacts with Sidekiq.

    + +

    See Locking & Unlocking for an overview of the differences on when the various lock types are locked and unlocked.

    + +

    Options

    + +

    Lock Expiration

    + +

    This is probably not the configuration option you want...

    + +

    Since the client and the server are disconnected and not running inside the same process, setting a lock expiration is probably not what you want. Any keys that are used by this gem WILL be removed at the time of the expiration. For jobs that are scheduled in the future the key will expire when that job is scheduled + whatever expiration you have set.

    + +

    In previous versions there was a default expiration of 30 minutes which didn't work for a lot of long running jobs. Since version 6 there will be no expiration of any jobs from the default configuration. Please don't use lock_expiration unless you really know what you are doing.

    + +
    sidekiq_options lock_expiration: nil # default - don't expire keys
    +sidekiq_options lock_expiration: 20.days # expire this lock in 20 days
    +
    + +

    Lock Timeout

    + +

    This is the timeout (how long to wait) when creating the lock. By default we don't use a timeout so we won't wait for the lock to be created. If you want it is possible to set this like below.

    + +
    sidekiq_options lock_timeout: 0 # default - don't wait at all
    +sidekiq_options lock_timeout: 5 # wait 5 seconds
    +sidekiq_options lock_timeout: nil # lock indefinitely, this process won't continue until it gets a lock. VERY DANGEROUS!!
    +
    + +

    Unique Across Queues

    + +

    This configuration option is slightly misleading. It doesn't disregard the queue on other jobs. Just on itself, this means that a worker that might schedule jobs into multiple queues will be able to have uniqueness enforced on all queues it is pushed to.

    + +
    class Worker
    +  include Sidekiq::Worker
    +
    +  sidekiq_options unique_across_queues: true, queue: 'default'
    +
    +  def perform(args); end
    +end
    +
    + +

    Now if you push override the queue with Worker.set(queue: 'another').perform_async(1) it will still be considered unique when compared to Worker.perform_async(1) (that was actually pushed to the queue default).

    + +

    Unique Across Workers

    + +

    This configuration option is slightly misleading. It doesn't disregard the worker class on other jobs. Just on itself, this means that a worker that the worker class won't be used for generating the unique digest. The only way this option really makes sense is when you want to have uniqueness between two different worker classes.

    + +
    class WorkerOne
    +  include Sidekiq::Worker
    +
    +  sidekiq_options unique_across_workers: true, queue: 'default'
    +
    +  def perform(args); end
    +end
    +
    +class WorkerTwo
    +  include Sidekiq::Worker
    +
    +  sidekiq_options unique_across_workers: true, queue: 'default'
    +
    +  def perform(args); end
    +end
    +
    +
    +WorkerOne.perform_async(1) 
    +# => 'the jobs unique id'
    +
    +WorkerTwo.perform_async(1) 
    +# => nil because WorkerOne just stole the lock
    +
    + +

    Locks

    + +

    Until Executing

    + +

    Locks from when the client pushes the job to the queue. Will be unlocked before the server starts processing the job.

    + +

    NOTE this is probably not so good for jobs that shouldn't be running simultaneously (aka slow jobs).

    + +
    sidekiq_options lock: :until_executing
    +
    + +

    Until Executed

    + +

    Locks from when the client pushes the job to the queue. Will be unlocked when the server has successfully processed the job.

    + +
    sidekiq_options lock: :until_executed
    +
    + +

    Until Timeout

    + +

    Locks from when the client pushes the job to the queue. Will be unlocked when the specified timeout has been reached.

    + +
    sidekiq_options lock: :until_expired
    +
    + +

    Unique Until And While Executing

    + +

    Locks when the client pushes the job to the queue. The queue will be unlocked when the server starts processing the job. The server then goes on to creating a runtime lock for the job to prevent simultaneous jobs from being executed. As soon as the server starts processing a job, the client can push the same job to the queue.

    + +
    sidekiq_options lock: :until_and_while_executing
    +
    + +

    While Executing

    + +

    With this lock type it is possible to put any number of these jobs on the queue, but as the server pops the job from the queue it will create a lock and then wait until other locks are done processing. It looks like multiple jobs are running at the same time but in fact the second job will only be waiting for the first job to finish.

    + +

    NOTE Unless this job is configured with a lock_timeout: nil or lock_timeout: > 0 then all jobs that are attempted to be executed will just be dropped without waiting.

    + +
    sidekiq_options lock: :while_executing, lock_timeout: nil
    +
    + +

    There is an example of this to try it out in the rails_example application. Run foreman start in the root of the directory and open the url: localhost:5000/work/duplicate_while_executing.

    + +

    In the console you should see something like:

    + +
    0:32:24 worker.1 | 2017-04-23T08:32:24.955Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: start
    +10:32:24 worker.1 | 2017-04-23T08:32:24.956Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: start
    +10:32:24 worker.1 | 2017-04-23T08:32:24.957Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: start
    +10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: start
    +10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 WhileExecutingWorker INFO: perform(1, 2)
    +10:32:34 worker.1 | 2017-04-23T08:32:34.964Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: done: 10.009 sec
    +10:32:34 worker.1 | 2017-04-23T08:32:34.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 WhileExecutingWorker INFO: perform(1, 2)
    +10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 WhileExecutingWorker INFO: perform(1, 2)
    +10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: done: 20.009 sec
    +10:32:54 worker.1 | 2017-04-23T08:32:54.970Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f WhileExecutingWorker INFO: perform(1, 2)
    +10:32:54 worker.1 | 2017-04-23T08:32:54.969Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: done: 30.012 sec
    +10:33:04 worker.1 | 2017-04-23T08:33:04.973Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: done: 40.014 sec
    +
    + +

    Conflict Strategy

    + +

    Decides how we handle conflict. We can either reject the job to the dead queue or reschedule it. Both are useful for jobs that absolutely need to run and have been configured to use the lock WhileExecuting that is used only by the sidekiq server process.

    + +

    The last one is log which can be be used with the lock UntilExecuted and UntilExpired. Now we write a log entry saying the job could not be pushed because it is a duplicate of another job with the same arguments

    + +

    Log

    + +

    This strategy is intended to be used with UntilExecuted and UntilExpired. It will log a line about that this is job is a duplicate of another.

    + +

    sidekiq_options lock: :until_executed, on_conflict: :log

    + +

    Raise

    + +

    This strategy is intended to be used with WhileExecuting. Basically it will allow us to let the server process crash with a specific error message and be retried without messing up the Sidekiq stats.

    + +

    sidekiq_options lock: :while_executing, on_conflict: :raise, retry: 10

    + +

    Reject

    + +

    This strategy is intended to be used with WhileExecuting and will push the job to the dead queue on conflict.

    + +

    sidekiq_options lock: :while_executing, on_conflict: :reject

    + +

    Replace

    + +

    This strategy is intended to be used with client locks like UntilExecuted. +It will delete any existing job for these arguments from retry, schedule and +queue and retry the lock again.

    + +

    This is slightly dangerous and should probably only be used for jobs that are +always scheduled in the future. Currently only attempting to retry one time.

    + +

    sidekiq_options lock: :until_executed, on_conflict: :replace

    + +

    Reschedule

    + +

    This strategy is intended to be used with WhileExecuting and will delay the job to be tried again in 5 seconds. This will mess up the sidekiq stats but will prevent exceptions from being logged and confuse your sysadmins.

    + +

    sidekiq_options lock: :while_executing, on_conflict: :reschedule

    + +

    Usage

    + +

    All that is required is that you specifically set the sidekiq option for unique to a valid value like below:

    + +
    sidekiq_options lock: :while_executing
    +
    + +

    Requiring the gem in your gemfile should be sufficient to enable unique jobs.

    + +

    Finer Control over Uniqueness

    + +

    Sometimes it is desired to have a finer control over which arguments are used in determining uniqueness of the job, and others may be transient. For this use-case, you need to define either a unique_args method, or a ruby proc.

    + +

    The unique_args method need to return an array of values to use for uniqueness check.

    + +

    The method or the proc can return a modified version of args without the transient arguments included, as shown below:

    + +
    class UniqueJobWithFilterMethod
    +  include Sidekiq::Worker
    +  sidekiq_options lock: :until_and_while_executing,
    +                  unique_args: :unique_args # this is default and will be used if such a method is defined
    +
    +  def self.unique_args(args)
    +    [ args[0], args[2][:type] ]
    +  end
    +
    +  ...
    +
    +end
    +
    +class UniqueJobWithFilterProc
    +  include Sidekiq::Worker
    +  sidekiq_options lock: :until_executed,
    +                  unique_args: ->(args) { [ args.first ] }
    +
    +  ...
    +
    +end
    +
    + +

    It is also quite possible to ensure different types of unique args based on context. I can't vouch for the below example but see #203 for the discussion.

    + +
    class UniqueJobWithFilterMethod
    +  include Sidekiq::Worker
    +  sidekiq_options lock: :until_and_while_executing, unique_args: :unique_args
    +
    +  def self.unique_args(args)
    +    if Sidekiq::ProcessSet.new.size > 1
    +      # sidekiq runtime; uniqueness for the object (first arg)
    +      args.first
    +    else
    +      # queuing from the app; uniqueness for all params
    +      args
    +    end
    +  end
    +end
    +
    + +

    After Unlock Callback

    + +

    If you need to perform any additional work after the lock has been released you can provide an #after_unlock instance method. The method will be called when the lock has been unlocked. Most times this means after yield but there are two exceptions to that.

    + +

    Exception 1: UntilExecuting unlocks and calls back before yielding. +Exception 2: UntilExpired expires eventually, no after_unlock hook is called.

    + +
    class UniqueJobWithFilterMethod
    +  include Sidekiq::Worker
    +  sidekiq_options lock: :while_executing,
    +
    +  def after_unlock
    +   # block has yielded and lock is released
    +  end
    +  ...
    +end.
    +
    + +

    Logging

    + +

    To see logging in sidekiq when duplicate payload has been filtered out you can enable on a per worker basis using the sidekiq options. The default value is false

    + +
    class UniqueJobWithFilterMethod
    +  include Sidekiq::Worker
    +  sidekiq_options lock: :while_executing,
    +                  log_duplicate_payload: true
    +
    +  ...
    +
    +end
    +
    + +

    Cleanup Dead Locks

    + +

    For sidekiq versions before 5.1 a sidekiq_retries_exhausted block is required per worker class.

    + +
    class MyWorker
    +  sidekiq_retries_exhausted do |msg, _ex|
    +    SidekiqUniqueJobs::Digests.del(digest: msg['unique_digest']) if msg['unique_digest']
    +  end
    +end
    +
    + +

    Starting in v5.1, Sidekiq can also fire a global callback when a job dies:

    + +
    # this goes in your initializer
    +Sidekiq.configure_server do |config|
    +  config.death_handlers << ->(job, _ex) do
    +    SidekiqUniqueJobs::Digests.del(digest: job['unique_digest']) if job['unique_digest']
    +  end
    +end
    +
    + +

    Debugging

    + +

    There are several ways of removing keys that are stuck. The prefered way is by using the unique extension to Sidekiq::Web. The old console and command line versions still work but might be deprecated in the future. It is better to search for the digest itself and delete the keys matching that digest.

    + +

    Sidekiq Web

    + +

    To use the web extension you need to require it in your routes.

    + +
    # app/config/routes.rb
    +require 'sidekiq_unique_jobs/web'
    +mount Sidekiq::Web, at: '/sidekiq'
    +
    + +

    There is no need to require 'sidekiq/web' since sidekiq_unique_jobs/web +already does this.

    + +

    To filter/search for keys we can use the wildcard *. If we have a unique digest 'uniquejobs:9e9b5ce5d423d3ea470977004b50ff84 we can search for it by enter *ff84 and it should return all digests that end with ff84.

    + +

    Show Unique Digests

    + +

    Unique Digests

    + +

    Show keys for digest

    + +

    Unique Digests

    + +

    Communication

    + +

    There is a Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs for praise or scorn. This would be a good place to have lengthy discuss or brilliant suggestions or simply just nudge me if I forget about anything.

    + +

    Testing

    + +

    This has been probably the most confusing part of this gem. People get really confused with how unreliable the unique jobs have been. I there for decided to do what Mike is doing for sidekiq enterprise. Read the section about unique jobs.

    + +

    https://www.dailydrip.com/topics/sidekiq/drips/sidekiq-enterprise-unique-jobs

    + +
    SidekiqUniqueJobs.configure do |config|
    +  config.enabled = !Rails.env.test?
    +end
    +
    + +

    If you truly wanted to test the sidekiq client push you could do something like below. Note that it will only work for the jobs that lock when the client pushes the job to redis (UntilExecuted, UntilAndWhileExecuting and UntilExpired).

    + +
    RSpec.describe Workers::CoolOne do
    +  before do
    +    SidekiqUniqueJobs.config.enabled = false
    +  end
    +
    +  # ... your tests that don't test uniqueness
    +
    +  context 'when Sidekiq::Testing.disabled?' do
    +    before do
    +      Sidekiq::Testing.disable!
    +      Sidekiq.redis(&:flushdb)
    +    end
    +
    +    after do
    +      Sidekiq.redis(&:flushdb)
    +    end
    +
    +    it 'prevents duplicate jobs from being scheduled' do
    +      SidekiqUniqueJobs.use_config(enabled: true) do
    +        expect(described_class.perform_in(3600, 1)).not_to eq(nil)
    +        expect(described_class.perform_async(1)).to eq(nil)
    +      end
    +    end
    +  end
    +end
    +
    + +

    I would strongly suggest you let this gem test uniqueness. If you care about how the gem is integration tested have a look at the following specs:

    + + + +

    Contributing

    + +
      +
    1. Fork it
    2. +
    3. Create your feature branch (git checkout -b my-new-feature)
    4. +
    5. Commit your changes (git commit -am 'Add some feature')
    6. +
    7. Push to the branch (git push origin my-new-feature)
    8. +
    9. Create new Pull Request
    10. +
    + +

    Contributors

    + +

    You can find a list of contributors over on https://github.com/mhenrixon/sidekiq-unique-jobs/graphs/contributors

    +
    + + + +
    + + \ No newline at end of file diff --git a/docs/file_list.html b/docs/file_list.html new file mode 100644 index 000000000..b98a664b6 --- /dev/null +++ b/docs/file_list.html @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + File List + + + +
    +
    +

    File List

    + + + +
    + + +
    + + diff --git a/docs/frames.html b/docs/frames.html new file mode 100644 index 000000000..1529bf66b --- /dev/null +++ b/docs/frames.html @@ -0,0 +1,17 @@ + + + + + Documentation by YARD 0.9.18 + + + + diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 000000000..33ed6467d --- /dev/null +++ b/docs/index.html @@ -0,0 +1,546 @@ + + + + + + + File: README + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
    + + +

    SidekiqUniqueJobs Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs Build Status Code Climate Test Coverage

    + +

    Table of contents

    + + + +

    Introduction

    + +

    The goal of this gem is to ensure your Sidekiq jobs are unique. We do this by creating unique keys in Redis based on how you configure uniqueness.

    + +

    Documentation

    + +

    This is the documentation for the master branch. You can find the documentation for each release by navigating to its tag: https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10.

    + +

    Below are links to the latest major versions (4 & 5):

    + + + +

    Requirements

    + +

    See https://github.com/mperham/sidekiq#requirements for what is required. Starting from 5.0.0 only sidekiq >= 4 is supported and support for MRI <= 2.1 is dropped. ActiveJob is not supported

    + +

    Version 6 requires Redis >= 3 and pure Sidekiq, no ActiveJob supported anymore. See About ActiveJob for why.

    + +

    Installation

    + +

    Add this line to your application's Gemfile:

    + +
    gem 'sidekiq-unique-jobs'
    +
    + +

    And then execute:

    + +
    $ bundle
    +
    + +

    Or install it yourself as:

    + +
    $ gem install sidekiq-unique-jobs
    +
    + +

    Support Me

    + +

    Want to show me some ❤️ for the hard work I do on this gem? You can use the following PayPal link https://paypal.me/mhenrixon. Any amount is welcome and let me tell you it feels good to be appreciated. Even a dollar makes me super excited about all of this.

    + +

    General Information

    + +

    See Interaction w/ Sidekiq on how the gem interacts with Sidekiq.

    + +

    See Locking & Unlocking for an overview of the differences on when the various lock types are locked and unlocked.

    + +

    Options

    + +

    Lock Expiration

    + +

    This is probably not the configuration option you want...

    + +

    Since the client and the server are disconnected and not running inside the same process, setting a lock expiration is probably not what you want. Any keys that are used by this gem WILL be removed at the time of the expiration. For jobs that are scheduled in the future the key will expire when that job is scheduled + whatever expiration you have set.

    + +

    In previous versions there was a default expiration of 30 minutes which didn't work for a lot of long running jobs. Since version 6 there will be no expiration of any jobs from the default configuration. Please don't use lock_expiration unless you really know what you are doing.

    + +
    sidekiq_options lock_expiration: nil # default - don't expire keys
    +sidekiq_options lock_expiration: 20.days # expire this lock in 20 days
    +
    + +

    Lock Timeout

    + +

    This is the timeout (how long to wait) when creating the lock. By default we don't use a timeout so we won't wait for the lock to be created. If you want it is possible to set this like below.

    + +
    sidekiq_options lock_timeout: 0 # default - don't wait at all
    +sidekiq_options lock_timeout: 5 # wait 5 seconds
    +sidekiq_options lock_timeout: nil # lock indefinitely, this process won't continue until it gets a lock. VERY DANGEROUS!!
    +
    + +

    Unique Across Queues

    + +

    This configuration option is slightly misleading. It doesn't disregard the queue on other jobs. Just on itself, this means that a worker that might schedule jobs into multiple queues will be able to have uniqueness enforced on all queues it is pushed to.

    + +
    class Worker
    +  include Sidekiq::Worker
    +
    +  sidekiq_options unique_across_queues: true, queue: 'default'
    +
    +  def perform(args); end
    +end
    +
    + +

    Now if you push override the queue with Worker.set(queue: 'another').perform_async(1) it will still be considered unique when compared to Worker.perform_async(1) (that was actually pushed to the queue default).

    + +

    Unique Across Workers

    + +

    This configuration option is slightly misleading. It doesn't disregard the worker class on other jobs. Just on itself, this means that a worker that the worker class won't be used for generating the unique digest. The only way this option really makes sense is when you want to have uniqueness between two different worker classes.

    + +
    class WorkerOne
    +  include Sidekiq::Worker
    +
    +  sidekiq_options unique_across_workers: true, queue: 'default'
    +
    +  def perform(args); end
    +end
    +
    +class WorkerTwo
    +  include Sidekiq::Worker
    +
    +  sidekiq_options unique_across_workers: true, queue: 'default'
    +
    +  def perform(args); end
    +end
    +
    +
    +WorkerOne.perform_async(1) 
    +# => 'the jobs unique id'
    +
    +WorkerTwo.perform_async(1) 
    +# => nil because WorkerOne just stole the lock
    +
    + +

    Locks

    + +

    Until Executing

    + +

    Locks from when the client pushes the job to the queue. Will be unlocked before the server starts processing the job.

    + +

    NOTE this is probably not so good for jobs that shouldn't be running simultaneously (aka slow jobs).

    + +
    sidekiq_options lock: :until_executing
    +
    + +

    Until Executed

    + +

    Locks from when the client pushes the job to the queue. Will be unlocked when the server has successfully processed the job.

    + +
    sidekiq_options lock: :until_executed
    +
    + +

    Until Timeout

    + +

    Locks from when the client pushes the job to the queue. Will be unlocked when the specified timeout has been reached.

    + +
    sidekiq_options lock: :until_expired
    +
    + +

    Unique Until And While Executing

    + +

    Locks when the client pushes the job to the queue. The queue will be unlocked when the server starts processing the job. The server then goes on to creating a runtime lock for the job to prevent simultaneous jobs from being executed. As soon as the server starts processing a job, the client can push the same job to the queue.

    + +
    sidekiq_options lock: :until_and_while_executing
    +
    + +

    While Executing

    + +

    With this lock type it is possible to put any number of these jobs on the queue, but as the server pops the job from the queue it will create a lock and then wait until other locks are done processing. It looks like multiple jobs are running at the same time but in fact the second job will only be waiting for the first job to finish.

    + +

    NOTE Unless this job is configured with a lock_timeout: nil or lock_timeout: > 0 then all jobs that are attempted to be executed will just be dropped without waiting.

    + +
    sidekiq_options lock: :while_executing, lock_timeout: nil
    +
    + +

    There is an example of this to try it out in the rails_example application. Run foreman start in the root of the directory and open the url: localhost:5000/work/duplicate_while_executing.

    + +

    In the console you should see something like:

    + +
    0:32:24 worker.1 | 2017-04-23T08:32:24.955Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: start
    +10:32:24 worker.1 | 2017-04-23T08:32:24.956Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: start
    +10:32:24 worker.1 | 2017-04-23T08:32:24.957Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: start
    +10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: start
    +10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 WhileExecutingWorker INFO: perform(1, 2)
    +10:32:34 worker.1 | 2017-04-23T08:32:34.964Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: done: 10.009 sec
    +10:32:34 worker.1 | 2017-04-23T08:32:34.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 WhileExecutingWorker INFO: perform(1, 2)
    +10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 WhileExecutingWorker INFO: perform(1, 2)
    +10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: done: 20.009 sec
    +10:32:54 worker.1 | 2017-04-23T08:32:54.970Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f WhileExecutingWorker INFO: perform(1, 2)
    +10:32:54 worker.1 | 2017-04-23T08:32:54.969Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: done: 30.012 sec
    +10:33:04 worker.1 | 2017-04-23T08:33:04.973Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: done: 40.014 sec
    +
    + +

    Conflict Strategy

    + +

    Decides how we handle conflict. We can either reject the job to the dead queue or reschedule it. Both are useful for jobs that absolutely need to run and have been configured to use the lock WhileExecuting that is used only by the sidekiq server process.

    + +

    The last one is log which can be be used with the lock UntilExecuted and UntilExpired. Now we write a log entry saying the job could not be pushed because it is a duplicate of another job with the same arguments

    + +

    Log

    + +

    This strategy is intended to be used with UntilExecuted and UntilExpired. It will log a line about that this is job is a duplicate of another.

    + +

    sidekiq_options lock: :until_executed, on_conflict: :log

    + +

    Raise

    + +

    This strategy is intended to be used with WhileExecuting. Basically it will allow us to let the server process crash with a specific error message and be retried without messing up the Sidekiq stats.

    + +

    sidekiq_options lock: :while_executing, on_conflict: :raise, retry: 10

    + +

    Reject

    + +

    This strategy is intended to be used with WhileExecuting and will push the job to the dead queue on conflict.

    + +

    sidekiq_options lock: :while_executing, on_conflict: :reject

    + +

    Replace

    + +

    This strategy is intended to be used with client locks like UntilExecuted. +It will delete any existing job for these arguments from retry, schedule and +queue and retry the lock again.

    + +

    This is slightly dangerous and should probably only be used for jobs that are +always scheduled in the future. Currently only attempting to retry one time.

    + +

    sidekiq_options lock: :until_executed, on_conflict: :replace

    + +

    Reschedule

    + +

    This strategy is intended to be used with WhileExecuting and will delay the job to be tried again in 5 seconds. This will mess up the sidekiq stats but will prevent exceptions from being logged and confuse your sysadmins.

    + +

    sidekiq_options lock: :while_executing, on_conflict: :reschedule

    + +

    Usage

    + +

    All that is required is that you specifically set the sidekiq option for unique to a valid value like below:

    + +
    sidekiq_options lock: :while_executing
    +
    + +

    Requiring the gem in your gemfile should be sufficient to enable unique jobs.

    + +

    Finer Control over Uniqueness

    + +

    Sometimes it is desired to have a finer control over which arguments are used in determining uniqueness of the job, and others may be transient. For this use-case, you need to define either a unique_args method, or a ruby proc.

    + +

    The unique_args method need to return an array of values to use for uniqueness check.

    + +

    The method or the proc can return a modified version of args without the transient arguments included, as shown below:

    + +
    class UniqueJobWithFilterMethod
    +  include Sidekiq::Worker
    +  sidekiq_options lock: :until_and_while_executing,
    +                  unique_args: :unique_args # this is default and will be used if such a method is defined
    +
    +  def self.unique_args(args)
    +    [ args[0], args[2][:type] ]
    +  end
    +
    +  ...
    +
    +end
    +
    +class UniqueJobWithFilterProc
    +  include Sidekiq::Worker
    +  sidekiq_options lock: :until_executed,
    +                  unique_args: ->(args) { [ args.first ] }
    +
    +  ...
    +
    +end
    +
    + +

    It is also quite possible to ensure different types of unique args based on context. I can't vouch for the below example but see #203 for the discussion.

    + +
    class UniqueJobWithFilterMethod
    +  include Sidekiq::Worker
    +  sidekiq_options lock: :until_and_while_executing, unique_args: :unique_args
    +
    +  def self.unique_args(args)
    +    if Sidekiq::ProcessSet.new.size > 1
    +      # sidekiq runtime; uniqueness for the object (first arg)
    +      args.first
    +    else
    +      # queuing from the app; uniqueness for all params
    +      args
    +    end
    +  end
    +end
    +
    + +

    After Unlock Callback

    + +

    If you need to perform any additional work after the lock has been released you can provide an #after_unlock instance method. The method will be called when the lock has been unlocked. Most times this means after yield but there are two exceptions to that.

    + +

    Exception 1: UntilExecuting unlocks and calls back before yielding. +Exception 2: UntilExpired expires eventually, no after_unlock hook is called.

    + +
    class UniqueJobWithFilterMethod
    +  include Sidekiq::Worker
    +  sidekiq_options lock: :while_executing,
    +
    +  def after_unlock
    +   # block has yielded and lock is released
    +  end
    +  ...
    +end.
    +
    + +

    Logging

    + +

    To see logging in sidekiq when duplicate payload has been filtered out you can enable on a per worker basis using the sidekiq options. The default value is false

    + +
    class UniqueJobWithFilterMethod
    +  include Sidekiq::Worker
    +  sidekiq_options lock: :while_executing,
    +                  log_duplicate_payload: true
    +
    +  ...
    +
    +end
    +
    + +

    Cleanup Dead Locks

    + +

    For sidekiq versions before 5.1 a sidekiq_retries_exhausted block is required per worker class.

    + +
    class MyWorker
    +  sidekiq_retries_exhausted do |msg, _ex|
    +    SidekiqUniqueJobs::Digests.del(digest: msg['unique_digest']) if msg['unique_digest']
    +  end
    +end
    +
    + +

    Starting in v5.1, Sidekiq can also fire a global callback when a job dies:

    + +
    # this goes in your initializer
    +Sidekiq.configure_server do |config|
    +  config.death_handlers << ->(job, _ex) do
    +    SidekiqUniqueJobs::Digests.del(digest: job['unique_digest']) if job['unique_digest']
    +  end
    +end
    +
    + +

    Debugging

    + +

    There are several ways of removing keys that are stuck. The prefered way is by using the unique extension to Sidekiq::Web. The old console and command line versions still work but might be deprecated in the future. It is better to search for the digest itself and delete the keys matching that digest.

    + +

    Sidekiq Web

    + +

    To use the web extension you need to require it in your routes.

    + +
    # app/config/routes.rb
    +require 'sidekiq_unique_jobs/web'
    +mount Sidekiq::Web, at: '/sidekiq'
    +
    + +

    There is no need to require 'sidekiq/web' since sidekiq_unique_jobs/web +already does this.

    + +

    To filter/search for keys we can use the wildcard *. If we have a unique digest 'uniquejobs:9e9b5ce5d423d3ea470977004b50ff84 we can search for it by enter *ff84 and it should return all digests that end with ff84.

    + +

    Show Unique Digests

    + +

    Unique Digests

    + +

    Show keys for digest

    + +

    Unique Digests

    + +

    Communication

    + +

    There is a Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs for praise or scorn. This would be a good place to have lengthy discuss or brilliant suggestions or simply just nudge me if I forget about anything.

    + +

    Testing

    + +

    This has been probably the most confusing part of this gem. People get really confused with how unreliable the unique jobs have been. I there for decided to do what Mike is doing for sidekiq enterprise. Read the section about unique jobs.

    + +

    https://www.dailydrip.com/topics/sidekiq/drips/sidekiq-enterprise-unique-jobs

    + +
    SidekiqUniqueJobs.configure do |config|
    +  config.enabled = !Rails.env.test?
    +end
    +
    + +

    If you truly wanted to test the sidekiq client push you could do something like below. Note that it will only work for the jobs that lock when the client pushes the job to redis (UntilExecuted, UntilAndWhileExecuting and UntilExpired).

    + +
    RSpec.describe Workers::CoolOne do
    +  before do
    +    SidekiqUniqueJobs.config.enabled = false
    +  end
    +
    +  # ... your tests that don't test uniqueness
    +
    +  context 'when Sidekiq::Testing.disabled?' do
    +    before do
    +      Sidekiq::Testing.disable!
    +      Sidekiq.redis(&:flushdb)
    +    end
    +
    +    after do
    +      Sidekiq.redis(&:flushdb)
    +    end
    +
    +    it 'prevents duplicate jobs from being scheduled' do
    +      SidekiqUniqueJobs.use_config(enabled: true) do
    +        expect(described_class.perform_in(3600, 1)).not_to eq(nil)
    +        expect(described_class.perform_async(1)).to eq(nil)
    +      end
    +    end
    +  end
    +end
    +
    + +

    I would strongly suggest you let this gem test uniqueness. If you care about how the gem is integration tested have a look at the following specs:

    + + + +

    Contributing

    + +
      +
    1. Fork it
    2. +
    3. Create your feature branch (git checkout -b my-new-feature)
    4. +
    5. Commit your changes (git commit -am 'Add some feature')
    6. +
    7. Push to the branch (git push origin my-new-feature)
    8. +
    9. Create new Pull Request
    10. +
    + +

    Contributors

    + +

    You can find a list of contributors over on https://github.com/mhenrixon/sidekiq-unique-jobs/graphs/contributors

    +
    + + + +
    + + \ No newline at end of file diff --git a/docs/js/app.js b/docs/js/app.js new file mode 100644 index 000000000..c3f326d3c --- /dev/null +++ b/docs/js/app.js @@ -0,0 +1,292 @@ +(function() { + +var localStorage = {}, sessionStorage = {}; +try { localStorage = window.localStorage; } catch (e) { } +try { sessionStorage = window.sessionStorage; } catch (e) { } + +function createSourceLinks() { + $('.method_details_list .source_code'). + before("[View source]"); + $('.toggleSource').toggle(function() { + $(this).parent().nextAll('.source_code').slideDown(100); + $(this).text("Hide source"); + }, + function() { + $(this).parent().nextAll('.source_code').slideUp(100); + $(this).text("View source"); + }); +} + +function createDefineLinks() { + var tHeight = 0; + $('.defines').after(" more..."); + $('.toggleDefines').toggle(function() { + tHeight = $(this).parent().prev().height(); + $(this).prev().css('display', 'inline'); + $(this).parent().prev().height($(this).parent().height()); + $(this).text("(less)"); + }, + function() { + $(this).prev().hide(); + $(this).parent().prev().height(tHeight); + $(this).text("more..."); + }); +} + +function createFullTreeLinks() { + var tHeight = 0; + $('.inheritanceTree').toggle(function() { + tHeight = $(this).parent().prev().height(); + $(this).parent().toggleClass('showAll'); + $(this).text("(hide)"); + $(this).parent().prev().height($(this).parent().height()); + }, + function() { + $(this).parent().toggleClass('showAll'); + $(this).parent().prev().height(tHeight); + $(this).text("show all"); + }); +} + +function searchFrameButtons() { + $('.full_list_link').click(function() { + toggleSearchFrame(this, $(this).attr('href')); + return false; + }); + window.addEventListener('message', function(e) { + if (e.data === 'navEscape') { + $('#nav').slideUp(100); + $('#search a').removeClass('active inactive'); + $(window).focus(); + } + }); + + $(window).resize(function() { + if ($('#search:visible').length === 0) { + $('#nav').removeAttr('style'); + $('#search a').removeClass('active inactive'); + $(window).focus(); + } + }); +} + +function toggleSearchFrame(id, link) { + var frame = $('#nav'); + $('#search a').removeClass('active').addClass('inactive'); + if (frame.attr('src') === link && frame.css('display') !== "none") { + frame.slideUp(100); + $('#search a').removeClass('active inactive'); + } + else { + $(id).addClass('active').removeClass('inactive'); + if (frame.attr('src') !== link) frame.attr('src', link); + frame.slideDown(100); + } +} + +function linkSummaries() { + $('.summary_signature').click(function() { + document.location = $(this).find('a').attr('href'); + }); +} + +function summaryToggle() { + $('.summary_toggle').click(function(e) { + e.preventDefault(); + localStorage.summaryCollapsed = $(this).text(); + $('.summary_toggle').each(function() { + $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); + var next = $(this).parent().parent().nextAll('ul.summary').first(); + if (next.hasClass('compact')) { + next.toggle(); + next.nextAll('ul.summary').first().toggle(); + } + else if (next.hasClass('summary')) { + var list = $('
      '); + list.html(next.html()); + list.find('.summary_desc, .note').remove(); + list.find('a').each(function() { + $(this).html($(this).find('strong').html()); + $(this).parent().html($(this)[0].outerHTML); + }); + next.before(list); + next.toggle(); + } + }); + return false; + }); + if (localStorage.summaryCollapsed == "collapse") { + $('.summary_toggle').first().click(); + } else { localStorage.summaryCollapsed = "expand"; } +} + +function constantSummaryToggle() { + $('.constants_summary_toggle').click(function(e) { + e.preventDefault(); + localStorage.summaryCollapsed = $(this).text(); + $('.constants_summary_toggle').each(function() { + $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); + var next = $(this).parent().parent().nextAll('dl.constants').first(); + if (next.hasClass('compact')) { + next.toggle(); + next.nextAll('dl.constants').first().toggle(); + } + else if (next.hasClass('constants')) { + var list = $('
      '); + list.html(next.html()); + list.find('dt').each(function() { + $(this).addClass('summary_signature'); + $(this).text( $(this).text().split('=')[0]); + if ($(this).has(".deprecated").length) { + $(this).addClass('deprecated'); + }; + }); + // Add the value of the constant as "Tooltip" to the summary object + list.find('pre.code').each(function() { + console.log($(this).parent()); + var dt_element = $(this).parent().prev(); + var tooltip = $(this).text(); + if (dt_element.hasClass("deprecated")) { + tooltip = 'Deprecated. ' + tooltip; + }; + dt_element.attr('title', tooltip); + }); + list.find('.docstring, .tags, dd').remove(); + next.before(list); + next.toggle(); + } + }); + return false; + }); + if (localStorage.summaryCollapsed == "collapse") { + $('.constants_summary_toggle').first().click(); + } else { localStorage.summaryCollapsed = "expand"; } +} + +function generateTOC() { + if ($('#filecontents').length === 0) return; + var _toc = $('
        '); + var show = false; + var toc = _toc; + var counter = 0; + var tags = ['h2', 'h3', 'h4', 'h5', 'h6']; + var i; + if ($('#filecontents h1').length > 1) tags.unshift('h1'); + for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; } + var lastTag = parseInt(tags[0][1], 10); + $(tags.join(', ')).each(function() { + if ($(this).parents('.method_details .docstring').length != 0) return; + if (this.id == "filecontents") return; + show = true; + var thisTag = parseInt(this.tagName[1], 10); + if (this.id.length === 0) { + var proposedId = $(this).attr('toc-id'); + if (typeof(proposedId) != "undefined") this.id = proposedId; + else { + var proposedId = $(this).text().replace(/[^a-z0-9-]/ig, '_'); + if ($('#' + proposedId).length > 0) { proposedId += counter; counter++; } + this.id = proposedId; + } + } + if (thisTag > lastTag) { + for (i = 0; i < thisTag - lastTag; i++) { + var tmp = $('
          '); toc.append(tmp); toc = tmp; + } + } + if (thisTag < lastTag) { + for (i = 0; i < lastTag - thisTag; i++) toc = toc.parent(); + } + var title = $(this).attr('toc-title'); + if (typeof(title) == "undefined") title = $(this).text(); + toc.append('
        1. ' + title + '
        2. '); + lastTag = thisTag; + }); + if (!show) return; + html = ''; + $('#content').prepend(html); + $('#toc').append(_toc); + $('#toc .hide_toc').toggle(function() { + $('#toc .top').slideUp('fast'); + $('#toc').toggleClass('hidden'); + $('#toc .title small').toggle(); + }, function() { + $('#toc .top').slideDown('fast'); + $('#toc').toggleClass('hidden'); + $('#toc .title small').toggle(); + }); +} + +function navResizeFn(e) { + if (e.which !== 1) { + navResizeFnStop(); + return; + } + + sessionStorage.navWidth = e.pageX.toString(); + $('.nav_wrap').css('width', e.pageX); + $('.nav_wrap').css('-ms-flex', 'inherit'); +} + +function navResizeFnStop() { + $(window).unbind('mousemove', navResizeFn); + window.removeEventListener('message', navMessageFn, false); +} + +function navMessageFn(e) { + if (e.data.action === 'mousemove') navResizeFn(e.data.event); + if (e.data.action === 'mouseup') navResizeFnStop(); +} + +function navResizer() { + $('#resizer').mousedown(function(e) { + e.preventDefault(); + $(window).mousemove(navResizeFn); + window.addEventListener('message', navMessageFn, false); + }); + $(window).mouseup(navResizeFnStop); + + if (sessionStorage.navWidth) { + navResizeFn({which: 1, pageX: parseInt(sessionStorage.navWidth, 10)}); + } +} + +function navExpander() { + var done = false, timer = setTimeout(postMessage, 500); + function postMessage() { + if (done) return; + clearTimeout(timer); + var opts = { action: 'expand', path: pathId }; + document.getElementById('nav').contentWindow.postMessage(opts, '*'); + done = true; + } + + window.addEventListener('message', function(event) { + if (event.data === 'navReady') postMessage(); + return false; + }, false); +} + +function mainFocus() { + var hash = window.location.hash; + if (hash !== '' && $(hash)[0]) { + $(hash)[0].scrollIntoView(); + } + + setTimeout(function() { $('#main').focus(); }, 10); +} + +$(document).ready(function() { + navResizer(); + navExpander(); + createSourceLinks(); + createDefineLinks(); + createFullTreeLinks(); + searchFrameButtons(); + linkSummaries(); + summaryToggle(); + constantSummaryToggle(); + generateTOC(); + mainFocus(); +}); + +})(); diff --git a/docs/js/full_list.js b/docs/js/full_list.js new file mode 100644 index 000000000..3e4afd6f4 --- /dev/null +++ b/docs/js/full_list.js @@ -0,0 +1,216 @@ +(function() { + +var $clicked = $(null); +var searchTimeout = null; +var searchCache = []; +var caseSensitiveMatch = false; +var ignoreKeyCodeMin = 8; +var ignoreKeyCodeMax = 46; +var commandKey = 91; + +RegExp.escape = function(text) { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); +} + +function escapeShortcut() { + $(document).keydown(function(evt) { + if (evt.which == 27) { + window.parent.postMessage('navEscape', '*'); + } + }); +} + +function navResizer() { + $(window).mousemove(function(e) { + window.parent.postMessage({ + action: 'mousemove', event: {pageX: e.pageX, which: e.which} + }, '*'); + }).mouseup(function(e) { + window.parent.postMessage({action: 'mouseup'}, '*'); + }); + window.parent.postMessage("navReady", "*"); +} + +function clearSearchTimeout() { + clearTimeout(searchTimeout); + searchTimeout = null; +} + +function enableLinks() { + // load the target page in the parent window + $('#full_list li').on('click', function(evt) { + $('#full_list li').removeClass('clicked'); + $clicked = $(this); + $clicked.addClass('clicked'); + evt.stopPropagation(); + + if (evt.target.tagName === 'A') return true; + + var elem = $clicked.find('> .item .object_link a')[0]; + var e = evt.originalEvent; + var newEvent = new MouseEvent(evt.originalEvent.type); + newEvent.initMouseEvent(e.type, e.canBubble, e.cancelable, e.view, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget); + elem.dispatchEvent(newEvent); + evt.preventDefault(); + return false; + }); +} + +function enableToggles() { + // show/hide nested classes on toggle click + $('#full_list a.toggle').on('click', function(evt) { + evt.stopPropagation(); + evt.preventDefault(); + $(this).parent().parent().toggleClass('collapsed'); + highlight(); + }); +} + +function populateSearchCache() { + $('#full_list li .item').each(function() { + var $node = $(this); + var $link = $node.find('.object_link a'); + if ($link.length > 0) { + searchCache.push({ + node: $node, + link: $link, + name: $link.text(), + fullName: $link.attr('title').split(' ')[0] + }); + } + }); +} + +function enableSearch() { + $('#search input').keyup(function(event) { + if (ignoredKeyPress(event)) return; + if (this.value === "") { + clearSearch(); + } else { + performSearch(this.value); + } + }); + + $('#full_list').after(""); +} + +function ignoredKeyPress(event) { + if ( + (event.keyCode > ignoreKeyCodeMin && event.keyCode < ignoreKeyCodeMax) || + (event.keyCode == commandKey) + ) { + return true; + } else { + return false; + } +} + +function clearSearch() { + clearSearchTimeout(); + $('#full_list .found').removeClass('found').each(function() { + var $link = $(this).find('.object_link a'); + $link.text($link.text()); + }); + $('#full_list, #content').removeClass('insearch'); + $clicked.parents().removeClass('collapsed'); + highlight(); +} + +function performSearch(searchString) { + clearSearchTimeout(); + $('#full_list, #content').addClass('insearch'); + $('#noresults').text('').hide(); + partialSearch(searchString, 0); +} + +function partialSearch(searchString, offset) { + var lastRowClass = ''; + var i = null; + for (i = offset; i < Math.min(offset + 50, searchCache.length); i++) { + var item = searchCache[i]; + var searchName = (searchString.indexOf('::') != -1 ? item.fullName : item.name); + var matchString = buildMatchString(searchString); + var matchRegexp = new RegExp(matchString, caseSensitiveMatch ? "" : "i"); + if (searchName.match(matchRegexp) == null) { + item.node.removeClass('found'); + item.link.text(item.link.text()); + } + else { + item.node.addClass('found'); + item.node.removeClass(lastRowClass).addClass(lastRowClass == 'r1' ? 'r2' : 'r1'); + lastRowClass = item.node.hasClass('r1') ? 'r1' : 'r2'; + item.link.html(item.name.replace(matchRegexp, "$&")); + } + } + if(i == searchCache.length) { + searchDone(); + } else { + searchTimeout = setTimeout(function() { + partialSearch(searchString, i); + }, 0); + } +} + +function searchDone() { + searchTimeout = null; + highlight(); + if ($('#full_list li:visible').size() === 0) { + $('#noresults').text('No results were found.').hide().fadeIn(); + } else { + $('#noresults').text('').hide(); + } + $('#content').removeClass('insearch'); +} + +function buildMatchString(searchString, event) { + caseSensitiveMatch = searchString.match(/[A-Z]/) != null; + var regexSearchString = RegExp.escape(searchString); + if (caseSensitiveMatch) { + regexSearchString += "|" + + $.map(searchString.split(''), function(e) { return RegExp.escape(e); }). + join('.+?'); + } + return regexSearchString; +} + +function highlight() { + $('#full_list li:visible').each(function(n) { + $(this).removeClass('even odd').addClass(n % 2 == 0 ? 'odd' : 'even'); + }); +} + +/** + * Expands the tree to the target element and its immediate + * children. + */ +function expandTo(path) { + var $target = $(document.getElementById('object_' + path)); + $target.addClass('clicked'); + $target.removeClass('collapsed'); + $target.parentsUntil('#full_list', 'li').removeClass('collapsed'); + if($target[0]) { + window.scrollTo(window.scrollX, $target.offset().top - 250); + highlight(); + } +} + +function windowEvents(event) { + var msg = event.data; + if (msg.action === "expand") { + expandTo(msg.path); + } + return false; +} + +window.addEventListener("message", windowEvents, false); + +$(document).ready(function() { + escapeShortcut(); + navResizer(); + enableLinks(); + enableToggles(); + populateSearchCache(); + enableSearch(); +}); + +})(); diff --git a/docs/js/jquery.js b/docs/js/jquery.js new file mode 100644 index 000000000..979ed0824 --- /dev/null +++ b/docs/js/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
    a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
    "+""+"
    ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
    t
    ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
    ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

    ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
    ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
    ","
    "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
    ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/docs/method_list.html b/docs/method_list.html new file mode 100644 index 000000000..c4963eb8b --- /dev/null +++ b/docs/method_list.html @@ -0,0 +1,1291 @@ + + + + + + + + + + + + + + + + + + Method List + + + +
    +
    +

    Method List

    + + + +
    + +
      + + +
    • +
      + #add_uniqueness + SidekiqUniqueJobs::Job +
      +
    • + + +
    • +
      + #add_uniqueness_to_item + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #after_unlock_hook + SidekiqUniqueJobs::SidekiqWorkerMethods +
      +
    • + + +
    • +
      + #all + SidekiqUniqueJobs::Digests +
      +
    • + + +
    • +
      + #available_count + SidekiqUniqueJobs::Locksmith +
      +
    • + + +
    • +
      + banner + SidekiqUniqueJobs::Cli +
      +
    • + + +
    • +
      + #call + SidekiqUniqueJobs::OnConflict::Replace +
      +
    • + + +
    • +
      + #call + SidekiqUniqueJobs::OnConflict::NullStrategy +
      +
    • + + +
    • +
      + #call + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #call + SidekiqUniqueJobs::OnConflict::Reschedule +
      +
    • + + +
    • +
      + #call + SidekiqUniqueJobs::Server::Middleware +
      +
    • + + +
    • +
      + #call + SidekiqUniqueJobs::OnConflict::Raise +
      +
    • + + +
    • +
      + #call + SidekiqUniqueJobs::Client::Middleware +
      +
    • + + +
    • +
      + #call + SidekiqUniqueJobs::OnConflict::Strategy +
      +
    • + + +
    • +
      + call + SidekiqUniqueJobs::Scripts +
      +
    • + + +
    • +
      + #call + SidekiqUniqueJobs::OnConflict::Log +
      +
    • + + +
    • +
      + #clear + Sidekiq::Worker::ClassMethods +
      +
    • + + +
    • +
      + #clear_all_ext + Sidekiq::Worker::Overrides::Testing +
      +
    • + + +
    • +
      + #clear_ext + Sidekiq::JobSet::UniqueExtension +
      +
    • + + +
    • +
      + #clear_ext + Sidekiq::Queue::UniqueExtension +
      +
    • + + +
    • +
      + config + SidekiqUniqueJobs +
      +
    • + + +
    • +
      + configure + SidekiqUniqueJobs +
      +
    • + + +
    • +
      + #configure_client_middleware + SidekiqUniqueJobs::Middleware +
      +
    • + + +
    • +
      + #configure_middleware + SidekiqUniqueJobs::Middleware +
      +
    • + + +
    • +
      + #configure_server_middleware + SidekiqUniqueJobs::Middleware +
      +
    • + + +
    • +
      + #console + SidekiqUniqueJobs::Cli +
      +
    • + + +
    • +
      + #count + SidekiqUniqueJobs::Digests +
      +
    • + + +
    • +
      + #cparams + SidekiqUniqueJobs::Web::Helpers +
      +
    • + + +
    • +
      + #create_digest + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #current_time + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #deadset + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #deadset_kill + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #deadset_kill? + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #default_lock_timeout + SidekiqUniqueJobs::Timeout::Calculator +
      +
    • + + +
    • +
      + #default_unique_args_method + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #default_worker_options + SidekiqUniqueJobs::SidekiqWorkerMethods +
      +
    • + + +
    • +
      + #del + SidekiqUniqueJobs::Cli +
      +
    • + + +
    • +
      + #del + SidekiqUniqueJobs::Util +
      +
    • + + +
    • +
      + #del + SidekiqUniqueJobs::Digests +
      +
    • + + +
    • +
      + delete + SidekiqUniqueJobs::Unlockable +
      +
    • + + +
    • +
      + #delete + SidekiqUniqueJobs::Locksmith +
      +
    • + + +
    • +
      + #delete + SidekiqUniqueJobs::Lock::BaseLock +
      +
    • + + +
    • +
      + #delete! + SidekiqUniqueJobs::Locksmith +
      +
    • + + +
    • +
      + #delete! + SidekiqUniqueJobs::Lock::BaseLock +
      +
    • + + +
    • +
      + #delete_by_value_ext + Sidekiq::JobSet::UniqueExtension +
      +
    • + + +
    • +
      + #delete_ext + Sidekiq::SortedEntry::UniqueExtension +
      +
    • + + +
    • +
      + #delete_ext + Sidekiq::ScheduledSet::UniqueExtension +
      +
    • + + +
    • +
      + #delete_ext + Sidekiq::Job::UniqueExtension +
      +
    • + + +
    • +
      + #delete_job_by_digest + SidekiqUniqueJobs::OnConflict::Replace +
      +
    • + + +
    • +
      + #delete_lock + SidekiqUniqueJobs::OnConflict::Replace +
      +
    • + + +
    • +
      + digest + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #digestable_hash + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #execute + SidekiqUniqueJobs::Lock::UntilExecuting +
      +
    • + + +
    • +
      + #execute + SidekiqUniqueJobs::Lock::UntilExecuted +
      +
    • + + +
    • +
      + #execute + SidekiqUniqueJobs::Lock::WhileExecuting +
      +
    • + + +
    • +
      + #execute + SidekiqUniqueJobs::Lock::UntilAndWhileExecuting +
      +
    • + + +
    • +
      + #execute + SidekiqUniqueJobs::Lock::BaseLock +
      +
    • + + +
    • +
      + #execute + SidekiqUniqueJobs::Lock::UntilExpired +
      +
    • + + +
    • +
      + #execute + SidekiqUniqueJobs::Lock::WhileExecutingReject +
      +
    • + + +
    • +
      + execute_script + SidekiqUniqueJobs::Scripts +
      +
    • + + +
    • +
      + #exists? + SidekiqUniqueJobs::Locksmith +
      +
    • + + +
    • +
      + #extract_options! + Array +
      +
    • + + +
    • +
      + #filter_by_proc + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #filter_by_symbol + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #filtered_args + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + find_strategy + SidekiqUniqueJobs::OnConflict +
      +
    • + + +
    • +
      + handle_error + SidekiqUniqueJobs::Scripts +
      +
    • + + +
    • +
      + #initialize + SidekiqUniqueJobs::OnConflict::Strategy +
      +
    • + + +
    • +
      + #initialize + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #initialize + SidekiqUniqueJobs::Lock::BaseLock +
      +
    • + + +
    • +
      + #initialize + SidekiqUniqueJobs::OnConflict::Reschedule +
      +
    • + + +
    • +
      + #initialize + SidekiqUniqueJobs::Lock::WhileExecuting +
      +
    • + + +
    • +
      + #initialize + SidekiqUniqueJobs::ScriptError +
      +
    • + + +
    • +
      + #initialize + SidekiqUniqueJobs::Conflict +
      +
    • + + +
    • +
      + #initialize + SidekiqUniqueJobs::OnConflict::Replace +
      +
    • + + +
    • +
      + #initialize + SidekiqUniqueJobs::Timeout::Calculator +
      +
    • + + +
    • +
      + #initialize + SidekiqUniqueJobs::Locksmith +
      +
    • + + +
    • +
      + #item + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #item + SidekiqUniqueJobs::OnConflict::Strategy +
      +
    • + + +
    • +
      + #item + SidekiqUniqueJobs::Timeout::Calculator +
      +
    • + + +
    • +
      + jsonify + SidekiqUniqueJobs::Normalizer +
      +
    • + + +
    • +
      + #keys + SidekiqUniqueJobs::Cli +
      +
    • + + +
    • +
      + #keys + SidekiqUniqueJobs::Util +
      +
    • + + +
    • +
      + #keys_with_ttl + SidekiqUniqueJobs::Util +
      +
    • + + +
    • +
      + #kill_job_with_options + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #kill_job_without_options + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #kill_with_options? + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #lock + SidekiqUniqueJobs::OptionsWithFallback +
      +
    • + + +
    • +
      + #lock + SidekiqUniqueJobs::Lock::BaseLock +
      +
    • + + +
    • +
      + #lock + SidekiqUniqueJobs::Locksmith +
      +
    • + + +
    • +
      + #lock + SidekiqUniqueJobs::Lock::WhileExecuting +
      +
    • + + +
    • +
      + #lock_class + SidekiqUniqueJobs::OptionsWithFallback +
      +
    • + + +
    • +
      + #lock_expiration + SidekiqUniqueJobs::Timeout::Calculator +
      +
    • + + +
    • +
      + #lock_timeout + SidekiqUniqueJobs::Timeout::Calculator +
      +
    • + + +
    • +
      + #lock_type + SidekiqUniqueJobs::OptionsWithFallback +
      +
    • + + +
    • +
      + #locked? + SidekiqUniqueJobs::Lock::BaseLock +
      +
    • + + +
    • +
      + #locked? + SidekiqUniqueJobs::Locksmith +
      +
    • + + +
    • +
      + #log_debug + SidekiqUniqueJobs::Logging +
      +
    • + + +
    • +
      + #log_duplicate_payload? + SidekiqUniqueJobs::OptionsWithFallback +
      +
    • + + +
    • +
      + #log_error + SidekiqUniqueJobs::Logging +
      +
    • + + +
    • +
      + #log_fatal + SidekiqUniqueJobs::Logging +
      +
    • + + +
    • +
      + #log_info + SidekiqUniqueJobs::Logging +
      +
    • + + +
    • +
      + #log_warn + SidekiqUniqueJobs::Logging +
      +
    • + + +
    • +
      + #logger + SidekiqUniqueJobs::Logging +
      +
    • + + +
    • +
      + logger + SidekiqUniqueJobs +
      +
    • + + +
    • +
      + logger= + SidekiqUniqueJobs +
      +
    • + + +
    • +
      + #logging_context + SidekiqUniqueJobs::Logging +
      +
    • + + +
    • +
      + #options + SidekiqUniqueJobs::OptionsWithFallback +
      +
    • + + +
    • +
      + #page + SidekiqUniqueJobs::Digests +
      +
    • + + +
    • +
      + #payload + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #push_to_deadset + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #queue + SidekiqUniqueJobs::OnConflict::Replace +
      +
    • + + +
    • +
      + #redirect_to + SidekiqUniqueJobs::Web::Helpers +
      +
    • + + +
    • +
      + #redis + SidekiqUniqueJobs::Connection +
      +
    • + + +
    • +
      + redis_version + SidekiqUniqueJobs +
      +
    • + + +
    • +
      + registered + SidekiqUniqueJobs::Web +
      +
    • + + +
    • +
      + #replace? + SidekiqUniqueJobs::OnConflict::Strategy +
      +
    • + + +
    • +
      + #runtime_lock + SidekiqUniqueJobs::Lock::UntilAndWhileExecuting +
      +
    • + + +
    • +
      + #safe_relative_time + SidekiqUniqueJobs::Web::Helpers +
      +
    • + + +
    • +
      + #scheduled_at + SidekiqUniqueJobs::Timeout::Calculator +
      +
    • + + +
    • +
      + script_path + SidekiqUniqueJobs::Scripts +
      +
    • + + +
    • +
      + script_sha + SidekiqUniqueJobs::Scripts +
      +
    • + + +
    • +
      + script_source + SidekiqUniqueJobs::Scripts +
      +
    • + + +
    • +
      + #send_to_deadset + SidekiqUniqueJobs::OnConflict::Reject +
      +
    • + + +
    • +
      + #sidekiq_worker_class? + SidekiqUniqueJobs::SidekiqWorkerMethods +
      +
    • + + +
    • +
      + #slice + Hash +
      +
    • + + +
    • +
      + #slice! + Hash +
      +
    • + + +
    • +
      + #strategy + SidekiqUniqueJobs::Lock::WhileExecutingReject +
      +
    • + + +
    • +
      + #stringify_keys + Hash +
      +
    • + + +
    • +
      + #time_until_scheduled + SidekiqUniqueJobs::Timeout::Calculator +
      +
    • + + +
    • +
      + #transform_keys + Hash +
      +
    • + + +
    • +
      + #unique_across_queues? + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #unique_across_workers? + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #unique_args + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #unique_args_enabled? + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #unique_args_method + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #unique_digest + SidekiqUniqueJobs::OnConflict::Replace +
      +
    • + + +
    • +
      + #unique_digest + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #unique_disabled? + SidekiqUniqueJobs::OptionsWithFallback +
      +
    • + + +
    • +
      + #unique_enabled? + SidekiqUniqueJobs::OptionsWithFallback +
      +
    • + + +
    • +
      + #unique_prefix + SidekiqUniqueJobs::UniqueArgs +
      +
    • + + +
    • +
      + #unique_template + SidekiqUniqueJobs::Web::Helpers +
      +
    • + + +
    • +
      + #unique_type + SidekiqUniqueJobs::OptionsWithFallback +
      +
    • + + +
    • +
      + #unlock + SidekiqUniqueJobs::Lock::UntilExpired +
      +
    • + + +
    • +
      + #unlock + SidekiqUniqueJobs::Locksmith +
      +
    • + + +
    • +
      + unlock + SidekiqUniqueJobs::Unlockable +
      +
    • + + +
    • +
      + #unlock + SidekiqUniqueJobs::Lock::BaseLock +
      +
    • + + +
    • +
      + #unlock! + SidekiqUniqueJobs::Locksmith +
      +
    • + + +
    • +
      + use_config + SidekiqUniqueJobs +
      +
    • + + +
    • +
      + use_options + Sidekiq +
      +
    • + + +
    • +
      + #use_options + Sidekiq::Worker::ClassMethods +
      +
    • + + +
    • +
      + #worker_class + SidekiqUniqueJobs::SidekiqWorkerMethods +
      +
    • + + +
    • +
      + #worker_class_constantize + SidekiqUniqueJobs::SidekiqWorkerMethods +
      +
    • + + +
    • +
      + #worker_method_defined? + SidekiqUniqueJobs::SidekiqWorkerMethods +
      +
    • + + +
    • +
      + #worker_options + SidekiqUniqueJobs::SidekiqWorkerMethods +
      +
    • + + + +
    +
    + + diff --git a/docs/top-level-namespace.html b/docs/top-level-namespace.html new file mode 100644 index 000000000..d7e422303 --- /dev/null +++ b/docs/top-level-namespace.html @@ -0,0 +1,112 @@ + + + + + + + Top Level Namespace + + — Documentation by YARD 0.9.18 + + + + + + + + + + + + + + + + + + + +
    + + +

    Top Level Namespace + + + +

    +
    + + + + + + + + + + + +
    + +

    Defined Under Namespace

    +

    + + + Modules: Sidekiq, SidekiqUniqueJobs + + + + Classes: Array, Hash + + +

    + + + + + + + + + +
    + + + +
    + + \ No newline at end of file From ce2c09628901d71138409254f733e42972e6f9bd Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 1 Feb 2019 22:32:56 +0100 Subject: [PATCH 05/23] Prefer double quotes --- .rubocop_todo.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a3a36467e..9b68c0598 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -11,13 +11,13 @@ # AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS Naming/FileName: Exclude: - - '**/Gemfile' - - 'lib/sidekiq-unique-jobs.rb' + - "**/Gemfile" + - "lib/sidekiq-unique-jobs.rb" # Offense count: 2 RSpec/DescribeClass: Exclude: - - 'spec/unit/sidekiq_unique_jobs/core_ext_spec.rb' + - "spec/unit/sidekiq_unique_jobs/core_ext_spec.rb" # Offense count: 43 # Configuration parameters: Max. @@ -27,30 +27,30 @@ RSpec/ExampleLength: # Offense count: 29 RSpec/ExpectActual: Exclude: - - 'spec/routing/**/*' - - 'spec/examples/expiring_job_spec.rb' - - 'spec/examples/my_unique_job_spec.rb' + - "spec/routing/**/*" + - "spec/examples/expiring_job_spec.rb" + - "spec/examples/my_unique_job_spec.rb" # Offense count: 10 RSpec/ExpectInHook: Exclude: - - 'spec/integration/sidekiq/retry_set_spec.rb' - - 'spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb' - - 'spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb' - - 'spec/unit/sidekiq_unique_jobs/util_spec.rb' + - "spec/integration/sidekiq/retry_set_spec.rb" + - "spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb" + - "spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb" + - "spec/unit/sidekiq_unique_jobs/util_spec.rb" # Offense count: 27 # Configuration parameters: EnforcedStyle. # SupportedStyles: have_received, receive RSpec/MessageSpies: Exclude: - - 'spec/examples/spawn_simple_worker_spec.rb' - - 'spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb' - - 'spec/support/shared_examples/a_performing_worker.rb' - - 'spec/unit/sidekiq_unique_jobs/cli_spec.rb' - - 'spec/unit/sidekiq_unique_jobs/middleware_spec.rb' - - 'spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb' - - 'spec/unit/sidekiq_unique_jobs/scripts_spec.rb' + - "spec/examples/spawn_simple_worker_spec.rb" + - "spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb" + - "spec/support/shared_examples/a_performing_worker.rb" + - "spec/unit/sidekiq_unique_jobs/cli_spec.rb" + - "spec/unit/sidekiq_unique_jobs/middleware_spec.rb" + - "spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb" + - "spec/unit/sidekiq_unique_jobs/scripts_spec.rb" # Offense count: 76 # Configuration parameters: AggregateFailuresByDefault. @@ -60,7 +60,7 @@ RSpec/MultipleExpectations: # Offense count: 8 RSpec/RepeatedExample: Exclude: - - 'spec/unit/sidekiq_unique_jobs/unique_args_spec.rb' + - "spec/unit/sidekiq_unique_jobs/unique_args_spec.rb" # Offense count: 56 Style/Documentation: From 0658abe2acd31570739b33745daf34133c44afff Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 1 Feb 2019 22:35:44 +0100 Subject: [PATCH 06/23] Prefer automatic TOC --- README.md | 117 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 1e6a50722..493b738b3 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,53 @@ # SidekiqUniqueJobs [![Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs](https://badges.gitter.im/mhenrixon/sidekiq-unique-jobs.svg)](https://gitter.im/mhenrixon/sidekiq-unique-jobs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/mhenrixon/sidekiq-unique-jobs.png?branch=master)](https://travis-ci.org/mhenrixon/sidekiq-unique-jobs) [![Code Climate](https://codeclimate.com/github/mhenrixon/sidekiq-unique-jobs.png)](https://codeclimate.com/github/mhenrixon/sidekiq-unique-jobs) [![Test Coverage](https://codeclimate.com/github/mhenrixon/sidekiq-unique-jobs/badges/coverage.svg)](https://codeclimate.com/github/mhenrixon/sidekiq-unique-jobs/coverage) -## Table of contents - -* [Introduction](#introduction) -* [Documentation](#documentation) -* [Requirements](#requirements) -* [Installation](#installation) -* [Support Me](#support-me) -* [General Information](#general-information) -* [Options](#options) - * [Lock Expiration](#lock-expiration) - * [Lock Timeout](#lock-timeout) - * [Unique Across Queues](#unique-across-queues) - * [Unique Across Workers](#unique-across-workers) -* [Locks](#locks) - * [Until Executing](#until-executing) - * [Until Executed](#until-executed) - * [Until Timeout](#until-timeout) - * [Unique Until And While Executing](#unique-until-and-while-executing) - * [While Executing](#while-executing) -* [Conflict Strategy](#conflict-strategy) - * [Log](#log) - * [Raise](#raise) - * [Reject](#reject) - * [Replace](#replace) - * [Reschedule](#reschedule) -* [Usage](#usage) - * [Finer Control over Uniqueness](#finer-control-over-uniqueness) - * [After Unlock Callback](#after-unlock-callback) - * [Logging](#logging) - * [Cleanup Dead Locks](#cleanup-dead-locks) -* [Debugging](#debugging) - * [Sidekiq Web](#sidekiq-web) - * [Show Unique Digests](#show-unique-digests) - * [Show keys for digest](#show-keys-for-digest) -* [Communication](#communication) -* [Testing](#testing) -* [Contributing](#contributing) -* [Contributors](#contributors) - + + +- [Introduction](#introduction) +- [Documentation](#documentation) +- [Requirements](#requirements) +- [Installation](#installation) +- [Support Me](#support-me) +- [General Information](#general-information) +- [Options](#options) + - [Lock Expiration](#lock-expiration) + - [Lock Timeout](#lock-timeout) + - [Unique Across Queues](#unique-across-queues) + - [Unique Across Workers](#unique-across-workers) +- [Locks](#locks) + - [Until Executing](#until-executing) + - [Until Executed](#until-executed) + - [Until Timeout](#until-timeout) + - [Unique Until And While Executing](#unique-until-and-while-executing) + - [While Executing](#while-executing) +- [Conflict Strategy](#conflict-strategy) + - [Log](#log) + - [Raise](#raise) + - [Reject](#reject) + - [Replace](#replace) + - [Reschedule](#reschedule) +- [Usage](#usage) + - [Finer Control over Uniqueness](#finer-control-over-uniqueness) + - [After Unlock Callback](#after-unlock-callback) + - [Logging](#logging) + - [Cleanup Dead Locks](#cleanup-dead-locks) +- [Debugging](#debugging) + - [Sidekiq Web](#sidekiq-web) + - [Show Unique Digests](#show-unique-digests) + - [Show keys for digest](#show-keys-for-digest) +- [Communication](#communication) +- [Testing](#testing) +- [Contributing](#contributing) +- [Contributors](#contributors) + + + + + ## Introduction The goal of this gem is to ensure your Sidekiq jobs are unique. We do this by creating unique keys in Redis based on how you configure uniqueness. + ## Documentation This is the documentation for the master branch. You can find the documentation for each release by navigating to its tag: https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10. @@ -52,12 +57,14 @@ Below are links to the latest major versions (4 & 5): - [v5.0.10](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10) - [v4.0.18](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.18) + ## Requirements See https://github.com/mperham/sidekiq#requirements for what is required. Starting from 5.0.0 only sidekiq >= 4 is supported and support for MRI <= 2.1 is dropped. ActiveJob is not supported Version 6 requires Redis >= 3 and pure Sidekiq, no ActiveJob supported anymore. See [About ActiveJob](https://github.com/mhenrixon/sidekiq-unique-jobs/wiki/About-ActiveJob) for why. + ## Installation Add this line to your application's Gemfile: @@ -73,18 +80,22 @@ Or install it yourself as: $ gem install sidekiq-unique-jobs + ## Support Me Want to show me some ❤️ for the hard work I do on this gem? You can use the following PayPal link https://paypal.me/mhenrixon. Any amount is welcome and let me tell you it feels good to be appreciated. Even a dollar makes me super excited about all of this. + ## General Information See [Interaction w/ Sidekiq](https://github.com/mhenrixon/sidekiq-unique-jobs/wiki/How-this-gem-interacts-with-Sidekiq) on how the gem interacts with Sidekiq. See [Locking & Unlocking](https://github.com/mhenrixon/sidekiq-unique-jobs/wiki/Locking-&-Unlocking) for an overview of the differences on when the various lock types are locked and unlocked. + ## Options + ### Lock Expiration This is probably not the configuration option you want... @@ -98,6 +109,7 @@ sidekiq_options lock_expiration: nil # default - don't expire keys sidekiq_options lock_expiration: 20.days # expire this lock in 20 days ``` + ### Lock Timeout This is the timeout (how long to wait) when creating the lock. By default we don't use a timeout so we won't wait for the lock to be created. If you want it is possible to set this like below. @@ -108,6 +120,7 @@ sidekiq_options lock_timeout: 5 # wait 5 seconds sidekiq_options lock_timeout: nil # lock indefinitely, this process won't continue until it gets a lock. VERY DANGEROUS!! ``` + ### Unique Across Queues This configuration option is slightly misleading. It doesn't disregard the queue on other jobs. Just on itself, this means that a worker that might schedule jobs into multiple queues will be able to have uniqueness enforced on all queues it is pushed to. @@ -124,6 +137,7 @@ end Now if you push override the queue with `Worker.set(queue: 'another').perform_async(1)` it will still be considered unique when compared to `Worker.perform_async(1)` (that was actually pushed to the queue `default`). + ### Unique Across Workers This configuration option is slightly misleading. It doesn't disregard the worker class on other jobs. Just on itself, this means that a worker that the worker class won't be used for generating the unique digest. The only way this option really makes sense is when you want to have uniqueness between two different worker classes. @@ -153,8 +167,10 @@ WorkerTwo.perform_async(1) # => nil because WorkerOne just stole the lock ``` + ## Locks + ### Until Executing Locks from when the client pushes the job to the queue. Will be unlocked before the server starts processing the job. @@ -165,6 +181,7 @@ Locks from when the client pushes the job to the queue. Will be unlocked before sidekiq_options lock: :until_executing ``` + ### Until Executed Locks from when the client pushes the job to the queue. Will be unlocked when the server has successfully processed the job. @@ -173,6 +190,7 @@ Locks from when the client pushes the job to the queue. Will be unlocked when th sidekiq_options lock: :until_executed ``` + ### Until Timeout Locks from when the client pushes the job to the queue. Will be unlocked when the specified timeout has been reached. @@ -181,6 +199,7 @@ Locks from when the client pushes the job to the queue. Will be unlocked when th sidekiq_options lock: :until_expired ``` + ### Unique Until And While Executing Locks when the client pushes the job to the queue. The queue will be unlocked when the server starts processing the job. The server then goes on to creating a runtime lock for the job to prevent simultaneous jobs from being executed. As soon as the server starts processing a job, the client can push the same job to the queue. @@ -189,6 +208,7 @@ Locks when the client pushes the job to the queue. The queue will be unlocked wh sidekiq_options lock: :until_and_while_executing ``` + ### While Executing With this lock type it is possible to put any number of these jobs on the queue, but as the server pops the job from the queue it will create a lock and then wait until other locks are done processing. It _looks_ like multiple jobs are running at the same time but in fact the second job will only be waiting for the first job to finish. @@ -218,30 +238,35 @@ In the console you should see something like: 10:33:04 worker.1 | 2017-04-23T08:33:04.973Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: done: 40.014 sec ``` + ## Conflict Strategy Decides how we handle conflict. We can either reject the job to the dead queue or reschedule it. Both are useful for jobs that absolutely need to run and have been configured to use the lock `WhileExecuting` that is used only by the sidekiq server process. The last one is log which can be be used with the lock `UntilExecuted` and `UntilExpired`. Now we write a log entry saying the job could not be pushed because it is a duplicate of another job with the same arguments + ### Log This strategy is intended to be used with `UntilExecuted` and `UntilExpired`. It will log a line about that this is job is a duplicate of another. `sidekiq_options lock: :until_executed, on_conflict: :log` + ### Raise This strategy is intended to be used with `WhileExecuting`. Basically it will allow us to let the server process crash with a specific error message and be retried without messing up the Sidekiq stats. `sidekiq_options lock: :while_executing, on_conflict: :raise, retry: 10` + ### Reject This strategy is intended to be used with `WhileExecuting` and will push the job to the dead queue on conflict. `sidekiq_options lock: :while_executing, on_conflict: :reject` + ### Replace This strategy is intended to be used with client locks like `UntilExecuted`. @@ -253,12 +278,14 @@ always scheduled in the future. Currently only attempting to retry one time. `sidekiq_options lock: :until_executed, on_conflict: :replace` + ### Reschedule This strategy is intended to be used with `WhileExecuting` and will delay the job to be tried again in 5 seconds. This will mess up the sidekiq stats but will prevent exceptions from being logged and confuse your sysadmins. `sidekiq_options lock: :while_executing, on_conflict: :reschedule` + ## Usage All that is required is that you specifically set the sidekiq option for _unique_ to a valid value like below: @@ -269,6 +296,7 @@ sidekiq_options lock: :while_executing Requiring the gem in your gemfile should be sufficient to enable unique jobs. + ### Finer Control over Uniqueness Sometimes it is desired to have a finer control over which arguments are used in determining uniqueness of the job, and others may be _transient_. For this use-case, you need to define either a `unique_args` method, or a ruby proc. @@ -320,6 +348,7 @@ class UniqueJobWithFilterMethod end ``` + ### After Unlock Callback If you need to perform any additional work after the lock has been released you can provide an `#after_unlock` instance method. The method will be called when the lock has been unlocked. Most times this means after yield but there are two exceptions to that. @@ -339,6 +368,7 @@ class UniqueJobWithFilterMethod end. ``` + ### Logging To see logging in sidekiq when duplicate payload has been filtered out you can enable on a per worker basis using the sidekiq options. The default value is false @@ -354,6 +384,7 @@ class UniqueJobWithFilterMethod end ``` + ### Cleanup Dead Locks For sidekiq versions before 5.1 a `sidekiq_retries_exhausted` block is required per worker class. @@ -377,10 +408,12 @@ Sidekiq.configure_server do |config| end ``` + ## Debugging There are several ways of removing keys that are stuck. The prefered way is by using the unique extension to `Sidekiq::Web`. The old console and command line versions still work but might be deprecated in the future. It is better to search for the digest itself and delete the keys matching that digest. + ### Sidekiq Web To use the web extension you need to require it in your routes. @@ -397,18 +430,22 @@ already does this. To filter/search for keys we can use the wildcard `*`. If we have a unique digest `'uniquejobs:9e9b5ce5d423d3ea470977004b50ff84` we can search for it by enter `*ff84` and it should return all digests that end with `ff84`. + #### Show Unique Digests ![Unique Digests](assets/unique_digests_1.png) + #### Show keys for digest ![Unique Digests](assets/unique_digests_2.png) + ## Communication There is a [![Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs](https://badges.gitter.im/mhenrixon/sidekiq-unique-jobs.svg)](https://gitter.im/mhenrixon/sidekiq-unique-jobs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) for praise or scorn. This would be a good place to have lengthy discuss or brilliant suggestions or simply just nudge me if I forget about anything. + ## Testing This has been probably the most confusing part of this gem. People get really confused with how unreliable the unique jobs have been. I there for decided to do what Mike is doing for sidekiq enterprise. Read the section about unique jobs. @@ -459,6 +496,7 @@ I would strongly suggest you let this gem test uniqueness. If you care about how - [spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb) - [spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb) + ## Contributing 1. Fork it @@ -468,6 +506,7 @@ I would strongly suggest you let this gem test uniqueness. If you care about how 5. Create new Pull Request + ## Contributors You can find a list of contributors over on https://github.com/mhenrixon/sidekiq-unique-jobs/graphs/contributors From a4315679226493c2a1a49945a6460c5177bce5d4 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 1 Feb 2019 22:41:55 +0100 Subject: [PATCH 07/23] Remove docs folder --- docs/Array.html | 198 -- docs/Hash.html | 378 ---- docs/Sidekiq.html | 202 -- docs/Sidekiq/Job.html | 147 -- docs/Sidekiq/Job/UniqueExtension.html | 181 -- docs/Sidekiq/JobSet.html | 147 -- docs/Sidekiq/JobSet/UniqueExtension.html | 233 --- docs/Sidekiq/Queue.html | 147 -- docs/Sidekiq/Queue/UniqueExtension.html | 181 -- docs/Sidekiq/ScheduledSet.html | 147 -- .../Sidekiq/ScheduledSet/UniqueExtension.html | 179 -- docs/Sidekiq/SortedEntry.html | 147 -- docs/Sidekiq/SortedEntry/UniqueExtension.html | 179 -- docs/Sidekiq/Worker.html | 126 -- docs/Sidekiq/Worker/ClassMethods.html | 246 --- docs/Sidekiq/Worker/Overrides.html | 120 -- docs/Sidekiq/Worker/Overrides/Testing.html | 176 -- docs/SidekiqUniqueJobs.html | 767 -------- docs/SidekiqUniqueJobs/Cli.html | 415 ---- docs/SidekiqUniqueJobs/Client.html | 115 -- docs/SidekiqUniqueJobs/Client/Middleware.html | 353 ---- docs/SidekiqUniqueJobs/Conflict.html | 229 --- docs/SidekiqUniqueJobs/Connection.html | 240 --- docs/SidekiqUniqueJobs/Digests.html | 699 ------- docs/SidekiqUniqueJobs/Job.html | 222 --- docs/SidekiqUniqueJobs/Lock.html | 133 -- docs/SidekiqUniqueJobs/Lock/BaseLock.html | 801 -------- .../Lock/UntilAndWhileExecuting.html | 343 ---- .../SidekiqUniqueJobs/Lock/UntilExecuted.html | 282 --- .../Lock/UntilExecuting.html | 280 --- docs/SidekiqUniqueJobs/Lock/UntilExpired.html | 367 ---- .../Lock/WhileExecuting.html | 487 ----- .../Lock/WhileExecutingReject.html | 375 ---- docs/SidekiqUniqueJobs/Locksmith.html | 1082 ----------- docs/SidekiqUniqueJobs/Logging.html | 779 -------- docs/SidekiqUniqueJobs/Middleware.html | 335 ---- docs/SidekiqUniqueJobs/Normalizer.html | 242 --- docs/SidekiqUniqueJobs/OnConflict.html | 244 --- docs/SidekiqUniqueJobs/OnConflict/Log.html | 272 --- .../OnConflict/NullStrategy.html | 274 --- docs/SidekiqUniqueJobs/OnConflict/Raise.html | 275 --- docs/SidekiqUniqueJobs/OnConflict/Reject.html | 859 --------- .../SidekiqUniqueJobs/OnConflict/Replace.html | 654 ------- .../OnConflict/Reschedule.html | 362 ---- .../OnConflict/Strategy.html | 526 ----- .../OptionsWithFallback.html | 770 -------- docs/SidekiqUniqueJobs/ScriptError.html | 263 --- docs/SidekiqUniqueJobs/Scripts.html | 935 --------- docs/SidekiqUniqueJobs/Server.html | 115 -- docs/SidekiqUniqueJobs/Server/Middleware.html | 355 ---- .../SidekiqWorkerMethods.html | 704 ------- docs/SidekiqUniqueJobs/Timeout.html | 117 -- .../SidekiqUniqueJobs/Timeout/Calculator.html | 766 -------- docs/SidekiqUniqueJobs/UniqueArgs.html | 1704 ----------------- docs/SidekiqUniqueJobs/UnknownLock.html | 149 -- docs/SidekiqUniqueJobs/Unlockable.html | 318 --- docs/SidekiqUniqueJobs/Util.html | 611 ------ docs/SidekiqUniqueJobs/Web.html | 275 --- docs/SidekiqUniqueJobs/Web/Helpers.html | 393 ---- docs/_index.html | 633 ------ docs/class_list.html | 51 - docs/css/common.css | 1 - docs/css/full_list.css | 58 - docs/css/style.css | 496 ----- docs/file.README.html | 546 ------ docs/file_list.html | 56 - docs/frames.html | 17 - docs/index.html | 546 ------ docs/js/app.js | 292 --- docs/js/full_list.js | 216 --- docs/js/jquery.js | 4 - docs/method_list.html | 1291 ------------- docs/top-level-namespace.html | 112 -- 73 files changed, 26940 deletions(-) delete mode 100644 docs/Array.html delete mode 100644 docs/Hash.html delete mode 100644 docs/Sidekiq.html delete mode 100644 docs/Sidekiq/Job.html delete mode 100644 docs/Sidekiq/Job/UniqueExtension.html delete mode 100644 docs/Sidekiq/JobSet.html delete mode 100644 docs/Sidekiq/JobSet/UniqueExtension.html delete mode 100644 docs/Sidekiq/Queue.html delete mode 100644 docs/Sidekiq/Queue/UniqueExtension.html delete mode 100644 docs/Sidekiq/ScheduledSet.html delete mode 100644 docs/Sidekiq/ScheduledSet/UniqueExtension.html delete mode 100644 docs/Sidekiq/SortedEntry.html delete mode 100644 docs/Sidekiq/SortedEntry/UniqueExtension.html delete mode 100644 docs/Sidekiq/Worker.html delete mode 100644 docs/Sidekiq/Worker/ClassMethods.html delete mode 100644 docs/Sidekiq/Worker/Overrides.html delete mode 100644 docs/Sidekiq/Worker/Overrides/Testing.html delete mode 100644 docs/SidekiqUniqueJobs.html delete mode 100644 docs/SidekiqUniqueJobs/Cli.html delete mode 100644 docs/SidekiqUniqueJobs/Client.html delete mode 100644 docs/SidekiqUniqueJobs/Client/Middleware.html delete mode 100644 docs/SidekiqUniqueJobs/Conflict.html delete mode 100644 docs/SidekiqUniqueJobs/Connection.html delete mode 100644 docs/SidekiqUniqueJobs/Digests.html delete mode 100644 docs/SidekiqUniqueJobs/Job.html delete mode 100644 docs/SidekiqUniqueJobs/Lock.html delete mode 100644 docs/SidekiqUniqueJobs/Lock/BaseLock.html delete mode 100644 docs/SidekiqUniqueJobs/Lock/UntilAndWhileExecuting.html delete mode 100644 docs/SidekiqUniqueJobs/Lock/UntilExecuted.html delete mode 100644 docs/SidekiqUniqueJobs/Lock/UntilExecuting.html delete mode 100644 docs/SidekiqUniqueJobs/Lock/UntilExpired.html delete mode 100644 docs/SidekiqUniqueJobs/Lock/WhileExecuting.html delete mode 100644 docs/SidekiqUniqueJobs/Lock/WhileExecutingReject.html delete mode 100644 docs/SidekiqUniqueJobs/Locksmith.html delete mode 100644 docs/SidekiqUniqueJobs/Logging.html delete mode 100644 docs/SidekiqUniqueJobs/Middleware.html delete mode 100644 docs/SidekiqUniqueJobs/Normalizer.html delete mode 100644 docs/SidekiqUniqueJobs/OnConflict.html delete mode 100644 docs/SidekiqUniqueJobs/OnConflict/Log.html delete mode 100644 docs/SidekiqUniqueJobs/OnConflict/NullStrategy.html delete mode 100644 docs/SidekiqUniqueJobs/OnConflict/Raise.html delete mode 100644 docs/SidekiqUniqueJobs/OnConflict/Reject.html delete mode 100644 docs/SidekiqUniqueJobs/OnConflict/Replace.html delete mode 100644 docs/SidekiqUniqueJobs/OnConflict/Reschedule.html delete mode 100644 docs/SidekiqUniqueJobs/OnConflict/Strategy.html delete mode 100644 docs/SidekiqUniqueJobs/OptionsWithFallback.html delete mode 100644 docs/SidekiqUniqueJobs/ScriptError.html delete mode 100644 docs/SidekiqUniqueJobs/Scripts.html delete mode 100644 docs/SidekiqUniqueJobs/Server.html delete mode 100644 docs/SidekiqUniqueJobs/Server/Middleware.html delete mode 100644 docs/SidekiqUniqueJobs/SidekiqWorkerMethods.html delete mode 100644 docs/SidekiqUniqueJobs/Timeout.html delete mode 100644 docs/SidekiqUniqueJobs/Timeout/Calculator.html delete mode 100644 docs/SidekiqUniqueJobs/UniqueArgs.html delete mode 100644 docs/SidekiqUniqueJobs/UnknownLock.html delete mode 100644 docs/SidekiqUniqueJobs/Unlockable.html delete mode 100644 docs/SidekiqUniqueJobs/Util.html delete mode 100644 docs/SidekiqUniqueJobs/Web.html delete mode 100644 docs/SidekiqUniqueJobs/Web/Helpers.html delete mode 100644 docs/_index.html delete mode 100644 docs/class_list.html delete mode 100644 docs/css/common.css delete mode 100644 docs/css/full_list.css delete mode 100644 docs/css/style.css delete mode 100644 docs/file.README.html delete mode 100644 docs/file_list.html delete mode 100644 docs/frames.html delete mode 100644 docs/index.html delete mode 100644 docs/js/app.js delete mode 100644 docs/js/full_list.js delete mode 100644 docs/js/jquery.js delete mode 100644 docs/method_list.html delete mode 100644 docs/top-level-namespace.html diff --git a/docs/Array.html b/docs/Array.html deleted file mode 100644 index e670a1992..000000000 --- a/docs/Array.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - - - Class: Array - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: Array - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/core_ext.rb
    -
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #extract_options!Object - - - - - -

    - - - - -
    -
    -
    -
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -
    -
    # File 'lib/sidekiq_unique_jobs/core_ext.rb', line 44
    -
    -def extract_options!
    -  if last.is_a?(Hash) && last.instance_of?(Hash)
    -    pop
    -  else
    -    {}
    -  end
    -end
    -
    - - - - - - - - - - - \ No newline at end of file diff --git a/docs/Hash.html b/docs/Hash.html deleted file mode 100644 index b5b870dd1..000000000 --- a/docs/Hash.html +++ /dev/null @@ -1,378 +0,0 @@ - - - - - - - Class: Hash - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: Hash - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/core_ext.rb
    -
    - -
    - -

    Overview

    -
    -

    :nocov:

    - - -
    -
    -
    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #slice(*keys) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -7
    -8
    -9
    -10
    -
    -
    # File 'lib/sidekiq_unique_jobs/core_ext.rb', line 7
    -
    -def slice(*keys)
    -  keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
    -  keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if key?(k) }
    -end
    -
    -
    - -
    -

    - - #slice!(*keys) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -
    -
    # File 'lib/sidekiq_unique_jobs/core_ext.rb', line 30
    -
    -def slice!(*keys)
    -  keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
    -  omit = slice(*self.keys - keys)
    -  hash = slice(*keys)
    -  hash.default      = default
    -  hash.default_proc = default_proc if default_proc
    -  replace(hash)
    -  omit
    -end
    -
    -
    - -
    -

    - - #stringify_keysObject - - - - - -

    - - - - -
    -
    -
    -
    -14
    -15
    -16
    -
    -
    # File 'lib/sidekiq_unique_jobs/core_ext.rb', line 14
    -
    -def stringify_keys
    -  transform_keys(&:to_s)
    -end
    -
    -
    - -
    -

    - - #transform_keysObject - - - - - -

    - - - - -
    -
    -
    -
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -
    -
    # File 'lib/sidekiq_unique_jobs/core_ext.rb', line 20
    -
    -def transform_keys
    -  result = {}
    -  each_key do |key|
    -    result[yield(key)] = self[key]
    -  end
    -  result
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq.html b/docs/Sidekiq.html deleted file mode 100644 index ac383329d..000000000 --- a/docs/Sidekiq.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - Module: Sidekiq - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: Sidekiq - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/testing.rb,
    - lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - Modules: Worker - - - - Classes: Job, JobSet, Queue, ScheduledSet, SortedEntry - - -

    - - - - - - - - -

    - Class Method Summary - collapse -

    - - - - - - -
    -

    Class Method Details

    - - -
    -

    - - .use_options(tmp_config = {}) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -
    -
    # File 'lib/sidekiq_unique_jobs/testing.rb', line 9
    -
    -def self.use_options(tmp_config = {})
    -  old_config = default_worker_options
    -  default_worker_options.clear
    -  self.default_worker_options = tmp_config
    -
    -  yield
    -ensure
    -  default_worker_options.clear
    -  self.default_worker_options = old_config
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/Job.html b/docs/Sidekiq/Job.html deleted file mode 100644 index d7350c564..000000000 --- a/docs/Sidekiq/Job.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - Class: Sidekiq::Job - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: Sidekiq::Job - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    UniqueExtension
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - Modules: UniqueExtension - - - - -

    - - - - - - - - - - - - - - -

    Method Summary

    - -

    Methods included from UniqueExtension

    -

    #delete_ext

    - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/Job/UniqueExtension.html b/docs/Sidekiq/Job/UniqueExtension.html deleted file mode 100644 index 7c0746746..000000000 --- a/docs/Sidekiq/Job/UniqueExtension.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - - Module: Sidekiq::Job::UniqueExtension - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: Sidekiq::Job::UniqueExtension - - - -

    -
    - - - - - - - - - -
    -
    Included in:
    -
    Sidekiq::Job
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #delete_extObject - - - - - -

    - - - - -
    -
    -
    -
    -59
    -60
    -61
    -62
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 59
    -
    -def delete_ext
    -  delete_orig
    -  SidekiqUniqueJobs::Unlockable.unlock(item)
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/JobSet.html b/docs/Sidekiq/JobSet.html deleted file mode 100644 index b7fca6ffe..000000000 --- a/docs/Sidekiq/JobSet.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - Class: Sidekiq::JobSet - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: Sidekiq::JobSet - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    UniqueExtension
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - Modules: UniqueExtension - - - - -

    - - - - - - - - - - - - - - -

    Method Summary

    - -

    Methods included from UniqueExtension

    -

    #clear_ext, #delete_by_value_ext

    - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/JobSet/UniqueExtension.html b/docs/Sidekiq/JobSet/UniqueExtension.html deleted file mode 100644 index 6ca1c9791..000000000 --- a/docs/Sidekiq/JobSet/UniqueExtension.html +++ /dev/null @@ -1,233 +0,0 @@ - - - - - - - Module: Sidekiq::JobSet::UniqueExtension - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: Sidekiq::JobSet::UniqueExtension - - - -

    -
    - - - - - - - - - -
    -
    Included in:
    -
    Sidekiq::JobSet
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #clear_extObject - - - - - -

    - - - - -
    -
    -
    -
    -102
    -103
    -104
    -105
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 102
    -
    -def clear_ext
    -  each(&:delete)
    -  clear_orig
    -end
    -
    -
    - -
    -

    - - #delete_by_value_ext(name, value) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -107
    -108
    -109
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 107
    -
    -def delete_by_value_ext(name, value)
    -  SidekiqUniqueJobs::Unlockable.unlock(Sidekiq.load_json(value)) if delete_by_value_orig(name, value)
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/Queue.html b/docs/Sidekiq/Queue.html deleted file mode 100644 index 2fe2f4185..000000000 --- a/docs/Sidekiq/Queue.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - Class: Sidekiq::Queue - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: Sidekiq::Queue - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    UniqueExtension
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - Modules: UniqueExtension - - - - -

    - - - - - - - - - - - - - - -

    Method Summary

    - -

    Methods included from UniqueExtension

    -

    #clear_ext

    - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/Queue/UniqueExtension.html b/docs/Sidekiq/Queue/UniqueExtension.html deleted file mode 100644 index d5cf5ed44..000000000 --- a/docs/Sidekiq/Queue/UniqueExtension.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - - Module: Sidekiq::Queue::UniqueExtension - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: Sidekiq::Queue::UniqueExtension - - - -

    -
    - - - - - - - - - -
    -
    Included in:
    -
    Sidekiq::Queue
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #clear_extObject - - - - - -

    - - - - -
    -
    -
    -
    -77
    -78
    -79
    -80
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 77
    -
    -def clear_ext
    -  each(&:delete)
    -  clear_orig
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/ScheduledSet.html b/docs/Sidekiq/ScheduledSet.html deleted file mode 100644 index ffe874782..000000000 --- a/docs/Sidekiq/ScheduledSet.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - Class: Sidekiq::ScheduledSet - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: Sidekiq::ScheduledSet - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    UniqueExtension
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - Modules: UniqueExtension - - - - -

    - - - - - - - - - - - - - - -

    Method Summary

    - -

    Methods included from UniqueExtension

    -

    #delete_ext

    - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/ScheduledSet/UniqueExtension.html b/docs/Sidekiq/ScheduledSet/UniqueExtension.html deleted file mode 100644 index 2092f22c6..000000000 --- a/docs/Sidekiq/ScheduledSet/UniqueExtension.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - Module: Sidekiq::ScheduledSet::UniqueExtension - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: Sidekiq::ScheduledSet::UniqueExtension - - - -

    -
    - - - - - - - - - -
    -
    Included in:
    -
    Sidekiq::ScheduledSet
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #delete_extObject - - - - - -

    - - - - -
    -
    -
    -
    -43
    -44
    -45
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 43
    -
    -def delete_ext
    -  SidekiqUniqueJobs::Unlockable.unlock(item) if delete_orig
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/SortedEntry.html b/docs/Sidekiq/SortedEntry.html deleted file mode 100644 index 56eaa0829..000000000 --- a/docs/Sidekiq/SortedEntry.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - Class: Sidekiq::SortedEntry - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: Sidekiq::SortedEntry - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    UniqueExtension
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - Modules: UniqueExtension - - - - -

    - - - - - - - - - - - - - - -

    Method Summary

    - -

    Methods included from UniqueExtension

    -

    #delete_ext

    - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/SortedEntry/UniqueExtension.html b/docs/Sidekiq/SortedEntry/UniqueExtension.html deleted file mode 100644 index 6a72317de..000000000 --- a/docs/Sidekiq/SortedEntry/UniqueExtension.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - Module: Sidekiq::SortedEntry::UniqueExtension - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: Sidekiq::SortedEntry::UniqueExtension - - - -

    -
    - - - - - - - - - -
    -
    Included in:
    -
    Sidekiq::SortedEntry
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
    -
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #delete_extObject - - - - - -

    - - - - -
    -
    -
    -
    -17
    -18
    -19
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb', line 17
    -
    -def delete_ext
    -  SidekiqUniqueJobs::Unlockable.unlock(item) if delete_orig
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/Worker.html b/docs/Sidekiq/Worker.html deleted file mode 100644 index a8a3a11d9..000000000 --- a/docs/Sidekiq/Worker.html +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - Module: Sidekiq::Worker - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: Sidekiq::Worker - - - -

    -
    - - - - - - -
    -
    Includes:
    -
    Overrides
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/testing.rb
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - Modules: ClassMethods, Overrides - - - - -

    - - - - - - - - - - - - - - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/Worker/ClassMethods.html b/docs/Sidekiq/Worker/ClassMethods.html deleted file mode 100644 index 087333c2d..000000000 --- a/docs/Sidekiq/Worker/ClassMethods.html +++ /dev/null @@ -1,246 +0,0 @@ - - - - - - - Module: Sidekiq::Worker::ClassMethods - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: Sidekiq::Worker::ClassMethods - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/testing.rb
    -
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #clearObject - - - - - -

    - - - - -
    -
    -
    -
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -
    -
    # File 'lib/sidekiq_unique_jobs/testing.rb', line 31
    -
    -def clear
    -  jobs.each do |job|
    -    SidekiqUniqueJobs::Unlockable.delete(job)
    -  end
    -
    -  Sidekiq::Queues[queue].clear
    -  jobs.clear
    -end
    -
    -
    - -
    -

    - - #use_options(tmp_config = {}) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -
    -
    # File 'lib/sidekiq_unique_jobs/testing.rb', line 22
    -
    -def use_options(tmp_config = {})
    -  old_config = get_sidekiq_options
    -  sidekiq_options(tmp_config)
    -
    -  yield
    -ensure
    -  sidekiq_options(old_config)
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/Worker/Overrides.html b/docs/Sidekiq/Worker/Overrides.html deleted file mode 100644 index eaf5e49cf..000000000 --- a/docs/Sidekiq/Worker/Overrides.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - Module: Sidekiq::Worker::Overrides - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: Sidekiq::Worker::Overrides - - - -

    -
    - - - - - - - - - -
    -
    Included in:
    -
    Sidekiq::Worker
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/testing.rb
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - Modules: Testing - - - - -

    - - - - - - - - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/Sidekiq/Worker/Overrides/Testing.html b/docs/Sidekiq/Worker/Overrides/Testing.html deleted file mode 100644 index f22edd9ae..000000000 --- a/docs/Sidekiq/Worker/Overrides/Testing.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - - Module: Sidekiq::Worker::Overrides::Testing - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: Sidekiq::Worker::Overrides::Testing - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/testing.rb
    -
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #clear_all_extObject - - - - - -

    - - - - -
    -
    -
    -
    -53
    -54
    -55
    -56
    -
    -
    # File 'lib/sidekiq_unique_jobs/testing.rb', line 53
    -
    -def clear_all_ext
    -  clear_all_orig
    -  SidekiqUniqueJobs::Util.del("*", 1000)
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs.html b/docs/SidekiqUniqueJobs.html deleted file mode 100644 index e28372f83..000000000 --- a/docs/SidekiqUniqueJobs.html +++ /dev/null @@ -1,767 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs - - - -

    -
    - - - - - - -
    -
    Includes:
    -
    Connection
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs.rb,
    - lib/sidekiq_unique_jobs/cli.rb,
    lib/sidekiq_unique_jobs/job.rb,
    lib/sidekiq_unique_jobs/web.rb,
    lib/sidekiq_unique_jobs/util.rb,
    lib/sidekiq_unique_jobs/digests.rb,
    lib/sidekiq_unique_jobs/logging.rb,
    lib/sidekiq_unique_jobs/scripts.rb,
    lib/sidekiq_unique_jobs/timeout.rb,
    lib/sidekiq_unique_jobs/version.rb,
    lib/sidekiq_unique_jobs/constants.rb,
    lib/sidekiq_unique_jobs/locksmith.rb,
    lib/sidekiq_unique_jobs/connection.rb,
    lib/sidekiq_unique_jobs/exceptions.rb,
    lib/sidekiq_unique_jobs/middleware.rb,
    lib/sidekiq_unique_jobs/normalizer.rb,
    lib/sidekiq_unique_jobs/unlockable.rb,
    lib/sidekiq_unique_jobs/on_conflict.rb,
    lib/sidekiq_unique_jobs/unique_args.rb,
    lib/sidekiq_unique_jobs/web/helpers.rb,
    lib/sidekiq_unique_jobs/lock/base_lock.rb,
    lib/sidekiq_unique_jobs/on_conflict/log.rb,
    lib/sidekiq_unique_jobs/client/middleware.rb,
    lib/sidekiq_unique_jobs/on_conflict/raise.rb,
    lib/sidekiq_unique_jobs/server/middleware.rb,
    lib/sidekiq_unique_jobs/lock/until_expired.rb,
    lib/sidekiq_unique_jobs/on_conflict/reject.rb,
    lib/sidekiq_unique_jobs/timeout/calculator.rb,
    lib/sidekiq_unique_jobs/lock/until_executed.rb,
    lib/sidekiq_unique_jobs/on_conflict/replace.rb,
    lib/sidekiq_unique_jobs/lock/until_executing.rb,
    lib/sidekiq_unique_jobs/lock/while_executing.rb,
    lib/sidekiq_unique_jobs/on_conflict/strategy.rb,
    lib/sidekiq_unique_jobs/options_with_fallback.rb,
    lib/sidekiq_unique_jobs/on_conflict/reschedule.rb,
    lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb,
    lib/sidekiq_unique_jobs/on_conflict/null_strategy.rb,
    lib/sidekiq_unique_jobs/lock/while_executing_reject.rb,
    lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb
    -
    -
    - -
    - -

    Overview

    -
    -

    Module with constants to avoid string duplication

    - - -
    -
    -
    - -

    Author:

    - - -

    Defined Under Namespace

    -

    - - - Modules: Client, Connection, Digests, Job, Logging, Middleware, Normalizer, OnConflict, OptionsWithFallback, Scripts, Server, SidekiqWorkerMethods, Timeout, Unlockable, Util, Web - - - - Classes: Cli, Conflict, Lock, Locksmith, ScriptError, UniqueArgs, UnknownLock - - -

    - - -

    - Constant Summary - collapse -

    - -
    - -
    Config = - -
    -
    Concurrent::MutableStruct.new(
    -  :default_lock_timeout,
    -  :enabled,
    -  :unique_prefix,
    -  :logger,
    -)
    - -
    VERSION = - -
    -
    "6.0.8"
    - -
    - - - - - - - - - -

    - Class Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from Connection

    -

    #redis

    - - -
    -

    Class Method Details

    - - -
    -

    - - .configObject - - - - - -

    -
    -

    The current configuration (See: configure on how to configure)

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
    -
    -
    # File 'lib/sidekiq_unique_jobs.rb', line 53
    -
    -def config
    -  # Arguments here need to match the definition of the new class (see above)
    -  @config ||= Config.new(
    -    0,
    -    true,
    -    "uniquejobs",
    -    Sidekiq.logger,
    -  )
    -end
    -
    -
    - -
    -

    - - .configure(options = {}) { ... } ⇒ Object - - - - - -

    -
    -

    Configure the gem

    - -

    This is usually called once at startup of an application

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - options - - - (Hash) - - - (defaults to: {}) - - - — -

      global gem options

      -
      - -
    • - -
    - - - - -

    Options Hash (options):

    -
      - -
    • - :default_lock_timeout - (Integer) - - - — default: - default is 0 - - - -
    • - -
    • - :enabled - (true, false) - - - — default: - default is true - - - -
    • - -
    • - :unique_prefix - (String) - - - — default: - default is 'uniquejobs' - - - -
    • - -
    • - :logger - (Logger) - - - — default: - default is Sidekiq.logger - - - -
    • - -
    - - -

    Yields:

    -
      - -
    • - - - - - - - -

      control to the caller when given block

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -95
    -96
    -97
    -98
    -99
    -100
    -101
    -102
    -103
    -
    -
    # File 'lib/sidekiq_unique_jobs.rb', line 95
    -
    -def configure(options = {})
    -  if block_given?
    -    yield config
    -  else
    -    options.each do |key, val|
    -      config.send("#{key}=", val)
    -    end
    -  end
    -end
    -
    -
    - -
    -

    - - .loggerLogger - - - - - -

    -
    -

    The current logger

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Logger) - - - - — -

      the configured logger

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -65
    -66
    -67
    -
    -
    # File 'lib/sidekiq_unique_jobs.rb', line 65
    -
    -def logger
    -  config.logger
    -end
    -
    -
    - -
    -

    - - .logger=(other) ⇒ Object - - - - - -

    -
    -

    Set a new logger

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - other - - - (Logger) - - - - — -

      a new logger

      -
      - -
    • - -
    - - -
    - - - - -
    -
    -
    -
    -71
    -72
    -73
    -
    -
    # File 'lib/sidekiq_unique_jobs.rb', line 71
    -
    -def logger=(other)
    -  config.logger = other
    -end
    -
    -
    - -
    -

    - - .redis_versionObject - - - - - -

    - - - - -
    -
    -
    -
    -105
    -106
    -107
    -
    -
    # File 'lib/sidekiq_unique_jobs.rb', line 105
    -
    -def redis_version
    -  @redis_version ||= redis { |conn| conn.info("server")["redis_version"] }
    -end
    -
    -
    - -
    -

    - - .use_config(tmp_config) { ... } ⇒ Object - - - - - -

    -
    -

    Change global configuration while yielding

    - - -
    -
    -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      control to the caller

      -
      - -
    • - -
    -

    Raises:

    -
      - -
    • - - - (::ArgumentError) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -77
    -78
    -79
    -80
    -81
    -82
    -83
    -84
    -
    -
    # File 'lib/sidekiq_unique_jobs.rb', line 77
    -
    -def use_config(tmp_config)
    -  raise ::ArgumentError, "#{name}.#{__method__} needs a block" unless block_given?
    -
    -  old_config = config.to_h
    -  configure(tmp_config)
    -  yield
    -  configure(old_config)
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Cli.html b/docs/SidekiqUniqueJobs/Cli.html deleted file mode 100644 index 0978acbd9..000000000 --- a/docs/SidekiqUniqueJobs/Cli.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Cli - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Cli - - - -

    -
    - -
    -
    Inherits:
    -
    - Thor - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/cli.rb
    -
    - -
    - -

    Overview

    -
    -

    Command line interface for unique jobs

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Class Method Summary - collapse -

    - - - -

    - Instance Method Summary - collapse -

    - - - - - - - -
    -

    Class Method Details

    - - -
    - - - - - -
    -
    -
    -
    -12
    -13
    -14
    -
    -
    # File 'lib/sidekiq_unique_jobs/cli.rb', line 12
    -
    -def self.banner(command, _namespace = nil, _subcommand = false)
    -  "jobs #{@package_name} #{command.usage}"
    -end
    -
    -
    - -
    - -
    -

    Instance Method Details

    - - -
    -

    - - #consoleObject - - - - - -

    - - - - -
    -
    -
    -
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -
    -
    # File 'lib/sidekiq_unique_jobs/cli.rb', line 39
    -
    -def console
    -  say "Use `keys '*', 1000 to display the first 1000 unique keys matching '*'"
    -  say "Use `del '*', 1000, true (default) to see how many keys would be deleted for the pattern '*'"
    -  say "Use `del '*', 1000, false to delete the first 1000 keys matching '*'"
    -  Object.include SidekiqUniqueJobs::Util
    -  console_class.start
    -end
    -
    -
    - -
    -

    - - #del(pattern) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -
    -
    # File 'lib/sidekiq_unique_jobs/cli.rb', line 27
    -
    -def del(pattern)
    -  max_count = options[:count]
    -  if options[:dry_run]
    -    keys = Util.keys(pattern, max_count)
    -    say "Would delete #{keys.size} keys matching '#{pattern}'"
    -  else
    -    deleted_count = Util.del(pattern, max_count)
    -    say "Deleted #{deleted_count} keys matching '#{pattern}'"
    -  end
    -end
    -
    -
    - -
    -

    - - #keys(pattern = "*") ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -18
    -19
    -20
    -21
    -22
    -
    -
    # File 'lib/sidekiq_unique_jobs/cli.rb', line 18
    -
    -def keys(pattern = "*")
    -  keys = Util.keys(pattern, options[:count])
    -  say "Found #{keys.size} keys matching '#{pattern}':"
    -  print_in_columns(keys.sort) if keys.any?
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Client.html b/docs/SidekiqUniqueJobs/Client.html deleted file mode 100644 index a3a30c03d..000000000 --- a/docs/SidekiqUniqueJobs/Client.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Client - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Client - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/client/middleware.rb
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - - - Classes: Middleware - - -

    - - - - - - - - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Client/Middleware.html b/docs/SidekiqUniqueJobs/Client/Middleware.html deleted file mode 100644 index c198e7ef5..000000000 --- a/docs/SidekiqUniqueJobs/Client/Middleware.html +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Client::Middleware - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Client::Middleware - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    Logging, OptionsWithFallback
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/client/middleware.rb
    -
    - -
    - -

    Overview

    -
    -

    The unique sidekiq middleware for the client push

    - - -
    -
    -
    - -

    Author:

    - - -
    - - -

    Constant Summary

    - -

    Constants included - from OptionsWithFallback

    -

    OptionsWithFallback::LOCKS

    - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from OptionsWithFallback

    -

    #lock, #lock_class, #lock_type, #log_duplicate_payload?, #options, #unique_disabled?, #unique_enabled?, #unique_type

    - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    - - -
    -

    Instance Method Details

    - - -
    -

    - - #call(worker_class, item, queue, redis_pool = nil) { ... } ⇒ Object - - - - - -

    -
    -

    Calls this client middleware - Used from Sidekiq.process_single

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - worker_class - - - (String) - - - - — -

      name of the sidekiq worker class

      -
      - -
    • - -
    • - - item - - - (Hash) - - - - — -

      a sidekiq job hash

      -
      - -
    • - -
    • - - queue - - - (String) - - - - — -

      name of the queue

      -
      - -
    • - -
    • - - redis_pool - - - (Sidekiq::RedisConnection, ConnectionPool) - - - (defaults to: nil) - - - — -

      the redis connection

      -
      - -
    • - -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      when uniqueness is disable or lock successful

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -
    -
    # File 'lib/sidekiq_unique_jobs/client/middleware.rb', line 21
    -
    -def call(worker_class, item, queue, redis_pool = nil)
    -  @worker_class = worker_class
    -  @item         = item
    -  @queue        = queue
    -  @redis_pool   = redis_pool
    -
    -  yield if success?
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Conflict.html b/docs/SidekiqUniqueJobs/Conflict.html deleted file mode 100644 index 83eac9684..000000000 --- a/docs/SidekiqUniqueJobs/Conflict.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - - Exception: SidekiqUniqueJobs::Conflict - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Exception: SidekiqUniqueJobs::Conflict - - - -

    -
    - -
    -
    Inherits:
    -
    - StandardError - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/exceptions.rb
    -
    - -
    - -

    Overview

    -
    -

    Error raised when a Lua script fails to execute

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - -
    -

    Constructor Details

    - -
    -

    - - #initialize(item) ⇒ Conflict - - - - - -

    -
    -

    Returns a new instance of Conflict

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -8
    -9
    -10
    -
    -
    # File 'lib/sidekiq_unique_jobs/exceptions.rb', line 8
    -
    -def initialize(item)
    -  super("Item with the key: #{item[UNIQUE_DIGEST_KEY]} is already scheduled or processing")
    -end
    -
    -
    - -
    - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Connection.html b/docs/SidekiqUniqueJobs/Connection.html deleted file mode 100644 index 6dfe2f992..000000000 --- a/docs/SidekiqUniqueJobs/Connection.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Connection - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Connection - - - -

    -
    - - - - - - - - - -
    -
    Included in:
    -
    SidekiqUniqueJobs, Digests, Locksmith, Scripts, Util
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/connection.rb
    -
    - -
    - -

    Overview

    -
    -

    Shared module for dealing with redis connections

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #redis(redis_pool = nil) ⇒ Sidekiq::RedisConnection, ConnectionPool - - - - - -

    -
    -

    Creates a connection to redis

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Sidekiq::RedisConnection, ConnectionPool) - - - - — -

      a connection to redis

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -
    -
    # File 'lib/sidekiq_unique_jobs/connection.rb', line 14
    -
    -def redis(redis_pool = nil)
    -  if redis_pool
    -    redis_pool.with { |conn| yield conn }
    -  else
    -    Sidekiq.redis { |conn| yield conn }
    -  end
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Digests.html b/docs/SidekiqUniqueJobs/Digests.html deleted file mode 100644 index 5b2313559..000000000 --- a/docs/SidekiqUniqueJobs/Digests.html +++ /dev/null @@ -1,699 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Digests - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Digests - - - -

    -
    - - - - -
    -
    Extended by:
    -
    Digests
    -
    - - - -
    -
    Includes:
    -
    Connection, Logging
    -
    - - - - -
    -
    Included in:
    -
    Digests
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/digests.rb
    -
    - -
    - -

    Overview

    -
    -

    Utility module to help manage unique digests in redis.

    - - -
    -
    -
    - -

    Author:

    - - -
    - -

    - Constant Summary - collapse -

    - -
    - -
    DEFAULT_COUNT = - -
    -
    1_000
    - -
    SCAN_PATTERN = - -
    -
    "*"
    - -
    CHUNK_SIZE = - -
    -
    100
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from Connection

    -

    #redis

    - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    - - -
    -

    Instance Method Details

    - - -
    -

    - - #all(pattern: SCAN_PATTERN, count: DEFAULT_COUNT) ⇒ Array<String> - - - - - -

    -
    -

    Return unique digests matching pattern

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - pattern - - - (String) - - - - — -

      a pattern to match with

      -
      - -
    • - -
    • - - count - - - (Integer) - - - - — -

      the maximum number to match

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (Array<String>) - - - - — -

      with unique digests

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -21
    -22
    -23
    -
    -
    # File 'lib/sidekiq_unique_jobs/digests.rb', line 21
    -
    -def all(pattern: SCAN_PATTERN, count: DEFAULT_COUNT)
    -  redis { |conn| conn.sscan_each(UNIQUE_SET, match: pattern, count: count).to_a }
    -end
    -
    -
    - -
    -

    - - #countInteger - - - - - -

    -
    -

    Get a total count of unique digests

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Integer) - - - - — -

      number of digests

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -46
    -47
    -48
    -
    -
    # File 'lib/sidekiq_unique_jobs/digests.rb', line 46
    -
    -def count
    -  redis { |conn| conn.scard(UNIQUE_SET) }
    -end
    -
    -
    - -
    -

    - - #del(digest: nil, pattern: nil, count: DEFAULT_COUNT) ⇒ Array<String> - - - - - -

    -
    -

    Deletes unique digest either by a digest or pattern

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - digest - - - (String) - - - - — -

      the full digest to delete

      -
      - -
    • - -
    • - - pattern - - - (String) - - - - — -

      a key pattern to match with

      -
      - -
    • - -
    • - - count - - - (Integer) - - - - — -

      the maximum number

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (Array<String>) - - - - — -

      with unique digests

      -
      - -
    • - -
    -

    Raises:

    -
      - -
    • - - - (ArgumentError) - - - - — -

      when both pattern and digest are nil

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -57
    -58
    -59
    -60
    -61
    -62
    -
    -
    # File 'lib/sidekiq_unique_jobs/digests.rb', line 57
    -
    -def del(digest: nil, pattern: nil, count: DEFAULT_COUNT)
    -  return delete_by_pattern(pattern, count: count) if pattern
    -  return delete_by_digest(digest) if digest
    -
    -  raise ArgumentError, "either digest or pattern need to be provided"
    -end
    -
    -
    - -
    -

    - - #page(pattern: SCAN_PATTERN, cursor: 0, page_size: 100) ⇒ Array<String> - - - - - -

    -
    -

    Paginate unique digests

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - pattern - - - (String) - - - - — -

      a pattern to match with

      -
      - -
    • - -
    • - - cursor - - - (Integer) - - - - — -

      the maximum number to match

      -
      - -
    • - -
    • - - page_size - - - (Integer) - - - - — -

      the current cursor position

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (Array<String>) - - - - — -

      with unique digests

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -
    -
    # File 'lib/sidekiq_unique_jobs/digests.rb', line 32
    -
    -def page(pattern: SCAN_PATTERN, cursor: 0, page_size: 100)
    -  redis do |conn|
    -    total_size, digests = conn.multi do
    -      conn.scard(UNIQUE_SET)
    -      conn.sscan(UNIQUE_SET, cursor, match: pattern, count: page_size)
    -    end
    -
    -    [total_size, digests[0], digests[1]]
    -  end
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Job.html b/docs/SidekiqUniqueJobs/Job.html deleted file mode 100644 index 51be59a80..000000000 --- a/docs/SidekiqUniqueJobs/Job.html +++ /dev/null @@ -1,222 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Job - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Job - - - -

    -
    - - - - -
    -
    Extended by:
    -
    Job
    -
    - - - - - - -
    -
    Included in:
    -
    Job
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/job.rb
    -
    - -
    - -

    Overview

    -
    -

    Utility class to append uniqueness to the sidekiq job hash

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - -
      - -
    • - - - #add_uniqueness(item) ⇒ void - - - - - - - - - - - - - -

      Adds timeout, expiration, unique_args, unique_prefix and unique_digest to the sidekiq job hash.

      -
      - -
    • - - -
    - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #add_uniqueness(item) ⇒ void - - - - - -

    -
    -

    This method returns an undefined value.

    Adds timeout, expiration, unique_args, unique_prefix and unique_digest to the sidekiq job hash

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -12
    -13
    -14
    -15
    -
    -
    # File 'lib/sidekiq_unique_jobs/job.rb', line 12
    -
    -def add_uniqueness(item)
    -  add_timeout_and_expiration(item)
    -  add_unique_args_and_digest(item)
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock.html b/docs/SidekiqUniqueJobs/Lock.html deleted file mode 100644 index f0c681ba0..000000000 --- a/docs/SidekiqUniqueJobs/Lock.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Lock - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Lock - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/lock/base_lock.rb,
    - lib/sidekiq_unique_jobs/lock/until_expired.rb,
    lib/sidekiq_unique_jobs/lock/until_executed.rb,
    lib/sidekiq_unique_jobs/lock/until_executing.rb,
    lib/sidekiq_unique_jobs/lock/while_executing.rb,
    lib/sidekiq_unique_jobs/lock/while_executing_reject.rb,
    lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb
    -
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - - - Classes: BaseLock, UntilAndWhileExecuting, UntilExecuted, UntilExecuting, UntilExpired, WhileExecuting, WhileExecutingReject - - -

    - - - - - - - - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/BaseLock.html b/docs/SidekiqUniqueJobs/Lock/BaseLock.html deleted file mode 100644 index ed6659fd0..000000000 --- a/docs/SidekiqUniqueJobs/Lock/BaseLock.html +++ /dev/null @@ -1,801 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Lock::BaseLock - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Lock::BaseLock - Abstract - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    SidekiqUniqueJobs::Logging
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/lock/base_lock.rb
    -
    - -
    - -

    Overview

    -
    -
    - This class is abstract. -
    -
    -

    Abstract base class for locks

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from SidekiqUniqueJobs::Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -
    -

    - - #initialize(item, callback, redis_pool = nil) ⇒ BaseLock - - - - - -

    -
    -

    Returns a new instance of BaseLock

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      the Sidekiq job hash

      -
      - -
    • - -
    • - - callback - - - (Proc) - - - - — -

      the callback to use after unlock

      -
      - -
    • - -
    • - - redis_pool - - - (Sidekiq::RedisConnection, ConnectionPool) - - - (defaults to: nil) - - - — -

      the redis connection

      -
      - -
    • - -
    - - -
    - - - - -
    -
    -
    -
    -15
    -16
    -17
    -18
    -19
    -20
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 15
    -
    -def initialize(item, callback, redis_pool = nil)
    -  @item       = item
    -  @callback   = callback
    -  @redis_pool = redis_pool
    -  add_uniqueness_when_missing # Used to ease testing
    -end
    -
    -
    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #deleteObject - - - - - -

    -
    -

    Deletes the job from redis if it is locked.

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -50
    -51
    -52
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 50
    -
    -def delete
    -  locksmith.delete # Soft delete (don't forcefully remove when expiration is set)
    -end
    -
    -
    - -
    -

    - - #delete!Object - - - - - -

    -
    -

    Forcefully deletes the job from redis. - This is good for jobs when a previous lock was not unlocked

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -56
    -57
    -58
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 56
    -
    -def delete!
    -  locksmith.delete! # Force delete the lock
    -end
    -
    -
    - -
    -

    - - #executeObject - - - - - -

    -
    -

    Execute the job in the Sidekiq server processor

    - - -
    -
    -
    - -

    Raises:

    -
      - -
    • - - - (NotImplementedError) - - - - — -

      needs to be implemented in child class

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -38
    -39
    -40
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 38
    -
    -def execute
    -  raise NotImplementedError, "##{__method__} needs to be implemented in #{self.class}"
    -end
    -
    -
    - -
    -

    - - #lockString - - - - - -

    -
    -

    Handles locking of sidekiq jobs. - Will call a conflict strategy if lock can't be achieved.

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (String) - - - - — -

      the sidekiq job id

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 25
    -
    -def lock
    -  @attempt = 0
    -  return item[JID_KEY] if locked?
    -
    -  if (token = locksmith.lock(item[LOCK_TIMEOUT_KEY]))
    -    token
    -  else
    -    call_strategy
    -  end
    -end
    -
    -
    - -
    -

    - - #locked?true, false - - - - - -

    -
    -

    Checks if the item has achieved a lock

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (true) - - - - — -

      when this jid has locked the job

      -
      - -
    • - -
    • - - - (false) - - - - — -

      when this jid has not locked the job

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -63
    -64
    -65
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 63
    -
    -def locked?
    -  locksmith.locked?(item[JID_KEY])
    -end
    -
    -
    - -
    -

    - - #unlockString, false - - - - - -

    -
    -

    Unlocks the job from redis

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (String) - - - - — -

      sidekiq job id when successful

      -
      - -
    • - -
    • - - - (false) - - - - — -

      when unsuccessful

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -45
    -46
    -47
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/base_lock.rb', line 45
    -
    -def unlock
    -  locksmith.unlock(item[JID_KEY]) # Only signal to release the lock
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/UntilAndWhileExecuting.html b/docs/SidekiqUniqueJobs/Lock/UntilAndWhileExecuting.html deleted file mode 100644 index ac4d83b2b..000000000 --- a/docs/SidekiqUniqueJobs/Lock/UntilAndWhileExecuting.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Lock::UntilAndWhileExecuting - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Lock::UntilAndWhileExecuting - - - -

    -
    - -
    -
    Inherits:
    -
    - BaseLock - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb
    -
    - -
    - -

    Overview

    -
    -

    Locks jobs while the job is executing in the server process

    - -
      -
    • Locks on perform_in or perform_async (see UntilExecuting)
    • -
    • Unlocks before yielding to the worker's perform method (see UntilExecuting)
    • -
    • Locks before yielding to the worker's perform method (see WhileExecuting)
    • -
    • Unlocks after yielding to the worker's perform method (see WhileExecuting)
    • -
    - -

    See BaseLock#lock for more information about the client. -See #execute for more information about the server

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods inherited from BaseLock

    -

    #delete, #delete!, #initialize, #lock, #locked?, #unlock

    - - - - - - - - - -

    Methods included from SidekiqUniqueJobs::Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -

    This class inherits a constructor from SidekiqUniqueJobs::Lock::BaseLock

    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #execute { ... } ⇒ Object - - - - - -

    -
    -

    Executes in the Sidekiq server process

    - - -
    -
    -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      to the worker class perform method

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb', line 18
    -
    -def execute
    -  return unless locked?
    -
    -  unlock
    -
    -  runtime_lock.execute { yield }
    -end
    -
    -
    - -
    -

    - - #runtime_lockObject - - - - - -

    - - - - -
    -
    -
    -
    -26
    -27
    -28
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb', line 26
    -
    -def runtime_lock
    -  @runtime_lock ||= SidekiqUniqueJobs::Lock::WhileExecuting.new(item, callback, redis_pool)
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/UntilExecuted.html b/docs/SidekiqUniqueJobs/Lock/UntilExecuted.html deleted file mode 100644 index 709d242f5..000000000 --- a/docs/SidekiqUniqueJobs/Lock/UntilExecuted.html +++ /dev/null @@ -1,282 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Lock::UntilExecuted - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Lock::UntilExecuted - - - -

    -
    - -
    -
    Inherits:
    -
    - BaseLock - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/lock/until_executed.rb
    -
    - -
    - -

    Overview

    -
    -

    Locks jobs until the server is done executing the job

    - -
      -
    • Locks on perform_in or perform_async
    • -
    • Unlocks after yielding to the worker's perform method
    • -
    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods inherited from BaseLock

    -

    #delete, #delete!, #initialize, #lock, #locked?, #unlock

    - - - - - - - - - -

    Methods included from SidekiqUniqueJobs::Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -

    This class inherits a constructor from SidekiqUniqueJobs::Lock::BaseLock

    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #execute { ... } ⇒ Object - - - - - -

    -
    -

    Executes in the Sidekiq server process

    - - -
    -
    -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      to the worker class perform method

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -15
    -16
    -17
    -18
    -19
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/until_executed.rb', line 15
    -
    -def execute
    -  return unless locked?
    -
    -  with_cleanup { yield }
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/UntilExecuting.html b/docs/SidekiqUniqueJobs/Lock/UntilExecuting.html deleted file mode 100644 index 56bc38212..000000000 --- a/docs/SidekiqUniqueJobs/Lock/UntilExecuting.html +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Lock::UntilExecuting - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Lock::UntilExecuting - - - -

    -
    - -
    -
    Inherits:
    -
    - BaseLock - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/lock/until_executing.rb
    -
    - -
    - -

    Overview

    -
    -

    Locks jobs until #execute starts

    - -
      -
    • Locks on perform_in or perform_async
    • -
    • Unlocks before yielding to the worker's perform method
    • -
    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods inherited from BaseLock

    -

    #delete, #delete!, #initialize, #lock, #locked?, #unlock

    - - - - - - - - - -

    Methods included from SidekiqUniqueJobs::Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -

    This class inherits a constructor from SidekiqUniqueJobs::Lock::BaseLock

    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #execute { ... } ⇒ Object - - - - - -

    -
    -

    Executes in the Sidekiq server process

    - - -
    -
    -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      to the worker class perform method

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -13
    -14
    -15
    -16
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/until_executing.rb', line 13
    -
    -def execute
    -  unlock_with_callback
    -  yield
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/UntilExpired.html b/docs/SidekiqUniqueJobs/Lock/UntilExpired.html deleted file mode 100644 index 2087cad2b..000000000 --- a/docs/SidekiqUniqueJobs/Lock/UntilExpired.html +++ /dev/null @@ -1,367 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Lock::UntilExpired - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Lock::UntilExpired - - - -

    -
    - -
    -
    Inherits:
    -
    - BaseLock - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/lock/until_expired.rb
    -
    - -
    - -

    Overview

    -
    -

    Locks jobs until the lock has expired

    - -
      -
    • Locks on perform_in or perform_async
    • -
    • Unlocks when the expiration is hit
    • -
    - -

    See BaseLock#lock for more information about the client. -See #execute for more information about the server

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods inherited from BaseLock

    -

    #delete, #delete!, #initialize, #lock, #locked?

    - - - - - - - - - -

    Methods included from SidekiqUniqueJobs::Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -

    This class inherits a constructor from SidekiqUniqueJobs::Lock::BaseLock

    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #execute { ... } ⇒ Object - - - - - -

    -
    -

    Executes in the Sidekiq server process

    - - -
    -
    -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      to the worker class perform method

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -22
    -23
    -24
    -25
    -26
    -27
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/until_expired.rb', line 22
    -
    -def execute
    -  return unless locked?
    -
    -  yield
    -  # this lock does not handle after_unlock since we don't know when that would happen
    -end
    -
    -
    - -
    -

    - - #unlocktrue - - - - - -

    -
    -

    Prevents these locks from being unlocked

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (true) - - - - — -

      always returns true

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -16
    -17
    -18
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/until_expired.rb', line 16
    -
    -def unlock
    -  true
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/WhileExecuting.html b/docs/SidekiqUniqueJobs/Lock/WhileExecuting.html deleted file mode 100644 index 382e9c755..000000000 --- a/docs/SidekiqUniqueJobs/Lock/WhileExecuting.html +++ /dev/null @@ -1,487 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Lock::WhileExecuting - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Lock::WhileExecuting - - - -

    -
    - -
    -
    Inherits:
    -
    - BaseLock - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/lock/while_executing.rb
    -
    - -
    - -

    Overview

    -
    -

    Locks jobs while the job is executing in the server process

    - -
      -
    • Locks before yielding to the worker's perform method
    • -
    • Unlocks after yielding to the worker's perform method
    • -
    - -

    See #lock for more information about the client. -See #execute for more information about the server

    - - -
    -
    -
    - -

    Author:

    - - -
    -

    Direct Known Subclasses

    -

    WhileExecutingReject

    -
    - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods inherited from BaseLock

    -

    #delete, #delete!, #locked?, #unlock

    - - - - - - - - - -

    Methods included from SidekiqUniqueJobs::Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -
    -

    - - #initialize(item, callback, redis_pool = nil) ⇒ WhileExecuting - - - - - -

    -
    -

    Returns a new instance of WhileExecuting

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      the Sidekiq job hash

      -
      - -
    • - -
    • - - callback - - - (Proc) - - - - — -

      callback to call after unlock

      -
      - -
    • - -
    • - - redis_pool - - - (Sidekiq::RedisConnection, ConnectionPool) - - - (defaults to: nil) - - - — -

      the redis connection

      -
      - -
    • - -
    - - -
    - - - - -
    -
    -
    -
    -19
    -20
    -21
    -22
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/while_executing.rb', line 19
    -
    -def initialize(item, callback, redis_pool = nil)
    -  super(item, callback, redis_pool)
    -  append_unique_key_suffix
    -end
    -
    -
    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #execute { ... } ⇒ Object - - - - - -

    -
    -

    Executes in the Sidekiq server process. - These jobs are locked in the server process not from the client

    - - -
    -
    -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      to the worker class perform method

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -34
    -35
    -36
    -37
    -38
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/while_executing.rb', line 34
    -
    -def execute
    -  return strategy.call unless locksmith.lock(item[LOCK_TIMEOUT_KEY])
    -
    -  with_cleanup { yield }
    -end
    -
    -
    - -
    -

    - - #locktrue - - - - - -

    -
    -

    Simulate that a client lock was achieved. - These locks should only ever be created in the server process.

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (true) - - - - — -

      always returns true

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -27
    -28
    -29
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/while_executing.rb', line 27
    -
    -def lock
    -  true
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Lock/WhileExecutingReject.html b/docs/SidekiqUniqueJobs/Lock/WhileExecutingReject.html deleted file mode 100644 index 78187b4bd..000000000 --- a/docs/SidekiqUniqueJobs/Lock/WhileExecutingReject.html +++ /dev/null @@ -1,375 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Lock::WhileExecutingReject - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Lock::WhileExecutingReject - - - -

    -
    - -
    -
    Inherits:
    -
    - WhileExecuting - - - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/lock/while_executing_reject.rb
    -
    - -
    - -

    Overview

    -
    -

    Locks jobs while executing - Locks from the server process - Unlocks after the server is done processing

    - -

    See SidekiqUniqueJobs::Lock::WhileExecuting#lock for more information about the client. -See #execute for more information about the server

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods inherited from WhileExecuting

    -

    #initialize, #lock

    - - - - - - - - - -

    Methods inherited from BaseLock

    -

    #delete, #delete!, #initialize, #lock, #locked?, #unlock

    - - - - - - - - - -

    Methods included from SidekiqUniqueJobs::Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -

    This class inherits a constructor from SidekiqUniqueJobs::Lock::WhileExecuting

    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #execute { ... } ⇒ Object - - - - - -

    -
    -

    Executes in the Sidekiq server process

    - - -
    -
    -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      to the worker class perform method

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -16
    -17
    -18
    -19
    -20
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/while_executing_reject.rb', line 16
    -
    -def execute
    -  return strategy.call unless locksmith.lock(item[LOCK_TIMEOUT_KEY])
    -
    -  with_cleanup { yield }
    -end
    -
    -
    - -
    -

    - - #strategyOnConflict::Reject - - - - - -

    -
    -

    Overridden with a forced OnConflict::Reject strategy

    - - -
    -
    -
    - -

    Returns:

    - - -
    - - - - -
    -
    -
    -
    -24
    -25
    -26
    -
    -
    # File 'lib/sidekiq_unique_jobs/lock/while_executing_reject.rb', line 24
    -
    -def strategy
    -  @strategy ||= OnConflict.find_strategy(:reject).new(item)
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Locksmith.html b/docs/SidekiqUniqueJobs/Locksmith.html deleted file mode 100644 index 8bb710a8d..000000000 --- a/docs/SidekiqUniqueJobs/Locksmith.html +++ /dev/null @@ -1,1082 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Locksmith - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Locksmith - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    Connection
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/locksmith.rb
    -
    - -
    - -

    Overview

    -
    -

    Lock manager class that handles all the various locks

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from Connection

    -

    #redis

    -
    -

    Constructor Details

    - -
    -

    - - #initialize(item, redis_pool = nil) ⇒ Locksmith - - - - - -

    -
    -

    Returns a new instance of Locksmith

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      a Sidekiq job hash

      -
      - -
    • - -
    • - - redis_pool - - - (Sidekiq::RedisConnection, ConnectionPool) - - - (defaults to: nil) - - - — -

      the redis connection

      -
      - -
    • - -
    - - - - -

    Options Hash (item):

    -
      - -
    • - :lock_expiration - (Integer) - - - - - —

      the configured expiration

      -
      - -
    • - -
    • - :jid - (String) - - - - - —

      the sidekiq job id

      -
      - -
    • - -
    • - :unique_digest - (String) - - - - - —

      the unique digest (See: UniqueArgs#unique_digest)

      -
      - -
    • - -
    - - - - - -
    - - - - -
    -
    -
    -
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -
    -
    # File 'lib/sidekiq_unique_jobs/locksmith.rb', line 15
    -
    -def initialize(item, redis_pool = nil)
    -  @concurrency   = 1 # removed in a0cff5bc42edbe7190d6ede7e7f845074d2d7af6
    -  @expiration    = item[LOCK_EXPIRATION_KEY]
    -  @jid           = item[JID_KEY]
    -  @unique_digest = item[UNIQUE_DIGEST_KEY]
    -  @redis_pool    = redis_pool
    -end
    -
    -
    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #available_countInteger - - - - - -

    -
    -

    The number of available resourced for this lock

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Integer) - - - - — -

      the number of available resources

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -31
    -32
    -33
    -34
    -35
    -
    -
    # File 'lib/sidekiq_unique_jobs/locksmith.rb', line 31
    -
    -def available_count
    -  return concurrency unless exists?
    -
    -  redis(redis_pool) { |conn| conn.llen(available_key) }
    -end
    -
    -
    - -
    -

    - - #deleteObject - - - - - -

    -
    -

    Deletes the lock unless it has an expiration set

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -38
    -39
    -40
    -41
    -42
    -
    -
    # File 'lib/sidekiq_unique_jobs/locksmith.rb', line 38
    -
    -def delete
    -  return if expiration
    -
    -  delete!
    -end
    -
    -
    - -
    -

    - - #delete!Object - - - - - -

    -
    -

    Deletes the lock regardless of if it has an expiration set

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -
    -
    # File 'lib/sidekiq_unique_jobs/locksmith.rb', line 45
    -
    -def delete!
    -  Scripts.call(
    -    :delete,
    -    redis_pool,
    -    keys: [exists_key, grabbed_key, available_key, version_key, UNIQUE_SET, unique_digest],
    -  )
    -end
    -
    -
    - -
    -

    - - #exists?true, false - - - - - -

    -
    -

    Checks if the exists key is created in redis

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (true, false) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -25
    -26
    -27
    -
    -
    # File 'lib/sidekiq_unique_jobs/locksmith.rb', line 25
    -
    -def exists?
    -  redis(redis_pool) { |conn| conn.exists(exists_key) }
    -end
    -
    -
    - -
    -

    - - #lock(timeout = nil) { ... } ⇒ Object - - - - Also known as: - wait - - - - -

    -
    -

    Create a lock for the item

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - timeout - - - (Integer) - - - (defaults to: nil) - - - — -

      the number of seconds to wait for a lock. -nil means wait indefinitely

      -
      - -
    • - -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      the block to execute if a lock is successful

      -
      - -
    • - -
    -

    Returns:

    -
      - -
    • - - - - - - - -

      the Sidekiq job_id (jid)

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -58
    -59
    -60
    -61
    -62
    -63
    -64
    -65
    -66
    -67
    -
    -
    # File 'lib/sidekiq_unique_jobs/locksmith.rb', line 58
    -
    -def lock(timeout = nil, &block)
    -  Scripts.call(:lock, redis_pool,
    -               keys: [exists_key, grabbed_key, available_key, UNIQUE_SET, unique_digest],
    -               argv: [jid, expiration])
    -
    -  grab_token(timeout) do |token|
    -    touch_grabbed_token(token)
    -    return_token_or_block_value(token, &block)
    -  end
    -end
    -
    -
    - -
    -

    - - #locked?(token = nil) ⇒ true, false - - - - - -

    -
    -

    Checks if this instance is considered locked

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - token - - - (String) - - - (defaults to: nil) - - - — -

      the unique token to check for a lock. -nil will default to the jid provided in the initializer

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (true, false) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -98
    -99
    -100
    -101
    -
    -
    # File 'lib/sidekiq_unique_jobs/locksmith.rb', line 98
    -
    -def locked?(token = nil)
    -  token ||= jid
    -  redis(redis_pool) { |conn| conn.hexists(grabbed_key, token) }
    -end
    -
    -
    - -
    -

    - - #unlock(token = nil) ⇒ false, String - - - - - -

    -
    -

    Removes the lock keys from Redis if locked by the provided jid/token

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (false) - - - - — -

      unless locked?

      -
      - -
    • - -
    • - - - (String) - - - - — -

      Sidekiq job_id (jid) if successful

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -73
    -74
    -75
    -76
    -77
    -78
    -
    -
    # File 'lib/sidekiq_unique_jobs/locksmith.rb', line 73
    -
    -def unlock(token = nil)
    -  token ||= jid
    -  return false unless locked?(token)
    -
    -  unlock!(token)
    -end
    -
    -
    - -
    -

    - - #unlock!(token = nil) ⇒ false, String - - - - - -

    -
    -

    Removes the lock keys from Redis

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (false) - - - - — -

      unless locked?

      -
      - -
    • - -
    • - - - (String) - - - - — -

      Sidekiq job_id (jid) if successful

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -83
    -84
    -85
    -86
    -87
    -88
    -89
    -90
    -91
    -92
    -
    -
    # File 'lib/sidekiq_unique_jobs/locksmith.rb', line 83
    -
    -def unlock!(token = nil)
    -  token ||= jid
    -
    -  Scripts.call(
    -    :unlock,
    -    redis_pool,
    -    keys: [exists_key, grabbed_key, available_key, version_key, UNIQUE_SET, unique_digest],
    -    argv: [token, expiration],
    -  )
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Logging.html b/docs/SidekiqUniqueJobs/Logging.html deleted file mode 100644 index 387d4e2f1..000000000 --- a/docs/SidekiqUniqueJobs/Logging.html +++ /dev/null @@ -1,779 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Logging - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Logging - - - -

    -
    - - - - - - - - - -
    -
    Included in:
    -
    Client::Middleware, Digests, SidekiqUniqueJobs::Lock::BaseLock, OnConflict::Log, OnConflict::Strategy, Server::Middleware, UniqueArgs, Util
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/logging.rb
    -
    - -
    - -

    Overview

    -
    -

    Utility module for reducing the number of uses of logger.

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #log_debug(message_or_exception = nil) { ... } ⇒ Object - - - - - -

    -
    -

    Logs a message at debug level

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - message_or_exception - - - (String, Exception) - - - (defaults to: nil) - - - — -

      the message or exception to log

      -
      - -
    • - -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      the message or exception to use for log message -Used for compatibility with logger

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -17
    -18
    -19
    -
    -
    # File 'lib/sidekiq_unique_jobs/logging.rb', line 17
    -
    -def log_debug(message_or_exception = nil, &block)
    -  logger.debug(message_or_exception, &block)
    -end
    -
    -
    - -
    -

    - - #log_error(message_or_exception = nil) { ... } ⇒ Object - - - - - -

    -
    -

    Logs a message at error level

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - message_or_exception - - - (String, Exception) - - - (defaults to: nil) - - - — -

      the message or exception to log

      -
      - -
    • - -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      the message or exception to use for log message -Used for compatibility with logger

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -41
    -42
    -43
    -
    -
    # File 'lib/sidekiq_unique_jobs/logging.rb', line 41
    -
    -def log_error(message_or_exception = nil, &block)
    -  logger.error(message_or_exception, &block)
    -end
    -
    -
    - -
    -

    - - #log_fatal(message_or_exception = nil) { ... } ⇒ Object - - - - - -

    -
    -

    Logs a message at fatal level

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - message_or_exception - - - (String, Exception) - - - (defaults to: nil) - - - — -

      the message or exception to log

      -
      - -
    • - -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      the message or exception to use for log message -Used for compatibility with logger

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -49
    -50
    -51
    -
    -
    # File 'lib/sidekiq_unique_jobs/logging.rb', line 49
    -
    -def log_fatal(message_or_exception = nil, &block)
    -  logger.fatal(message_or_exception, &block)
    -end
    -
    -
    - -
    -

    - - #log_info(message_or_exception = nil) { ... } ⇒ Object - - - - - -

    -
    -

    Logs a message at info level

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - message_or_exception - - - (String, Exception) - - - (defaults to: nil) - - - — -

      the message or exception to log

      -
      - -
    • - -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      the message or exception to use for log message -Used for compatibility with logger

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -25
    -26
    -27
    -
    -
    # File 'lib/sidekiq_unique_jobs/logging.rb', line 25
    -
    -def log_info(message_or_exception = nil, &block)
    -  logger.info(message_or_exception, &block)
    -end
    -
    -
    - -
    -

    - - #log_warn(message_or_exception = nil) { ... } ⇒ Object - - - - - -

    -
    -

    Logs a message at warn level

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - message_or_exception - - - (String, Exception) - - - (defaults to: nil) - - - — -

      the message or exception to log

      -
      - -
    • - -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      the message or exception to use for log message -Used for compatibility with logger

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -33
    -34
    -35
    -
    -
    # File 'lib/sidekiq_unique_jobs/logging.rb', line 33
    -
    -def log_warn(message_or_exception = nil, &block)
    -  logger.warn(message_or_exception, &block)
    -end
    -
    -
    - -
    -

    - - #loggerObject - - - - - -

    -
    -

    A convenience method for using the configured logger

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -9
    -10
    -11
    -
    -
    # File 'lib/sidekiq_unique_jobs/logging.rb', line 9
    -
    -def logger
    -  SidekiqUniqueJobs.logger
    -end
    -
    -
    - -
    -

    - - #logging_context(middleware_class, job_hash) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -53
    -54
    -55
    -56
    -
    -
    # File 'lib/sidekiq_unique_jobs/logging.rb', line 53
    -
    -def logging_context(middleware_class, job_hash)
    -  digest = job_hash["unique_digest"]
    -  "#{middleware_class} #{"DIG-#{digest}" if digest}"
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Middleware.html b/docs/SidekiqUniqueJobs/Middleware.html deleted file mode 100644 index f13fc9b50..000000000 --- a/docs/SidekiqUniqueJobs/Middleware.html +++ /dev/null @@ -1,335 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Middleware - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Middleware - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/middleware.rb
    -
    - -
    - -

    Overview

    -
    -

    Provides the sidekiq middleware that makes the gem work

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #configure_client_middlewareObject - - - - - -

    - - - - -
    -
    -
    -
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -
    -
    # File 'lib/sidekiq_unique_jobs/middleware.rb', line 37
    -
    -def configure_client_middleware
    -  Sidekiq.configure_client do |config|
    -    config.client_middleware do |chain|
    -      require "sidekiq_unique_jobs/client/middleware"
    -      chain.add SidekiqUniqueJobs::Client::Middleware
    -    end
    -  end
    -end
    -
    -
    - -
    -

    - - #configure_middlewareObject - - - - - -

    - - - - -
    -
    -
    -
    -18
    -19
    -20
    -21
    -
    -
    # File 'lib/sidekiq_unique_jobs/middleware.rb', line 18
    -
    -def configure_middleware
    -  configure_server_middleware
    -  configure_client_middleware
    -end
    -
    -
    - -
    -

    - - #configure_server_middlewareObject - - - - - -

    - - - - -
    -
    -
    -
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -
    -
    # File 'lib/sidekiq_unique_jobs/middleware.rb', line 23
    -
    -def configure_server_middleware
    -  Sidekiq.configure_server do |config|
    -    config.client_middleware do |chain|
    -      require "sidekiq_unique_jobs/client/middleware"
    -      chain.add SidekiqUniqueJobs::Client::Middleware
    -    end
    -
    -    config.server_middleware do |chain|
    -      require "sidekiq_unique_jobs/server/middleware"
    -      chain.add SidekiqUniqueJobs::Server::Middleware
    -    end
    -  end
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Normalizer.html b/docs/SidekiqUniqueJobs/Normalizer.html deleted file mode 100644 index 621959ec6..000000000 --- a/docs/SidekiqUniqueJobs/Normalizer.html +++ /dev/null @@ -1,242 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Normalizer - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Normalizer - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/normalizer.rb
    -
    - -
    - -

    Overview

    -
    -

    Normalizes hashes by dumping them to json and loading them from json

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Class Method Summary - collapse -

    - - - - - - -
    -

    Class Method Details

    - - -
    -

    - - .jsonify(args) ⇒ Hash - - - - - -

    -
    -

    Changes hash to a json compatible hash

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - args - - - (Hash) - - - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (Hash) - - - - — -

      a json compatible hash

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -13
    -14
    -15
    -
    -
    # File 'lib/sidekiq_unique_jobs/normalizer.rb', line 13
    -
    -def self.jsonify(args)
    -  Sidekiq.load_json(Sidekiq.dump_json(args))
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict.html b/docs/SidekiqUniqueJobs/OnConflict.html deleted file mode 100644 index e0cdcd608..000000000 --- a/docs/SidekiqUniqueJobs/OnConflict.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::OnConflict - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::OnConflict - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/on_conflict.rb,
    - lib/sidekiq_unique_jobs/on_conflict/log.rb,
    lib/sidekiq_unique_jobs/on_conflict/raise.rb,
    lib/sidekiq_unique_jobs/on_conflict/reject.rb,
    lib/sidekiq_unique_jobs/on_conflict/replace.rb,
    lib/sidekiq_unique_jobs/on_conflict/strategy.rb,
    lib/sidekiq_unique_jobs/on_conflict/reschedule.rb,
    lib/sidekiq_unique_jobs/on_conflict/null_strategy.rb
    -
    -
    - -
    - -

    Overview

    -
    -

    Provides lock conflict resolutions

    - - -
    -
    -
    - -

    Author:

    - - -

    Defined Under Namespace

    -

    - - - - - Classes: Log, NullStrategy, Raise, Reject, Replace, Reschedule, Strategy - - -

    - - -

    - Constant Summary - collapse -

    - -
    - -
    STRATEGIES = - -
    -
    {
    -  log: OnConflict::Log,
    -  raise: OnConflict::Raise,
    -  reject: OnConflict::Reject,
    -  replace: OnConflict::Replace,
    -  reschedule: OnConflict::Reschedule,
    -}.freeze
    - -
    - - - - - - - - - -

    - Class Method Summary - collapse -

    - - - - - - -
    -

    Class Method Details

    - - -
    -

    - - .find_strategy(strategy) ⇒ Object - - - - - -

    -
    -

    returns OnConflict::NullStrategy when no other could be found

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -27
    -28
    -29
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict.rb', line 27
    -
    -def self.find_strategy(strategy)
    -  STRATEGIES.fetch(strategy.to_s.to_sym) { OnConflict::NullStrategy }
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Log.html b/docs/SidekiqUniqueJobs/OnConflict/Log.html deleted file mode 100644 index 184cb8e26..000000000 --- a/docs/SidekiqUniqueJobs/OnConflict/Log.html +++ /dev/null @@ -1,272 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::OnConflict::Log - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::OnConflict::Log - - - -

    -
    - -
    -
    Inherits:
    -
    - Strategy - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    Logging
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/on_conflict/log.rb
    -
    - -
    - -

    Overview

    -
    -

    Strategy to log information about conflict

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - -

    Instance Attribute Summary

    - -

    Attributes inherited from Strategy

    -

    #item

    - - - -

    - Instance Method Summary - collapse -

    - -
      - -
    • - - - #call ⇒ Object - - - - - - - - - - - - - -

      Logs an informational message about that the job was not unique.

      -
      - -
    • - - -
    - - - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    - - - - - - - - - -

    Methods inherited from Strategy

    -

    #initialize, #replace?

    -
    -

    Constructor Details

    - -

    This class inherits a constructor from SidekiqUniqueJobs::OnConflict::Strategy

    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #callObject - - - - - -

    -
    -

    Logs an informational message about that the job was not unique

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -12
    -13
    -14
    -15
    -16
    -17
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/log.rb', line 12
    -
    -def call
    -  log_info(
    -    "skipping job with id (#{item[JID_KEY]}) " \
    -    "because unique_digest: (#{item[UNIQUE_DIGEST_KEY]}) already exists",
    -  )
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/NullStrategy.html b/docs/SidekiqUniqueJobs/OnConflict/NullStrategy.html deleted file mode 100644 index 18e9ad498..000000000 --- a/docs/SidekiqUniqueJobs/OnConflict/NullStrategy.html +++ /dev/null @@ -1,274 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::OnConflict::NullStrategy - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::OnConflict::NullStrategy - - - -

    -
    - -
    -
    Inherits:
    -
    - Strategy - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/on_conflict/null_strategy.rb
    -
    - -
    - -

    Overview

    -
    -

    Default conflict strategy class that does nothing

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - -

    Instance Attribute Summary

    - -

    Attributes inherited from Strategy

    -

    #item

    - - - -

    - Instance Method Summary - collapse -

    - -
      - -
    • - - - #call ⇒ nil - - - - - - - - - - - - - -

      Do nothing on conflict.

      -
      - -
    • - - -
    - - - - - - - - - - - -

    Methods inherited from Strategy

    -

    #initialize, #replace?

    - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -

    This class inherits a constructor from SidekiqUniqueJobs::OnConflict::Strategy

    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #callnil - - - - - -

    -
    -

    Do nothing on conflict

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (nil) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -11
    -12
    -13
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/null_strategy.rb', line 11
    -
    -def call
    -  # NOOP
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Raise.html b/docs/SidekiqUniqueJobs/OnConflict/Raise.html deleted file mode 100644 index b2ed7fac7..000000000 --- a/docs/SidekiqUniqueJobs/OnConflict/Raise.html +++ /dev/null @@ -1,275 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::OnConflict::Raise - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::OnConflict::Raise - - - -

    -
    - -
    -
    Inherits:
    -
    - Strategy - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/on_conflict/raise.rb
    -
    - -
    - -

    Overview

    -
    -

    Strategy to raise an error on conflict

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - -

    Instance Attribute Summary

    - -

    Attributes inherited from Strategy

    -

    #item

    - - - -

    - Instance Method Summary - collapse -

    - -
      - -
    • - - - #call ⇒ Object - - - - - - - - - - - - - -

      Raise an error on conflict.

      -
      - -
    • - - -
    - - - - - - - - - - - -

    Methods inherited from Strategy

    -

    #initialize, #replace?

    - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -

    This class inherits a constructor from SidekiqUniqueJobs::OnConflict::Strategy

    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #callObject - - - - - -

    -
    -

    Raise an error on conflict. - This will cause Sidekiq to retry the job

    - - -
    -
    -
    - -

    Raises:

    - - -
    - - - - -
    -
    -
    -
    -12
    -13
    -14
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/raise.rb', line 12
    -
    -def call
    -  raise SidekiqUniqueJobs::Conflict, item
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Reject.html b/docs/SidekiqUniqueJobs/OnConflict/Reject.html deleted file mode 100644 index 7bacc5318..000000000 --- a/docs/SidekiqUniqueJobs/OnConflict/Reject.html +++ /dev/null @@ -1,859 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::OnConflict::Reject - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::OnConflict::Reject - - - -

    -
    - -
    -
    Inherits:
    -
    - Strategy - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/on_conflict/reject.rb
    -
    - -
    - -

    Overview

    -
    -

    Strategy to send jobs to dead queue

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - -

    Instance Attribute Summary

    - -

    Attributes inherited from Strategy

    -

    #item

    - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods inherited from Strategy

    -

    #initialize, #replace?

    - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -

    This class inherits a constructor from SidekiqUniqueJobs::OnConflict::Strategy

    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #callObject - - - - - -

    -
    -

    Send jobs to dead queue

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -10
    -11
    -12
    -13
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 10
    -
    -def call
    -  log_debug { "Rejecting job with jid: #{item[JID_KEY]}" }
    -  send_to_deadset
    -end
    -
    -
    - -
    -

    - - #current_timeObject - - - - - -

    - - - - -
    -
    -
    -
    -63
    -64
    -65
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 63
    -
    -def current_time
    -  @current_time ||= Time.now.to_f
    -end
    -
    -
    - -
    -

    - - #deadsetObject - - - - - -

    - - - - -
    -
    -
    -
    -49
    -50
    -51
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 49
    -
    -def deadset
    -  @deadset ||= Sidekiq::DeadSet.new
    -end
    -
    -
    - -
    -

    - - #deadset_killObject - - - - - -

    - - - - -
    -
    -
    -
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 29
    -
    -def deadset_kill
    -  if kill_with_options?
    -    kill_job_with_options
    -  else
    -    kill_job_without_options
    -  end
    -end
    -
    -
    - -
    -

    - - #deadset_kill?Boolean - - - - - -

    -
    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Boolean) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -25
    -26
    -27
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 25
    -
    -def deadset_kill?
    -  deadset.respond_to?(:kill)
    -end
    -
    -
    - -
    -

    - - #kill_job_with_optionsObject - - - - - -

    - - - - -
    -
    -
    -
    -45
    -46
    -47
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 45
    -
    -def kill_job_with_options
    -  deadset.kill(payload, notify_failure: false)
    -end
    -
    -
    - -
    -

    - - #kill_job_without_optionsObject - - - - - -

    - - - - -
    -
    -
    -
    -41
    -42
    -43
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 41
    -
    -def kill_job_without_options
    -  deadset.kill(payload)
    -end
    -
    -
    - -
    -

    - - #kill_with_options?Boolean - - - - - -

    -
    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Boolean) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -37
    -38
    -39
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 37
    -
    -def kill_with_options?
    -  Sidekiq::DeadSet.instance_method(:kill).arity > 1
    -end
    -
    -
    - -
    -

    - - #payloadObject - - - - - -

    - - - - -
    -
    -
    -
    -67
    -68
    -69
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 67
    -
    -def payload
    -  @payload ||= Sidekiq.dump_json(item)
    -end
    -
    -
    - -
    -

    - - #push_to_deadsetObject - - - - - -

    - - - - -
    -
    -
    -
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 53
    -
    -def push_to_deadset
    -  Sidekiq.redis do |conn|
    -    conn.multi do
    -      conn.zadd("dead", current_time, payload)
    -      conn.zremrangebyscore("dead", "-inf", current_time - Sidekiq::DeadSet.timeout)
    -      conn.zremrangebyrank("dead", 0, -Sidekiq::DeadSet.max_jobs)
    -    end
    -  end
    -end
    -
    -
    - -
    -

    - - #send_to_deadsetObject - - - - - -

    - - - - -
    -
    -
    -
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reject.rb', line 15
    -
    -def send_to_deadset
    -  log_info { "Adding dead #{item[CLASS_KEY]} job #{item[JID_KEY]}" }
    -
    -  if deadset_kill?
    -    deadset_kill
    -  else
    -    push_to_deadset
    -  end
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Replace.html b/docs/SidekiqUniqueJobs/OnConflict/Replace.html deleted file mode 100644 index 6b472e2f6..000000000 --- a/docs/SidekiqUniqueJobs/OnConflict/Replace.html +++ /dev/null @@ -1,654 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::OnConflict::Replace - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::OnConflict::Replace - - - -

    -
    - -
    -
    Inherits:
    -
    - Strategy - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/on_conflict/replace.rb
    -
    - -
    - -

    Overview

    -
    -

    Strategy to replace the job on conflict

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - -

    Instance Attribute Summary collapse

    -
      - -
    • - - - #queue ⇒ Object - - - - - - - - - readonly - - - - - - - - - -

      Returns the value of attribute queue.

      -
      - -
    • - - -
    • - - - #unique_digest ⇒ Object - - - - - - - - - readonly - - - - - - - - - -

      Returns the value of attribute unique_digest.

      -
      - -
    • - - -
    - - - - - -

    Attributes inherited from Strategy

    -

    #item

    - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods inherited from Strategy

    -

    #replace?

    - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -
    -

    - - #initialize(item) ⇒ Replace - - - - - -

    -
    -

    Returns a new instance of Replace

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      sidekiq job hash

      -
      - -
    • - -
    - - -
    - - - - -
    -
    -
    -
    -12
    -13
    -14
    -15
    -16
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 12
    -
    -def initialize(item)
    -  super
    -  @queue         = item[QUEUE_KEY]
    -  @unique_digest = item[UNIQUE_DIGEST_KEY]
    -end
    -
    -
    - -
    - -
    -

    Instance Attribute Details

    - - - -
    -

    - - #queueObject (readonly) - - - - - -

    -
    -

    Returns the value of attribute queue

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -9
    -10
    -11
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 9
    -
    -def queue
    -  @queue
    -end
    -
    -
    - - - -
    -

    - - #unique_digestObject (readonly) - - - - - -

    -
    -

    Returns the value of attribute unique_digest

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -9
    -10
    -11
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 9
    -
    -def unique_digest
    -  @unique_digest
    -end
    -
    -
    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #call { ... } ⇒ Object - - - - - -

    -
    -

    Replace the old job in the queue

    - - -
    -
    -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      to retry the lock after deleting the old one

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -20
    -21
    -22
    -23
    -24
    -25
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 20
    -
    -def call(&block)
    -  return unless delete_job_by_digest
    -
    -  delete_lock
    -  block&.call
    -end
    -
    -
    - -
    -

    - - #delete_job_by_digestObject - - - - - -

    -
    -

    Delete the job from either schedule, retry or the queue

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 28
    -
    -def delete_job_by_digest
    -  Scripts.call(
    -    :delete_job_by_digest,
    -    nil,
    -    keys: ["#{QUEUE_KEY}:#{queue}", SCHEDULE_SET, RETRY_SET], argv: [unique_digest],
    -  )
    -end
    -
    -
    - -
    -

    - - #delete_lockObject - - - - - -

    -
    -

    Delete the keys belonging to the job

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -37
    -38
    -39
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/replace.rb', line 37
    -
    -def delete_lock
    -  Scripts.call(:delete_by_digest, nil, keys: [UNIQUE_SET, unique_digest])
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Reschedule.html b/docs/SidekiqUniqueJobs/OnConflict/Reschedule.html deleted file mode 100644 index 6d4b9746e..000000000 --- a/docs/SidekiqUniqueJobs/OnConflict/Reschedule.html +++ /dev/null @@ -1,362 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::OnConflict::Reschedule - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::OnConflict::Reschedule - - - -

    -
    - -
    -
    Inherits:
    -
    - Strategy - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    SidekiqWorkerMethods
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/on_conflict/reschedule.rb
    -
    - -
    - -

    Overview

    -
    -

    Strategy to reschedule job on conflict

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - -

    Instance Attribute Summary

    - -

    Attributes inherited from Strategy

    -

    #item

    - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from SidekiqWorkerMethods

    -

    #after_unlock_hook, #default_worker_options, #sidekiq_worker_class?, #worker_class, #worker_class_constantize, #worker_method_defined?, #worker_options

    - - - - - - - - - -

    Methods inherited from Strategy

    -

    #replace?

    - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -
    -

    - - #initialize(item) ⇒ Reschedule - - - - - -

    -
    -

    Returns a new instance of Reschedule

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      sidekiq job hash

      -
      - -
    • - -
    - - -
    - - - - -
    -
    -
    -
    -12
    -13
    -14
    -15
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reschedule.rb', line 12
    -
    -def initialize(item)
    -  super
    -  @worker_class = item[CLASS_KEY]
    -end
    -
    -
    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #callObject - - - - - -

    -
    -

    Create a new job from the current one. - This will mess up sidekiq stats because a new job is created

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -19
    -20
    -21
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/reschedule.rb', line 19
    -
    -def call
    -  worker_class&.perform_in(5, *item[ARGS_KEY]) if sidekiq_worker_class?
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OnConflict/Strategy.html b/docs/SidekiqUniqueJobs/OnConflict/Strategy.html deleted file mode 100644 index 0f415ff6f..000000000 --- a/docs/SidekiqUniqueJobs/OnConflict/Strategy.html +++ /dev/null @@ -1,526 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::OnConflict::Strategy - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::OnConflict::Strategy - Abstract - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    Logging
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/on_conflict/strategy.rb
    -
    - -
    - -

    Overview

    -
    -
    - This class is abstract. -
    -
    -

    Abstract conflict strategy class

    - - -
    -
    -
    - -

    Author:

    - - -
    -

    Direct Known Subclasses

    -

    Log, NullStrategy, Raise, Reject, Replace, Reschedule

    -
    - - - - -

    Instance Attribute Summary collapse

    -
      - -
    • - - - #item ⇒ Hash - - - - - - - - - readonly - - - - - - - - - -

      The sidekiq job hash.

      -
      - -
    • - - -
    - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -
    -

    - - #initialize(item) ⇒ Strategy - - - - - -

    -
    -

    Returns a new instance of Strategy

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      the Sidekiq job hash

      -
      - -
    • - -
    - - -
    - - - - -
    -
    -
    -
    -17
    -18
    -19
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/strategy.rb', line 17
    -
    -def initialize(item)
    -  @item = item
    -end
    -
    -
    - -
    - -
    -

    Instance Attribute Details

    - - - -
    -

    - - #itemHash (readonly) - - - - - -

    -
    -

    The sidekiq job hash

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Hash) - - - - — -

      the Sidekiq job hash

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -14
    -15
    -16
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/strategy.rb', line 14
    -
    -def item
    -  @item
    -end
    -
    -
    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #callObject - - - - - -

    -
    -

    Use strategy on conflict

    - - -
    -
    -
    - -

    Raises:

    -
      - -
    • - - - (NotImplementedError) - - - - — -

      needs to be implemented in child class

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -23
    -24
    -25
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/strategy.rb', line 23
    -
    -def call
    -  raise NotImplementedError, "needs to be implemented in child class"
    -end
    -
    -
    - -
    -

    - - #replace?Boolean - - - - - -

    -
    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Boolean) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -27
    -28
    -29
    -
    -
    # File 'lib/sidekiq_unique_jobs/on_conflict/strategy.rb', line 27
    -
    -def replace?
    -  is_a?(Replace)
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/OptionsWithFallback.html b/docs/SidekiqUniqueJobs/OptionsWithFallback.html deleted file mode 100644 index 0d530df56..000000000 --- a/docs/SidekiqUniqueJobs/OptionsWithFallback.html +++ /dev/null @@ -1,770 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::OptionsWithFallback - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::OptionsWithFallback - - - -

    -
    - - - - - - - - - -
    -
    Included in:
    -
    Client::Middleware, Server::Middleware
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/options_with_fallback.rb
    -
    - -
    - -

    Overview

    -
    -

    Module containing methods shared between client and server middleware

    - -

    Requires the following methods to be defined in the including class

    - -
      -
    1. item (required)
    2. -
    3. options (can be nil)
    4. -
    5. worker_class (required, can be anything)
    6. -
    - - -
    -
    -
    - -

    Author:

    - - -
    - -

    - Constant Summary - collapse -

    - -
    - -
    LOCKS = - -
    -
    {
    -  until_and_while_executing: SidekiqUniqueJobs::Lock::UntilAndWhileExecuting,
    -  until_executed: SidekiqUniqueJobs::Lock::UntilExecuted,
    -  until_executing: SidekiqUniqueJobs::Lock::UntilExecuting,
    -  until_expired: SidekiqUniqueJobs::Lock::UntilExpired,
    -  until_timeout: SidekiqUniqueJobs::Lock::UntilExpired,
    -  while_executing: SidekiqUniqueJobs::Lock::WhileExecuting,
    -  while_executing_reject: SidekiqUniqueJobs::Lock::WhileExecutingReject,
    -}.freeze
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #lockSidekiqUniqueJobs::Lock::BaseLock - - - - - -

    -
    -

    Check if we should log duplicate payloads

    - - -
    -
    -
    - -

    Returns:

    - - -
    - - - - -
    -
    -
    -
    -44
    -45
    -46
    -
    -
    # File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 44
    -
    -def lock
    -  @lock ||= lock_class.new(item, after_unlock_hook, @redis_pool)
    -end
    -
    -
    - -
    -

    - - #lock_classSidekiqUniqueJobs::Lock::BaseLock - - - - - -

    -
    -

    Check if we should log duplicate payloads

    - - -
    -
    -
    - -

    Returns:

    - - -
    - - - - -
    -
    -
    -
    -50
    -51
    -52
    -53
    -54
    -55
    -56
    -
    -
    # File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 50
    -
    -def lock_class
    -  @lock_class ||= begin
    -    LOCKS.fetch(lock_type.to_sym) do
    -      raise UnknownLock, "No implementation for `lock: :#{lock_type}`"
    -    end
    -  end
    -end
    -
    -
    - -
    -

    - - #lock_typeSymbol - - - - - -

    -
    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Symbol) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -59
    -60
    -61
    -
    -
    # File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 59
    -
    -def lock_type
    -  @lock_type ||= options[LOCK_KEY] || item[LOCK_KEY] || unique_type
    -end
    -
    -
    - -
    -

    - - #log_duplicate_payload?Boolean - - - - - -

    -
    -

    Check if we should log duplicate payloads

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Boolean) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -38
    -39
    -40
    -
    -
    # File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 38
    -
    -def log_duplicate_payload?
    -  options[LOG_DUPLICATE_KEY] || item[LOG_DUPLICATE_KEY]
    -end
    -
    -
    - -
    -

    - - #optionsObject - - - - - -

    - - - - -
    -
    -
    -
    -67
    -68
    -69
    -70
    -71
    -72
    -73
    -
    -
    # File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 67
    -
    -def options
    -  @options ||= begin
    -    opts = default_worker_options.dup
    -    opts.merge!(worker_options) if sidekiq_worker_class?
    -    (opts || {}).stringify_keys
    -  end
    -end
    -
    -
    - -
    -

    - - #unique_disabled?Boolean - - - - - -

    -
    -

    Check if unique has been disabled

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Boolean) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -33
    -34
    -35
    -
    -
    # File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 33
    -
    -def unique_disabled?
    -  !unique_enabled?
    -end
    -
    -
    - -
    -

    - - #unique_enabled?true, false - - - - - -

    -
    -

    Check if unique has been enabled

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (true, false) - - - - — -

      indicate if the gem has been enabled

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -28
    -29
    -30
    -
    -
    # File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 28
    -
    -def unique_enabled?
    -  SidekiqUniqueJobs.config.enabled && lock_type
    -end
    -
    -
    - -
    -

    - - #unique_typeObject - - - - - -

    - - - - -
    -
    -
    -
    -63
    -64
    -65
    -
    -
    # File 'lib/sidekiq_unique_jobs/options_with_fallback.rb', line 63
    -
    -def unique_type
    -  options[UNIQUE_KEY] || item[UNIQUE_KEY]
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/ScriptError.html b/docs/SidekiqUniqueJobs/ScriptError.html deleted file mode 100644 index 5b70fc592..000000000 --- a/docs/SidekiqUniqueJobs/ScriptError.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - - - Exception: SidekiqUniqueJobs::ScriptError - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Exception: SidekiqUniqueJobs::ScriptError - - - -

    -
    - -
    -
    Inherits:
    -
    - StandardError - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/exceptions.rb
    -
    - -
    - -

    Overview

    -
    -

    Error raised from OnConflict::Raise

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - -
    -

    Constructor Details

    - -
    -

    - - #initialize(file_name:, source_exception:) ⇒ ScriptError - - - - - -

    -
    -

    Returns a new instance of ScriptError

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - file_name - - - (Symbol) - - - - — -

      the name of the lua script

      -
      - -
    • - -
    • - - source_exception - - - (Redis::CommandError) - - - - — -

      exception to handle

      -
      - -
    • - -
    - - -
    - - - - -
    -
    -
    -
    -19
    -20
    -21
    -
    -
    # File 'lib/sidekiq_unique_jobs/exceptions.rb', line 19
    -
    -def initialize(file_name:, source_exception:)
    -  super("Problem compiling #{file_name}. Message: #{source_exception.message}")
    -end
    -
    -
    - -
    - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Scripts.html b/docs/SidekiqUniqueJobs/Scripts.html deleted file mode 100644 index 26ff09cad..000000000 --- a/docs/SidekiqUniqueJobs/Scripts.html +++ /dev/null @@ -1,935 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Scripts - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Scripts - - - -

    -
    - - - - - - -
    -
    Includes:
    -
    Connection
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/scripts.rb
    -
    - -
    - -

    Overview

    -
    -

    Interface to dealing with .lua files

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Class Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from Connection

    -

    #redis

    - - -
    -

    Class Method Details

    - - -
    -

    - - .call(file_name, redis_pool, options = {}) ⇒ Object - - - - - -

    -
    - -
    - Note: -

    this method is recursive if we need to load a lua script -that wasn't previously loaded.

    -
    -
    - -

    Call a lua script with the provided file_name

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - file_name - - - (Symbol) - - - - — -

      the name of the lua script

      -
      - -
    • - -
    • - - redis_pool - - - (Sidekiq::RedisConnection, ConnectionPool) - - - - — -

      the redis connection

      -
      - -
    • - -
    • - - options - - - (Hash) - - - (defaults to: {}) - - - — -

      arguments to pass to the script file

      -
      - -
    • - -
    - - - - - - - - -

    Options Hash (options):

    -
      - -
    • - :keys - (Array) - - - - - —

      the array of keys to pass to the script

      -
      - -
    • - -
    • - :argv - (Array) - - - - - —

      the array of arguments to pass to the script

      -
      - -
    • - -
    - - - -
    - - - - -
    -
    -
    -
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -
    -
    # File 'lib/sidekiq_unique_jobs/scripts.rb', line 27
    -
    -def call(file_name, redis_pool, options = {})
    -  execute_script(file_name, redis_pool, options)
    -rescue Redis::CommandError => ex
    -  handle_error(ex, file_name) do
    -    call(file_name, redis_pool, options)
    -  end
    -end
    -
    -
    - -
    -

    - - .execute_script(file_name, redis_pool, options = {}) ⇒ Object - - - - - -

    -
    -

    Execute the script file

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - file_name - - - (Symbol) - - - - — -

      the name of the lua script

      -
      - -
    • - -
    • - - redis_pool - - - (Sidekiq::RedisConnection, ConnectionPool) - - - - — -

      the redis connection

      -
      - -
    • - -
    • - - options - - - (Hash) - - - (defaults to: {}) - - - — -

      arguments to pass to the script file

      -
      - -
    • - -
    - - - - - - - - -

    Options Hash (options):

    -
      - -
    • - :keys - (Array) - - - - - —

      the array of keys to pass to the script

      -
      - -
    • - -
    • - :argv - (Array) - - - - - —

      the array of arguments to pass to the script

      -
      - -
    • - -
    - - - -
    - - - - -
    -
    -
    -
    -41
    -42
    -43
    -44
    -45
    -46
    -
    -
    # File 'lib/sidekiq_unique_jobs/scripts.rb', line 41
    -
    -def execute_script(file_name, redis_pool, options = {})
    -  redis(redis_pool) do |conn|
    -    sha = script_sha(conn, file_name)
    -    conn.evalsha(sha, options)
    -  end
    -end
    -
    -
    - -
    -

    - - .handle_error(ex, file_name) ⇒ Object - - - - - -

    -
    -

    Return sha of already loaded lua script or load it and return the sha

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - ex - - - (Redis::CommandError) - - - - — -

      exception to handle

      -
      - -
    • - -
    • - - file_name - - - (Symbol) - - - - — -

      the name of the lua script

      -
      - -
    • - -
    - -

    Raises:

    -
      - -
    • - - - (ScriptError) - - - - — -

      when the error isn't handled

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -66
    -67
    -68
    -69
    -70
    -71
    -72
    -73
    -
    -
    # File 'lib/sidekiq_unique_jobs/scripts.rb', line 66
    -
    -def handle_error(ex, file_name)
    -  if ex.message == "NOSCRIPT No matching script. Please use EVAL."
    -    SCRIPT_SHAS.delete(file_name)
    -    return yield if block_given?
    -  end
    -
    -  raise ScriptError, file_name: file_name, source_exception: ex
    -end
    -
    -
    - -
    -

    - - .script_path(file_name) ⇒ Pathname - - - - - -

    -
    -

    Construct a Pathname to a lua script

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - file_name - - - (Symbol) - - - - — -

      the name of the lua script

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (Pathname) - - - - — -

      the full path to the gems lua script

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -85
    -86
    -87
    -
    -
    # File 'lib/sidekiq_unique_jobs/scripts.rb', line 85
    -
    -def script_path(file_name)
    -  LUA_PATHNAME.join("#{file_name}.lua")
    -end
    -
    -
    - -
    -

    - - .script_sha(conn, file_name) ⇒ String - - - - - -

    -
    -

    Return sha of already loaded lua script or load it and return the sha

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - conn - - - (Sidekiq::RedisConnection) - - - - — -

      the redis connection

      -
      - -
    • - -
    • - - file_name - - - (Symbol) - - - - — -

      the name of the lua script

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (String) - - - - — -

      sha of the script file

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -52
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -
    -
    # File 'lib/sidekiq_unique_jobs/scripts.rb', line 52
    -
    -def script_sha(conn, file_name)
    -  if (sha = SCRIPT_SHAS.get(file_name))
    -    return sha
    -  end
    -
    -  sha = conn.script(:load, script_source(file_name))
    -  SCRIPT_SHAS.put(file_name, sha)
    -  sha
    -end
    -
    -
    - -
    -

    - - .script_source(file_name) ⇒ String - - - - - -

    -
    -

    Reads the lua file from disk

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - file_name - - - (Symbol) - - - - — -

      the name of the lua script

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (String) - - - - — -

      the content of the lua file

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -78
    -79
    -80
    -
    -
    # File 'lib/sidekiq_unique_jobs/scripts.rb', line 78
    -
    -def script_source(file_name)
    -  script_path(file_name).read
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Server.html b/docs/SidekiqUniqueJobs/Server.html deleted file mode 100644 index 5013c3e4d..000000000 --- a/docs/SidekiqUniqueJobs/Server.html +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Server - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Server - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/server/middleware.rb
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - - - Classes: Middleware - - -

    - - - - - - - - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Server/Middleware.html b/docs/SidekiqUniqueJobs/Server/Middleware.html deleted file mode 100644 index 2ab4144b7..000000000 --- a/docs/SidekiqUniqueJobs/Server/Middleware.html +++ /dev/null @@ -1,355 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Server::Middleware - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Server::Middleware - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    Logging, OptionsWithFallback
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/server/middleware.rb
    -
    - -
    - -

    Overview

    -
    -

    The unique sidekiq middleware for the server processor

    - - -
    -
    -
    - -

    Author:

    - - -
    - - -

    Constant Summary

    - -

    Constants included - from OptionsWithFallback

    -

    OptionsWithFallback::LOCKS

    - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from OptionsWithFallback

    -

    #lock, #lock_class, #lock_type, #log_duplicate_payload?, #options, #unique_disabled?, #unique_enabled?, #unique_type

    - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    - - -
    -

    Instance Method Details

    - - -
    -

    - - #call(worker_class, item, queue) { ... } ⇒ Object - - - - - -

    -
    -

    Runs the server middleware - Used from Sidekiq::Processor#process

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - worker_class - - - (Sidekiq::Worker) - - - -
    • - -
    • - - item - - - (Hash) - - - - — -

      a sidekiq job hash

      -
      - -
    • - -
    • - - queue - - - (String) - - - - — -

      name of the queue

      -
      - -
    • - -
    - -

    Yields:

    -
      - -
    • - - - - - - - -

      when uniqueness is disabled

      -
      - -
    • - -
    • - - - - - - - -

      when the lock class executes successfully

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -
    -
    # File 'lib/sidekiq_unique_jobs/server/middleware.rb', line 19
    -
    -def call(worker_class, item, queue)
    -  @worker_class = worker_class
    -  @item         = item
    -  @queue        = queue
    -  return yield if unique_disabled?
    -
    -  SidekiqUniqueJobs::Job.add_uniqueness(item)
    -  Sidekiq::Logging.with_context(logging_context(self.class, item)) do
    -    lock.execute do
    -      yield
    -    end
    -  end
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/SidekiqWorkerMethods.html b/docs/SidekiqUniqueJobs/SidekiqWorkerMethods.html deleted file mode 100644 index 5857e43a7..000000000 --- a/docs/SidekiqUniqueJobs/SidekiqWorkerMethods.html +++ /dev/null @@ -1,704 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::SidekiqWorkerMethods - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::SidekiqWorkerMethods - - - -

    -
    - - - - - - - - - -
    -
    Included in:
    -
    OnConflict::Reschedule, Timeout::Calculator, UniqueArgs
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb
    -
    - -
    - -

    Overview

    -
    -

    Module with convenience methods for the Sidekiq::Worker class

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #after_unlock_hookProc - - - - - -

    -
    -

    The hook to call after a successful unlock

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Proc) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -37
    -38
    -39
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 37
    -
    -def after_unlock_hook
    -  -> { worker_class.after_unlock if worker_method_defined?(:after_unlock) }
    -end
    -
    -
    - -
    -

    - - #default_worker_optionsObject - - - - - -

    - - - - -
    -
    -
    -
    -58
    -59
    -60
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 58
    -
    -def default_worker_options
    -  Sidekiq.default_worker_options
    -end
    -
    -
    - -
    -

    - - #sidekiq_worker_class?true, false - - - - - -

    -
    -

    Tests that the

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (true) - - - - — -

      if worker_class responds to get_sidekiq_options

      -
      - -
    • - -
    • - - - (false) - - - - — -

      if worker_class does not respond to get_sidekiq_options

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -25
    -26
    -27
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 25
    -
    -def sidekiq_worker_class?
    -  worker_method_defined?(:get_sidekiq_options)
    -end
    -
    -
    - -
    -

    - - #worker_classSidekiq::Worker - - - - - -

    -
    -

    The Sidekiq::Worker implementation

    - - -
    -
    -
    - -

    Returns:

    - - -
    - - - - -
    -
    -
    -
    -31
    -32
    -33
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 31
    -
    -def worker_class
    -  @_worker_class ||= worker_class_constantize # rubocop:disable Naming/MemoizedInstanceVariableName
    -end
    -
    -
    - -
    -

    - - #worker_class_constantize(klazz = @worker_class) ⇒ Sidekiq::Worker - - - - - -

    -
    -

    Attempt to constantize a string worker_class argument, always -failing back to the original argument when the constant can't be found

    - - -
    -
    -
    - -

    Returns:

    - - -
    - - - - -
    -
    -
    -
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    -53
    -54
    -55
    -56
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 45
    -
    -def worker_class_constantize(klazz = @worker_class)
    -  return klazz unless klazz.is_a?(String)
    -
    -  Object.const_get(klazz)
    -rescue NameError => ex
    -  case ex.message
    -  when /uninitialized constant/
    -    klazz
    -  else
    -    raise
    -  end
    -end
    -
    -
    - -
    -

    - - #worker_method_defined?(method_sym) ⇒ true, false - - - - - -

    -
    -

    Avoids duplicating worker_class.respond_to? in multiple places

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (true, false) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -10
    -11
    -12
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 10
    -
    -def worker_method_defined?(method_sym)
    -  worker_class.respond_to?(method_sym)
    -end
    -
    -
    - -
    -

    - - #worker_optionsHash - - - - - -

    -
    -

    Wraps #get_sidekiq_options to always work with a hash

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Hash) - - - - — -

      of the worker class sidekiq options

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -16
    -17
    -18
    -19
    -20
    -
    -
    # File 'lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb', line 16
    -
    -def worker_options
    -  return {} unless sidekiq_worker_class?
    -
    -  worker_class.get_sidekiq_options.stringify_keys
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Timeout.html b/docs/SidekiqUniqueJobs/Timeout.html deleted file mode 100644 index 8c2591c52..000000000 --- a/docs/SidekiqUniqueJobs/Timeout.html +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Timeout - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Timeout - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/timeout.rb,
    - lib/sidekiq_unique_jobs/timeout/calculator.rb
    -
    -
    - -
    - -

    Defined Under Namespace

    -

    - - - - - Classes: Calculator - - -

    - - - - - - - - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Timeout/Calculator.html b/docs/SidekiqUniqueJobs/Timeout/Calculator.html deleted file mode 100644 index 3f2c1514f..000000000 --- a/docs/SidekiqUniqueJobs/Timeout/Calculator.html +++ /dev/null @@ -1,766 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::Timeout::Calculator - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::Timeout::Calculator - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    SidekiqWorkerMethods
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/timeout/calculator.rb
    -
    - -
    - -

    Overview

    -
    -

    Calculates timeout and expiration

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - -

    Instance Attribute Summary collapse

    -
      - -
    • - - - #item ⇒ Object - - - - - - - - - readonly - - - - - - - - - -
      - -
    • - - -
    - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from SidekiqWorkerMethods

    -

    #after_unlock_hook, #default_worker_options, #sidekiq_worker_class?, #worker_class, #worker_class_constantize, #worker_method_defined?, #worker_options

    -
    -

    Constructor Details

    - -
    -

    - - #initialize(item) ⇒ Calculator - - - - - -

    -
    -

    Returns a new instance of Calculator

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      the Sidekiq job hash

      -
      - -
    • - -
    - - - - -

    Options Hash (item):

    -
      - -
    • - :lock_expiration - (Integer, nil) - - - - - —

      the configured lock expiration

      -
      - -
    • - -
    • - :lock_timeout - (Integer, nil) - - - - - —

      the configured lock timeout

      -
      - -
    • - -
    • - :class - (String) - - - - - —

      the class of the sidekiq worker

      -
      - -
    • - -
    • - :at - (Float) - - - - - —

      the unix time the job is scheduled at

      -
      - -
    • - -
    - - - -
    - - - - -
    -
    -
    -
    -19
    -20
    -21
    -22
    -
    -
    # File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 19
    -
    -def initialize(item)
    -  @item         = item
    -  @worker_class = item[CLASS_KEY]
    -end
    -
    -
    - -
    - -
    -

    Instance Attribute Details

    - - - -
    -

    - - #itemObject (readonly) - - - - - -

    - - - - -
    -
    -
    -
    -12
    -13
    -14
    -
    -
    # File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 12
    -
    -def item
    -  @item
    -end
    -
    -
    - -
    - - -
    -

    Instance Method Details

    - - -
    -

    - - #default_lock_timeoutObject - - - - - -

    -
    -

    The default lock_timeout of this gem

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -58
    -59
    -60
    -
    -
    # File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 58
    -
    -def default_lock_timeout
    -  SidekiqUniqueJobs.config.default_lock_timeout
    -end
    -
    -
    - -
    -

    - - #lock_expirationObject - - - - - -

    -
    -

    The configured lock_expiration

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -
    -
    # File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 39
    -
    -def lock_expiration
    -  @lock_expiration ||= begin
    -    expiration = item[LOCK_EXPIRATION_KEY]
    -    expiration ||= worker_options[LOCK_EXPIRATION_KEY]
    -    expiration && expiration.to_i + time_until_scheduled
    -  end
    -end
    -
    -
    - -
    -

    - - #lock_timeoutObject - - - - - -

    -
    -

    The configured lock_timeout

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -48
    -49
    -50
    -51
    -52
    -53
    -54
    -55
    -
    -
    # File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 48
    -
    -def lock_timeout
    -  @lock_timeout = begin
    -    timeout = default_worker_options[LOCK_TIMEOUT_KEY]
    -    timeout = default_lock_timeout if default_lock_timeout
    -    timeout = worker_options[LOCK_TIMEOUT_KEY] if worker_options.key?(LOCK_TIMEOUT_KEY)
    -    timeout
    -  end
    -end
    -
    -
    - -
    -

    - - #scheduled_atFloat - - - - - -

    -
    -

    The time a job is scheduled

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Float) - - - - — -

      the exact unix time the job is scheduled at

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -34
    -35
    -36
    -
    -
    # File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 34
    -
    -def scheduled_at
    -  @scheduled_at ||= item[AT_KEY]
    -end
    -
    -
    - -
    -

    - - #time_until_scheduledInteger - - - - - -

    -
    -

    The time until a job is scheduled

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Integer) - - - - — -

      the number of seconds until job is scheduled

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -26
    -27
    -28
    -29
    -30
    -
    -
    # File 'lib/sidekiq_unique_jobs/timeout/calculator.rb', line 26
    -
    -def time_until_scheduled
    -  return 0 unless scheduled_at
    -
    -  scheduled_at.to_i - Time.now.utc.to_i
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/UniqueArgs.html b/docs/SidekiqUniqueJobs/UniqueArgs.html deleted file mode 100644 index 0590c4007..000000000 --- a/docs/SidekiqUniqueJobs/UniqueArgs.html +++ /dev/null @@ -1,1704 +0,0 @@ - - - - - - - Class: SidekiqUniqueJobs::UniqueArgs - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Class: SidekiqUniqueJobs::UniqueArgs - - - -

    -
    - -
    -
    Inherits:
    -
    - Object - -
      -
    • Object
    • - - - -
    - show all - -
    -
    - - - - - - -
    -
    Includes:
    -
    Logging, SidekiqWorkerMethods
    -
    - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/unique_args.rb
    -
    - -
    - -

    Overview

    -
    -

    Handles uniqueness of sidekiq arguments

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - -

    Instance Attribute Summary collapse

    -
      - -
    • - - - #item ⇒ Hash - - - - - - - - - readonly - - - - - - - - - -

      The sidekiq job hash.

      -
      - -
    • - - -
    - - - - - -

    - Class Method Summary - collapse -

    - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from SidekiqWorkerMethods

    -

    #after_unlock_hook, #default_worker_options, #sidekiq_worker_class?, #worker_class, #worker_class_constantize, #worker_method_defined?, #worker_options

    - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    -
    -

    Constructor Details

    - -
    -

    - - #initialize(item) ⇒ UniqueArgs - - - - - -

    -
    -

    Returns a new instance of UniqueArgs

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      a Sidekiq job hash

      -
      - -
    • - -
    - - -
    - - - - -
    -
    -
    -
    -26
    -27
    -28
    -29
    -30
    -31
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 26
    -
    -def initialize(item)
    -  @item         = item
    -  @worker_class = item[CLASS_KEY]
    -
    -  add_uniqueness_to_item
    -end
    -
    -
    - -
    - -
    -

    Instance Attribute Details

    - - - -
    -

    - - #itemHash (readonly) - - - - - -

    -
    -

    The sidekiq job hash

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Hash) - - - - — -

      the Sidekiq job hash

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -23
    -24
    -25
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 23
    -
    -def item
    -  @item
    -end
    -
    -
    - -
    - - -
    -

    Class Method Details

    - - -
    -

    - - .digest(item) ⇒ String - - - - - -

    -
    -

    Convenience method for returning a digest

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      a Sidekiq job hash

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (String) - - - - — -

      a unique digest

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -17
    -18
    -19
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 17
    -
    -def self.digest(item)
    -  new(item).unique_digest
    -end
    -
    -
    - -
    - -
    -

    Instance Method Details

    - - -
    -

    - - #add_uniqueness_to_itemvoid - - - - - -

    -
    -

    This method returns an undefined value.

    Appends the keys unique_prefix, unique_args and #unique_digest to the sidekiq job hash #item

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -35
    -36
    -37
    -38
    -39
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 35
    -
    -def add_uniqueness_to_item
    -  item[UNIQUE_PREFIX_KEY] ||= unique_prefix
    -  item[UNIQUE_ARGS_KEY]     = unique_args(item[ARGS_KEY])
    -  item[UNIQUE_DIGEST_KEY]   = unique_digest
    -end
    -
    -
    - -
    -

    - - #create_digestString - - - - - -

    -
    -

    Creates a namespaced unique digest based on the #digestable_hash and the #unique_prefix

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (String) - - - - — -

      a unique digest

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -49
    -50
    -51
    -52
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 49
    -
    -def create_digest
    -  digest = Digest::MD5.hexdigest(Sidekiq.dump_json(digestable_hash))
    -  "#{unique_prefix}:#{digest}"
    -end
    -
    -
    - -
    -

    - - #default_unique_args_methodObject - - - - - -

    -
    -

    The global worker options defined in Sidekiq directly

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -145
    -146
    -147
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 145
    -
    -def default_unique_args_method
    -  Sidekiq.default_worker_options.stringify_keys[UNIQUE_ARGS_KEY]
    -end
    -
    -
    - -
    -

    - - #digestable_hashHash - - - - - -

    -
    -

    Filter a hash to use for digest

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (Hash) - - - - — -

      to use for digest

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -62
    -63
    -64
    -65
    -66
    -67
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 62
    -
    -def digestable_hash
    -  @item.slice(CLASS_KEY, QUEUE_KEY, UNIQUE_ARGS_KEY).tap do |hash|
    -    hash.delete(QUEUE_KEY) if unique_across_queues?
    -    hash.delete(CLASS_KEY) if unique_across_workers?
    -  end
    -end
    -
    -
    - -
    -

    - - #filter_by_proc(args) ⇒ Array - - - - - -

    -
    -

    Filters unique arguments by proc configured in the sidekiq worker

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - args - - - (Array) - - - - — -

      the arguments passed to the sidekiq worker

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (Array) - - - - — -

      with the filtered arguments

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -120
    -121
    -122
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 120
    -
    -def filter_by_proc(args)
    -  unique_args_method.call(args)
    -end
    -
    -
    - -
    -

    - - #filter_by_symbol(args) ⇒ Array - - - - - -

    -
    -

    Filters unique arguments by method configured in the sidekiq worker

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - args - - - (Array) - - - - — -

      the arguments passed to the sidekiq worker

      -
      - -
    • - -
    - -

    Returns:

    - - -
    - - - - -
    -
    -
    -
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 128
    -
    -def filter_by_symbol(args)
    -  return args unless worker_method_defined?(unique_args_method)
    -
    -  worker_class.send(unique_args_method, args)
    -rescue ArgumentError => ex
    -  log_fatal(ex)
    -  args
    -end
    -
    -
    - -
    -

    - - #filtered_args(args) ⇒ Array - - - - - -

    -
    -

    Filters unique arguments by proc or symbol

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - args - - - (Array) - - - - — -

      the arguments passed to the sidekiq worker

      -
      - -
    • - -
    - -

    Returns:

    - - -
    - - - - -
    -
    -
    -
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 101
    -
    -def filtered_args(args)
    -  return args if args.empty?
    -
    -  json_args = Normalizer.jsonify(args)
    -
    -  case unique_args_method
    -  when Proc
    -    filter_by_proc(json_args)
    -  when Symbol
    -    filter_by_symbol(json_args)
    -  else
    -    log_debug("#{__method__} arguments not filtered (using all arguments for uniqueness)")
    -    json_args
    -  end
    -end
    -
    -
    - -
    -

    - - #unique_across_queues?true, false - - - - - -

    -
    -

    Checks if we should disregard the queue when creating the unique digest

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (true, false) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -79
    -80
    -81
    -82
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 79
    -
    -def unique_across_queues?
    -  item[UNIQUE_ACROSS_QUEUES_KEY] || worker_options[UNIQUE_ACROSS_QUEUES_KEY] ||
    -    item[UNIQUE_ON_ALL_QUEUES_KEY] || worker_options[UNIQUE_ON_ALL_QUEUES_KEY] # TODO: Remove in v 6.1
    -end
    -
    -
    - -
    -

    - - #unique_across_workers?true, false - - - - - -

    -
    -

    Checks if we should disregard the worker when creating the unique digest

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (true, false) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -86
    -87
    -88
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 86
    -
    -def unique_across_workers?
    -  item[UNIQUE_ACROSS_WORKERS_KEY] || worker_options[UNIQUE_ACROSS_WORKERS_KEY]
    -end
    -
    -
    - -
    -

    - - #unique_args(args) ⇒ Array - - - - - -

    -
    -

    The unique arguments to use for creating a lock

    - - -
    -
    -
    - -

    Returns:

    - - -
    - - - - -
    -
    -
    -
    -71
    -72
    -73
    -74
    -75
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 71
    -
    -def unique_args(args)
    -  return filtered_args(args) if unique_args_enabled?
    -
    -  args
    -end
    -
    -
    - -
    -

    - - #unique_args_enabled?true, false - - - - - -

    -
    -

    Checks if the worker class has been enabled for unique_args?

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (true, false) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -92
    -93
    -94
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 92
    -
    -def unique_args_enabled?
    -  unique_args_method # && !unique_args_method.is_a?(Boolean)
    -end
    -
    -
    - -
    -

    - - #unique_args_methodObject - - - - - -

    -
    -

    The method to use for filtering unique arguments

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -138
    -139
    -140
    -141
    -142
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 138
    -
    -def unique_args_method
    -  @unique_args_method ||= worker_options[UNIQUE_ARGS_KEY]
    -  @unique_args_method ||= :unique_args if worker_method_defined?(:unique_args)
    -  @unique_args_method ||= default_unique_args_method
    -end
    -
    -
    - -
    -

    - - #unique_digestString - - - - - -

    -
    -

    Memoized unique_digest

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (String) - - - - — -

      a unique digest

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -43
    -44
    -45
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 43
    -
    -def unique_digest
    -  @unique_digest ||= create_digest
    -end
    -
    -
    - -
    -

    - - #unique_prefixString - - - - - -

    -
    -

    A prefix to use as namespace for the #unique_digest

    - - -
    -
    -
    - -

    Returns:

    -
      - -
    • - - - (String) - - - - — -

      a unique digest

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -56
    -57
    -58
    -
    -
    # File 'lib/sidekiq_unique_jobs/unique_args.rb', line 56
    -
    -def unique_prefix
    -  worker_options[UNIQUE_PREFIX_KEY] || SidekiqUniqueJobs.config.unique_prefix
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/UnknownLock.html b/docs/SidekiqUniqueJobs/UnknownLock.html deleted file mode 100644 index ebdb5fc99..000000000 --- a/docs/SidekiqUniqueJobs/UnknownLock.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - Exception: SidekiqUniqueJobs::UnknownLock - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Exception: SidekiqUniqueJobs::UnknownLock - - - -

    -
    - -
    -
    Inherits:
    -
    - StandardError - -
      -
    • Object
    • - - - - - -
    - show all - -
    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/exceptions.rb
    -
    - -
    - -

    Overview

    -
    -

    Error raised from OptionsWithFallback#lock_class

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - - - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Unlockable.html b/docs/SidekiqUniqueJobs/Unlockable.html deleted file mode 100644 index 0fa9f952d..000000000 --- a/docs/SidekiqUniqueJobs/Unlockable.html +++ /dev/null @@ -1,318 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Unlockable - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Unlockable - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/unlockable.rb
    -
    - -
    - -

    Overview

    -
    -

    Utility module to help manage unique keys in redis. -Useful for deleting keys that for whatever reason wasn't deleted

    - - -
    -
    -
    - -

    Author:

    - - -
    - - - - - - - -

    - Class Method Summary - collapse -

    - - - - - - -
    -

    Class Method Details

    - - -
    -

    - - .delete(item) ⇒ Object - - - - - -

    -
    -

    Deletes a lock regardless of if it was locked or not.

    - -

    This is good for situations when a job is locked by another item

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      a Sidekiq job hash

      -
      - -
    • - -
    - - -
    - - - - -
    -
    -
    -
    -22
    -23
    -24
    -25
    -
    -
    # File 'lib/sidekiq_unique_jobs/unlockable.rb', line 22
    -
    -def delete(item)
    -  SidekiqUniqueJobs::UniqueArgs.digest(item)
    -  SidekiqUniqueJobs::Locksmith.new(item).delete!
    -end
    -
    -
    - -
    -

    - - .unlock(item) ⇒ Object - - - - - -

    -
    -

    Unlocks a job.

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - item - - - (Hash) - - - - — -

      a Sidekiq job hash

      -
      - -
    • - -
    - - -
    - - - - -
    -
    -
    -
    -13
    -14
    -15
    -16
    -
    -
    # File 'lib/sidekiq_unique_jobs/unlockable.rb', line 13
    -
    -def unlock(item)
    -  SidekiqUniqueJobs::UniqueArgs.digest(item)
    -  SidekiqUniqueJobs::Locksmith.new(item).unlock
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Util.html b/docs/SidekiqUniqueJobs/Util.html deleted file mode 100644 index 6d5ad3bfa..000000000 --- a/docs/SidekiqUniqueJobs/Util.html +++ /dev/null @@ -1,611 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Util - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Util - - - -

    -
    - - - - -
    -
    Extended by:
    -
    Util
    -
    - - - -
    -
    Includes:
    -
    Connection, Logging
    -
    - - - - -
    -
    Included in:
    -
    Util
    -
    - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/util.rb
    -
    - -
    - -

    Overview

    -
    -

    Utility module to help manage unique keys in redis. -Useful for deleting keys that for whatever reason wasn't deleted

    - - -
    -
    -
    - -

    Author:

    - - -
    - -

    - Constant Summary - collapse -

    - -
    - -
    DEFAULT_COUNT = - -
    -
    1_000
    - -
    SCAN_PATTERN = - -
    -
    "*"
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - - - - - - - - -

    Methods included from Connection

    -

    #redis

    - - - - - - - - - -

    Methods included from Logging

    -

    #log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger, #logging_context

    - - -
    -

    Instance Method Details

    - - -
    -

    - - #del(pattern = SCAN_PATTERN, count = 0) ⇒ Integer - - - - - -

    -
    -

    Deletes unique keys from redis

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - pattern - - - (String) - - - (defaults to: SCAN_PATTERN) - - - — -

      a pattern to scan for in redis

      -
      - -
    • - -
    • - - count - - - (Integer) - - - (defaults to: 0) - - - — -

      the maximum number of keys to delete

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (Integer) - - - - — -

      the number of keys deleted

      -
      - -
    • - -
    -

    Raises:

    -
      - -
    • - - - (ArgumentError) - - - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -
    -
    # File 'lib/sidekiq_unique_jobs/util.rb', line 46
    -
    -def del(pattern = SCAN_PATTERN, count = 0)
    -  raise ArgumentError, "Please provide a number of keys to delete greater than zero" if count.zero?
    -
    -  pattern = suffix(pattern)
    -
    -  log_debug { "Deleting keys by: #{pattern}" }
    -  keys, time = timed { keys(pattern, count) }
    -  key_size   = keys.size
    -  log_debug { "#{key_size} keys found in #{time} sec." }
    -  _, time = timed { batch_delete(keys) }
    -  log_debug { "Deleted #{key_size} keys in #{time} sec." }
    -
    -  key_size
    -end
    -
    -
    - -
    -

    - - #keys(pattern = SCAN_PATTERN, count = DEFAULT_COUNT) ⇒ Array<String> - - - - - -

    -
    -

    Find unique keys in redis

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - pattern - - - (String) - - - (defaults to: SCAN_PATTERN) - - - — -

      a pattern to scan for in redis

      -
      - -
    • - -
    • - - count - - - (Integer) - - - (defaults to: DEFAULT_COUNT) - - - — -

      the maximum number of keys to delete

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (Array<String>) - - - - — -

      an array with active unique keys

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -21
    -22
    -23
    -24
    -25
    -
    -
    # File 'lib/sidekiq_unique_jobs/util.rb', line 21
    -
    -def keys(pattern = SCAN_PATTERN, count = DEFAULT_COUNT)
    -  return redis(&:keys) if pattern.nil?
    -
    -  redis { |conn| conn.scan_each(match: prefix(pattern), count: count).to_a }
    -end
    -
    -
    - -
    -

    - - #keys_with_ttl(pattern = SCAN_PATTERN, count = DEFAULT_COUNT) ⇒ Hash<String, Integer> - - - - - -

    -
    -

    Find unique keys with ttl

    - - -
    -
    -
    -

    Parameters:

    -
      - -
    • - - pattern - - - (String) - - - (defaults to: SCAN_PATTERN) - - - — -

      a pattern to scan for in redis

      -
      - -
    • - -
    • - - count - - - (Integer) - - - (defaults to: DEFAULT_COUNT) - - - — -

      the maximum number of keys to delete

      -
      - -
    • - -
    - -

    Returns:

    -
      - -
    • - - - (Hash<String, Integer>) - - - - — -

      a hash with active unique keys and corresponding ttl

      -
      - -
    • - -
    - -
    - - - - -
    -
    -
    -
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -
    -
    # File 'lib/sidekiq_unique_jobs/util.rb', line 31
    -
    -def keys_with_ttl(pattern = SCAN_PATTERN, count = DEFAULT_COUNT)
    -  hash = {}
    -  redis do |conn|
    -    conn.scan_each(match: prefix(pattern), count: count).each do |key|
    -      hash[key] = conn.ttl(key)
    -    end
    -  end
    -  hash
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Web.html b/docs/SidekiqUniqueJobs/Web.html deleted file mode 100644 index 6e5d3bb11..000000000 --- a/docs/SidekiqUniqueJobs/Web.html +++ /dev/null @@ -1,275 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Web - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Web - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/web.rb,
    - lib/sidekiq_unique_jobs/web/helpers.rb
    -
    -
    - -
    - -

    Overview

    -
    -

    Utility module to help manage unique keys in redis. -Useful for deleting keys that for whatever reason wasn't deleted

    - - -
    -
    -
    - -

    Author:

    - - -

    Defined Under Namespace

    -

    - - - Modules: Helpers - - - - -

    - - - - - - - - -

    - Class Method Summary - collapse -

    - - - - - - -
    -

    Class Method Details

    - - -
    -

    - - .registered(app) ⇒ Object - - - - - -

    -
    -

    rubocop:disable Metrics/MethodLength

    - - -
    -
    -
    - - -
    - - - - -
    -
    -
    -
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -
    -
    # File 'lib/sidekiq_unique_jobs/web.rb', line 17
    -
    -def self.registered(app) # rubocop:disable Metrics/MethodLength
    -  app.helpers do
    -    include Web::Helpers
    -  end
    -
    -  app.get "/unique_digests" do
    -    @filter         = params[:filter] || "*"
    -    @filter         = "*" if @filter == ""
    -    @count          = (params[:count] || 100).to_i
    -    @current_cursor = params[:cursor]
    -    @prev_cursor    = params[:prev_cursor]
    -    @total_size, @next_cursor, @unique_digests =
    -      Digests.page(pattern: @filter, cursor: @current_cursor, page_size: @count)
    -
    -    erb(unique_template(:unique_digests))
    -  end
    -
    -  app.get "/unique_digests/:digest" do
    -    @digest = params[:digest]
    -    @unique_keys = Util.keys("#{@digest}*", 1000)
    -
    -    erb(unique_template(:unique_digest))
    -  end
    -
    -  app.get "/unique_digests/:digest/delete" do
    -    Digests.del(digest: params[:digest])
    -    redirect_to :unique_digests
    -  end
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/SidekiqUniqueJobs/Web/Helpers.html b/docs/SidekiqUniqueJobs/Web/Helpers.html deleted file mode 100644 index 92f52afe4..000000000 --- a/docs/SidekiqUniqueJobs/Web/Helpers.html +++ /dev/null @@ -1,393 +0,0 @@ - - - - - - - Module: SidekiqUniqueJobs::Web::Helpers - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Module: SidekiqUniqueJobs::Web::Helpers - - - -

    -
    - - - - - - - - - - - -
    -
    Defined in:
    -
    lib/sidekiq_unique_jobs/web/helpers.rb
    -
    - -
    - - - -

    - Constant Summary - collapse -

    - -
    - -
    VIEW_PATH = - -
    -
    File.expand_path("../web/views", __dir__)
    - -
    SAFE_CPARAMS = - -
    -
    %w[cursor prev_cursor].freeze
    - -
    - - - - - - - - - -

    - Instance Method Summary - collapse -

    - - - - - - -
    -

    Instance Method Details

    - - -
    -

    - - #cparams(options) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -
    -
    # File 'lib/sidekiq_unique_jobs/web/helpers.rb', line 14
    -
    -def cparams(options)
    -  # stringify
    -  options.keys.each do |key|
    -    options[key.to_s] = options.delete(key)
    -  end
    -
    -  params.merge(options).map do |key, value|
    -    next unless SAFE_CPARAMS.include?(key)
    -
    -    "#{key}=#{CGI.escape(value.to_s)}"
    -  end.compact.join("&")
    -end
    -
    -
    - -
    -

    - - #redirect_to(subpath) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -
    -
    # File 'lib/sidekiq_unique_jobs/web/helpers.rb', line 27
    -
    -def redirect_to(subpath)
    -  if respond_to?(:to)
    -    # Sinatra-based web UI
    -    redirect to(subpath)
    -  else
    -    # Non-Sinatra based web UI (Sidekiq 4.2+)
    -    redirect "#{root_path}#{subpath}"
    -  end
    -end
    -
    -
    - -
    -

    - - #safe_relative_time(time) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -
    -
    # File 'lib/sidekiq_unique_jobs/web/helpers.rb', line 37
    -
    -def safe_relative_time(time)
    -  time = if time.is_a?(Numeric)
    -           Time.at(time)
    -         else
    -           Time.parse(time)
    -         end
    -
    -  relative_time(time)
    -end
    -
    -
    - -
    -

    - - #unique_template(name) ⇒ Object - - - - - -

    - - - - -
    -
    -
    -
    -8
    -9
    -10
    -
    -
    # File 'lib/sidekiq_unique_jobs/web/helpers.rb', line 8
    -
    -def unique_template(name)
    -  File.open(File.join(VIEW_PATH, "#{name}.erb")).read
    -end
    -
    -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/_index.html b/docs/_index.html deleted file mode 100644 index c542a51b8..000000000 --- a/docs/_index.html +++ /dev/null @@ -1,633 +0,0 @@ - - - - - - - Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
    - - -

    Documentation by YARD 0.9.18

    -
    -

    Alphabetic Index

    - -

    File Listing

    - - -
    -

    Namespace Listing A-Z

    - - - - - - - - -
    - - -
      -
    • A
    • - -
    - - -
      -
    • B
    • -
        - -
      • - BaseLock - - (SidekiqUniqueJobs::Lock) - -
      • - -
      -
    - - -
      -
    • C
    • -
        - -
      • - Calculator - - (SidekiqUniqueJobs::Timeout) - -
      • - -
      • - ClassMethods - - (Sidekiq::Worker) - -
      • - -
      • - Cli - - (SidekiqUniqueJobs) - -
      • - -
      • - Client - - (SidekiqUniqueJobs) - -
      • - -
      • - Conflict - - (SidekiqUniqueJobs) - -
      • - -
      • - Connection - - (SidekiqUniqueJobs) - -
      • - -
      -
    - - -
      -
    • D
    • -
        - -
      • - Digests - - (SidekiqUniqueJobs) - -
      • - -
      -
    - - -
      -
    • H
    • -
        - -
      • - Hash - -
      • - -
      • - Helpers - - (SidekiqUniqueJobs::Web) - -
      • - -
      -
    - - -
      -
    • J
    • -
        - -
      • - Job - - (Sidekiq) - -
      • - -
      • - Job - - (SidekiqUniqueJobs) - -
      • - -
      • - JobSet - - (Sidekiq) - -
      • - -
      -
    - - -
      -
    • L
    • -
        - -
      • - Lock - - (SidekiqUniqueJobs) - -
      • - -
      • - Locksmith - - (SidekiqUniqueJobs) - -
      • - -
      • - Log - - (SidekiqUniqueJobs::OnConflict) - -
      • - -
      • - Logging - - (SidekiqUniqueJobs) - -
      • - -
      -
    - - -
    - - -
      -
    • M
    • -
        - -
      • - Middleware - - (SidekiqUniqueJobs) - -
      • - -
      • - Middleware - - (SidekiqUniqueJobs::Server) - -
      • - -
      • - Middleware - - (SidekiqUniqueJobs::Client) - -
      • - -
      -
    - - -
      -
    • N
    • - -
    - - - - - -
      -
    • Q
    • -
        - -
      • - Queue - - (Sidekiq) - -
      • - -
      -
    - - -
      -
    • R
    • -
        - -
      • - Raise - - (SidekiqUniqueJobs::OnConflict) - -
      • - -
      • - Reject - - (SidekiqUniqueJobs::OnConflict) - -
      • - -
      • - Replace - - (SidekiqUniqueJobs::OnConflict) - -
      • - -
      • - Reschedule - - (SidekiqUniqueJobs::OnConflict) - -
      • - -
      -
    - - - - - -
      -
    • T
    • -
        - -
      • - Testing - - (Sidekiq::Worker::Overrides) - -
      • - -
      • - Timeout - - (SidekiqUniqueJobs) - -
      • - -
      -
    - - - - - -
    - - - - -
    - -
    - -
    - - - -
    - - \ No newline at end of file diff --git a/docs/class_list.html b/docs/class_list.html deleted file mode 100644 index 1d16a2e12..000000000 --- a/docs/class_list.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - Class List - - - -
    -
    -

    Class List

    - - - -
    - - -
    - - diff --git a/docs/css/common.css b/docs/css/common.css deleted file mode 100644 index cf25c4523..000000000 --- a/docs/css/common.css +++ /dev/null @@ -1 +0,0 @@ -/* Override this file with custom rules */ \ No newline at end of file diff --git a/docs/css/full_list.css b/docs/css/full_list.css deleted file mode 100644 index 742b72fa6..000000000 --- a/docs/css/full_list.css +++ /dev/null @@ -1,58 +0,0 @@ -body { - margin: 0; - font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; - font-size: 13px; - height: 101%; - overflow-x: hidden; - background: #fafafa; -} - -h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } -.clear { clear: both; } -.fixed_header { position: fixed; background: #fff; width: 100%; padding-bottom: 10px; margin-top: 0; top: 0; z-index: 9999; height: 70px; } -#search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } -#content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } -#full_list { padding: 0; list-style: none; margin-left: 0; margin-top: 80px; font-size: 1.1em; } -#full_list ul { padding: 0; } -#full_list li { padding: 0; margin: 0; list-style: none; } -#full_list li .item { padding: 5px 5px 5px 12px; } -#noresults { padding: 7px 12px; background: #fff; } -#content.insearch #noresults { margin-left: 7px; } -li.collapsed ul { display: none; } -li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } -li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; } -li { color: #888; cursor: pointer; } -li.deprecated { text-decoration: line-through; font-style: italic; } -li.odd { background: #f0f0f0; } -li.even { background: #fafafa; } -.item:hover { background: #ddd; } -li small:before { content: "("; } -li small:after { content: ")"; } -li small.search_info { display: none; } -a, a:visited { text-decoration: none; color: #05a; } -li.clicked > .item { background: #05a; color: #ccc; } -li.clicked > .item a, li.clicked > .item a:visited { color: #eee; } -li.clicked > .item a.toggle { opacity: 0.5; background-position: bottom right; } -li.collapsed.clicked a.toggle { background-position: top right; } -#search input { border: 1px solid #bbb; border-radius: 3px; } -#full_list_nav { margin-left: 10px; font-size: 0.9em; display: block; color: #aaa; } -#full_list_nav a, #nav a:visited { color: #358; } -#full_list_nav a:hover { background: transparent; color: #5af; } -#full_list_nav span:after { content: ' | '; } -#full_list_nav span:last-child:after { content: ''; } - -#content h1 { margin-top: 0; } -li { white-space: nowrap; cursor: normal; } -li small { display: block; font-size: 0.8em; } -li small:before { content: ""; } -li small:after { content: ""; } -li small.search_info { display: none; } -#search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; } -#content.insearch #search { background-position: center right; } -#search input { width: 110px; } - -#full_list.insearch ul { display: block; } -#full_list.insearch .item { display: none; } -#full_list.insearch .found { display: block; padding-left: 11px !important; } -#full_list.insearch li a.toggle { display: none; } -#full_list.insearch li small.search_info { display: block; } diff --git a/docs/css/style.css b/docs/css/style.css deleted file mode 100644 index 44d87e0d4..000000000 --- a/docs/css/style.css +++ /dev/null @@ -1,496 +0,0 @@ -html { - width: 100%; - height: 100%; -} -body { - font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; - font-size: 13px; - width: 100%; - margin: 0; - padding: 0; - display: flex; - display: -webkit-flex; - display: -ms-flexbox; -} - -#nav { - position: relative; - width: 100%; - height: 100%; - border: 0; - border-right: 1px dotted #eee; - overflow: auto; -} -.nav_wrap { - margin: 0; - padding: 0; - width: 20%; - height: 100%; - position: relative; - display: flex; - display: -webkit-flex; - display: -ms-flexbox; - flex-shrink: 0; - -webkit-flex-shrink: 0; - -ms-flex: 1 0; -} -#resizer { - position: absolute; - right: -5px; - top: 0; - width: 10px; - height: 100%; - cursor: col-resize; - z-index: 9999; -} -#main { - flex: 5 1; - -webkit-flex: 5 1; - -ms-flex: 5 1; - outline: none; - position: relative; - background: #fff; - padding: 1.2em; - padding-top: 0.2em; -} - -@media (max-width: 920px) { - .nav_wrap { width: 100%; top: 0; right: 0; overflow: visible; position: absolute; } - #resizer { display: none; } - #nav { - z-index: 9999; - background: #fff; - display: none; - position: absolute; - top: 40px; - right: 12px; - width: 500px; - max-width: 80%; - height: 80%; - overflow-y: scroll; - border: 1px solid #999; - border-collapse: collapse; - box-shadow: -7px 5px 25px #aaa; - border-radius: 2px; - } -} - -@media (min-width: 920px) { - body { height: 100%; overflow: hidden; } - #main { height: 100%; overflow: auto; } - #search { display: none; } -} - -#main img { max-width: 100%; } -h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; } -h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; } -h1.title { margin-bottom: 10px; } -h1.alphaindex { margin-top: 0; font-size: 22px; } -h2 { - padding: 0; - padding-bottom: 3px; - border-bottom: 1px #aaa solid; - font-size: 1.4em; - margin: 1.8em 0 0.5em; - position: relative; -} -h2 small { font-weight: normal; font-size: 0.7em; display: inline; position: absolute; right: 0; } -h2 small a { - display: block; - height: 20px; - border: 1px solid #aaa; - border-bottom: 0; - border-top-left-radius: 5px; - background: #f8f8f8; - position: relative; - padding: 2px 7px; -} -.clear { clear: both; } -.inline { display: inline; } -.inline p:first-child { display: inline; } -.docstring, .tags, #filecontents { font-size: 15px; line-height: 1.5145em; } -.docstring p > code, .docstring p > tt, .tags p > code, .tags p > tt { - color: #c7254e; background: #f9f2f4; padding: 2px 4px; font-size: 1em; - border-radius: 4px; -} -.docstring h1, .docstring h2, .docstring h3, .docstring h4 { padding: 0; border: 0; border-bottom: 1px dotted #bbb; } -.docstring h1 { font-size: 1.2em; } -.docstring h2 { font-size: 1.1em; } -.docstring h3, .docstring h4 { font-size: 1em; border-bottom: 0; padding-top: 10px; } -.summary_desc .object_link a, .docstring .object_link a { - font-family: monospace; font-size: 1.05em; - color: #05a; background: #EDF4FA; padding: 2px 4px; font-size: 1em; - border-radius: 4px; -} -.rdoc-term { padding-right: 25px; font-weight: bold; } -.rdoc-list p { margin: 0; padding: 0; margin-bottom: 4px; } -.summary_desc pre.code .object_link a, .docstring pre.code .object_link a { - padding: 0px; background: inherit; color: inherit; border-radius: inherit; -} - -/* style for */ -#filecontents table, .docstring table { border-collapse: collapse; } -#filecontents table th, #filecontents table td, -.docstring table th, .docstring table td { border: 1px solid #ccc; padding: 8px; padding-right: 17px; } -#filecontents table tr:nth-child(odd), -.docstring table tr:nth-child(odd) { background: #eee; } -#filecontents table tr:nth-child(even), -.docstring table tr:nth-child(even) { background: #fff; } -#filecontents table th, .docstring table th { background: #fff; } - -/* style for
      */ -#filecontents li > p, .docstring li > p { margin: 0px; } -#filecontents ul, .docstring ul { padding-left: 20px; } -/* style for
      */ -#filecontents dl, .docstring dl { border: 1px solid #ccc; } -#filecontents dt, .docstring dt { background: #ddd; font-weight: bold; padding: 3px 5px; } -#filecontents dd, .docstring dd { padding: 5px 0px; margin-left: 18px; } -#filecontents dd > p, .docstring dd > p { margin: 0px; } - -.note { - color: #222; - margin: 20px 0; - padding: 10px; - border: 1px solid #eee; - border-radius: 3px; - display: block; -} -.docstring .note { - border-left-color: #ccc; - border-left-width: 5px; -} -.note.todo { background: #ffffc5; border-color: #ececaa; } -.note.returns_void { background: #efefef; } -.note.deprecated { background: #ffe5e5; border-color: #e9dada; } -.note.title.deprecated { background: #ffe5e5; border-color: #e9dada; } -.note.private { background: #ffffc5; border-color: #ececaa; } -.note.title { padding: 3px 6px; font-size: 0.9em; font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; display: inline; } -.summary_signature + .note.title { margin-left: 7px; } -h1 .note.title { font-size: 0.5em; font-weight: normal; padding: 3px 5px; position: relative; top: -3px; text-transform: capitalize; } -.note.title { background: #efefef; } -.note.title.constructor { color: #fff; background: #6a98d6; border-color: #6689d6; } -.note.title.writeonly { color: #fff; background: #45a638; border-color: #2da31d; } -.note.title.readonly { color: #fff; background: #6a98d6; border-color: #6689d6; } -.note.title.private { background: #d5d5d5; border-color: #c5c5c5; } -.note.title.not_defined_here { background: transparent; border: none; font-style: italic; } -.discussion .note { margin-top: 6px; } -.discussion .note:first-child { margin-top: 0; } - -h3.inherited { - font-style: italic; - font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; - font-weight: normal; - padding: 0; - margin: 0; - margin-top: 12px; - margin-bottom: 3px; - font-size: 13px; -} -p.inherited { - padding: 0; - margin: 0; - margin-left: 25px; -} - -.box_info dl { - margin: 0; - border: 0; - width: 100%; - font-size: 1em; - display: flex; - display: -webkit-flex; - display: -ms-flexbox; -} -.box_info dl dt { - flex-shrink: 0; - -webkit-flex-shrink: 1; - -ms-flex-shrink: 1; - width: 100px; - text-align: right; - font-weight: bold; - border: 1px solid #aaa; - border-width: 1px 0px 0px 1px; - padding: 6px 0; - padding-right: 10px; -} -.box_info dl dd { - flex-grow: 1; - -webkit-flex-grow: 1; - -ms-flex: 1; - max-width: 420px; - padding: 6px 0; - padding-right: 20px; - border: 1px solid #aaa; - border-width: 1px 1px 0 0; - overflow: hidden; - position: relative; -} -.box_info dl:last-child > * { - border-bottom: 1px solid #aaa; -} -.box_info dl:nth-child(odd) > * { background: #eee; } -.box_info dl:nth-child(even) > * { background: #fff; } -.box_info dl > * { margin: 0; } - -ul.toplevel { list-style: none; padding-left: 0; font-size: 1.1em; } -.index_inline_list { padding-left: 0; font-size: 1.1em; } - -.index_inline_list li { - list-style: none; - display: inline-block; - padding: 0 12px; - line-height: 30px; - margin-bottom: 5px; -} - -dl.constants { margin-left: 10px; } -dl.constants dt { font-weight: bold; font-size: 1.1em; margin-bottom: 5px; } -dl.constants.compact dt { display: inline-block; font-weight: normal } -dl.constants dd { width: 75%; white-space: pre; font-family: monospace; margin-bottom: 18px; } -dl.constants .docstring .note:first-child { margin-top: 5px; } - -.summary_desc { - margin-left: 32px; - display: block; - font-family: sans-serif; - font-size: 1.1em; - margin-top: 8px; - line-height: 1.5145em; - margin-bottom: 0.8em; -} -.summary_desc tt { font-size: 0.9em; } -dl.constants .note { padding: 2px 6px; padding-right: 12px; margin-top: 6px; } -dl.constants .docstring { margin-left: 32px; font-size: 0.9em; font-weight: normal; } -dl.constants .tags { padding-left: 32px; font-size: 0.9em; line-height: 0.8em; } -dl.constants .discussion *:first-child { margin-top: 0; } -dl.constants .discussion *:last-child { margin-bottom: 0; } - -.method_details { border-top: 1px dotted #ccc; margin-top: 25px; padding-top: 0; } -.method_details.first { border: 0; margin-top: 5px; } -.method_details.first h3.signature { margin-top: 1em; } -p.signature, h3.signature { - font-size: 1.1em; font-weight: normal; font-family: Monaco, Consolas, Courier, monospace; - padding: 6px 10px; margin-top: 1em; - background: #E8F4FF; border: 1px solid #d8d8e5; border-radius: 5px; -} -p.signature tt, -h3.signature tt { font-family: Monaco, Consolas, Courier, monospace; } -p.signature .overload, -h3.signature .overload { display: block; } -p.signature .extras, -h3.signature .extras { font-weight: normal; font-family: sans-serif; color: #444; font-size: 1em; } -p.signature .not_defined_here, -h3.signature .not_defined_here, -p.signature .aliases, -h3.signature .aliases { display: block; font-weight: normal; font-size: 0.9em; font-family: sans-serif; margin-top: 0px; color: #555; } -p.signature .aliases .names, -h3.signature .aliases .names { font-family: Monaco, Consolas, Courier, monospace; font-weight: bold; color: #000; font-size: 1.2em; } - -.tags .tag_title { font-size: 1.05em; margin-bottom: 0; font-weight: bold; } -.tags .tag_title tt { color: initial; padding: initial; background: initial; } -.tags ul { margin-top: 5px; padding-left: 30px; list-style: square; } -.tags ul li { margin-bottom: 3px; } -.tags ul .name { font-family: monospace; font-weight: bold; } -.tags ul .note { padding: 3px 6px; } -.tags { margin-bottom: 12px; } - -.tags .examples .tag_title { margin-bottom: 10px; font-weight: bold; } -.tags .examples .inline p { padding: 0; margin: 0; font-weight: bold; font-size: 1em; } -.tags .examples .inline p:before { content: "▸"; font-size: 1em; margin-right: 5px; } - -.tags .overload .overload_item { list-style: none; margin-bottom: 25px; } -.tags .overload .overload_item .signature { - padding: 2px 8px; - background: #F1F8FF; border: 1px solid #d8d8e5; border-radius: 3px; -} -.tags .overload .signature { margin-left: -15px; font-family: monospace; display: block; font-size: 1.1em; } -.tags .overload .docstring { margin-top: 15px; } - -.defines { display: none; } - -#method_missing_details .notice.this { position: relative; top: -8px; color: #888; padding: 0; margin: 0; } - -.showSource { font-size: 0.9em; } -.showSource a, .showSource a:visited { text-decoration: none; color: #666; } - -#content a, #content a:visited { text-decoration: none; color: #05a; } -#content a:hover { background: #ffffa5; } - -ul.summary { - list-style: none; - font-family: monospace; - font-size: 1em; - line-height: 1.5em; - padding-left: 0px; -} -ul.summary a, ul.summary a:visited { - text-decoration: none; font-size: 1.1em; -} -ul.summary li { margin-bottom: 5px; } -.summary_signature { padding: 4px 8px; background: #f8f8f8; border: 1px solid #f0f0f0; border-radius: 5px; } -.summary_signature:hover { background: #CFEBFF; border-color: #A4CCDA; cursor: pointer; } -.summary_signature.deprecated { background: #ffe5e5; border-color: #e9dada; } -ul.summary.compact li { display: inline-block; margin: 0px 5px 0px 0px; line-height: 2.6em;} -ul.summary.compact .summary_signature { padding: 5px 7px; padding-right: 4px; } -#content .summary_signature:hover a, -#content .summary_signature:hover a:visited { - background: transparent; - color: #049; -} - -p.inherited a { font-family: monospace; font-size: 0.9em; } -p.inherited { word-spacing: 5px; font-size: 1.2em; } - -p.children { font-size: 1.2em; } -p.children a { font-size: 0.9em; } -p.children strong { font-size: 0.8em; } -p.children strong.modules { padding-left: 5px; } - -ul.fullTree { display: none; padding-left: 0; list-style: none; margin-left: 0; margin-bottom: 10px; } -ul.fullTree ul { margin-left: 0; padding-left: 0; list-style: none; } -ul.fullTree li { text-align: center; padding-top: 18px; padding-bottom: 12px; background: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAHtJREFUeNqMzrEJAkEURdGzuhgZbSoYWcAWoBVsB4JgZAGmphsZCZYzTQgWNCYrDN9RvMmHx+X916SUBFbo8CzD1idXrLErw1mQttgXtyrOcQ/Ny5p4Qh+2XqLYYazsPWNTiuMkRxa4vcV+evuNAUOLIx5+c2hyzv7hNQC67Q+/HHmlEwAAAABJRU5ErkJggg==) no-repeat top center; } -ul.fullTree li:first-child { padding-top: 0; background: transparent; } -ul.fullTree li:last-child { padding-bottom: 0; } -.showAll ul.fullTree { display: block; } -.showAll .inheritName { display: none; } - -#search { position: absolute; right: 12px; top: 0px; z-index: 9000; } -#search a { - display: block; float: left; - padding: 4px 8px; text-decoration: none; color: #05a; fill: #05a; - border: 1px solid #d8d8e5; - border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; - background: #F1F8FF; - box-shadow: -1px 1px 3px #ddd; -} -#search a:hover { background: #f5faff; color: #06b; fill: #06b; } -#search a.active { - background: #568; padding-bottom: 20px; color: #fff; fill: #fff; - border: 1px solid #457; - border-top-left-radius: 5px; border-top-right-radius: 5px; -} -#search a.inactive { color: #999; fill: #999; } -.inheritanceTree, .toggleDefines { - float: right; - border-left: 1px solid #aaa; - position: absolute; top: 0; right: 0; - height: 100%; - background: #f6f6f6; - padding: 5px; - min-width: 55px; - text-align: center; -} - -#menu { font-size: 1.3em; color: #bbb; } -#menu .title, #menu a { font-size: 0.7em; } -#menu .title a { font-size: 1em; } -#menu .title { color: #555; } -#menu a, #menu a:visited { color: #333; text-decoration: none; border-bottom: 1px dotted #bbd; } -#menu a:hover { color: #05a; } - -#footer { margin-top: 15px; border-top: 1px solid #ccc; text-align: center; padding: 7px 0; color: #999; } -#footer a, #footer a:visited { color: #444; text-decoration: none; border-bottom: 1px dotted #bbd; } -#footer a:hover { color: #05a; } - -#listing ul.alpha { font-size: 1.1em; } -#listing ul.alpha { margin: 0; padding: 0; padding-bottom: 10px; list-style: none; } -#listing ul.alpha li.letter { font-size: 1.4em; padding-bottom: 10px; } -#listing ul.alpha ul { margin: 0; padding-left: 15px; } -#listing ul small { color: #666; font-size: 0.7em; } - -li.r1 { background: #f0f0f0; } -li.r2 { background: #fafafa; } - -#content ul.summary li.deprecated .summary_signature a, -#content ul.summary li.deprecated .summary_signature a:visited { text-decoration: line-through; font-style: italic; } - -#toc { - position: relative; - float: right; - overflow-x: auto; - right: -3px; - margin-left: 20px; - margin-bottom: 20px; - padding: 20px; padding-right: 30px; - max-width: 300px; - z-index: 5000; - background: #fefefe; - border: 1px solid #ddd; - box-shadow: -2px 2px 6px #bbb; -} -#toc .title { margin: 0; } -#toc ol { padding-left: 1.8em; } -#toc li { font-size: 1.1em; line-height: 1.7em; } -#toc > ol > li { font-size: 1.1em; font-weight: bold; } -#toc ol > ol { font-size: 0.9em; } -#toc ol ol > ol { padding-left: 2.3em; } -#toc ol + li { margin-top: 0.3em; } -#toc.hidden { padding: 10px; background: #fefefe; box-shadow: none; } -#toc.hidden:hover { background: #fafafa; } -#filecontents h1 + #toc.nofloat { margin-top: 0; } -@media (max-width: 560px) { - #toc { - margin-left: 0; - margin-top: 16px; - float: none; - max-width: none; - } -} - -/* syntax highlighting */ -.source_code { display: none; padding: 3px 8px; border-left: 8px solid #ddd; margin-top: 5px; } -#filecontents pre.code, .docstring pre.code, .source_code pre { font-family: monospace; } -#filecontents pre.code, .docstring pre.code { display: block; } -.source_code .lines { padding-right: 12px; color: #555; text-align: right; } -#filecontents pre.code, .docstring pre.code, -.tags pre.example { - padding: 9px 14px; - margin-top: 4px; - border: 1px solid #e1e1e8; - background: #f7f7f9; - border-radius: 4px; - font-size: 1em; - overflow-x: auto; - line-height: 1.2em; -} -pre.code { color: #000; tab-size: 2; } -pre.code .info.file { color: #555; } -pre.code .val { color: #036A07; } -pre.code .tstring_content, -pre.code .heredoc_beg, pre.code .heredoc_end, -pre.code .qwords_beg, pre.code .qwords_end, pre.code .qwords_sep, -pre.code .words_beg, pre.code .words_end, pre.code .words_sep, -pre.code .qsymbols_beg, pre.code .qsymbols_end, pre.code .qsymbols_sep, -pre.code .symbols_beg, pre.code .symbols_end, pre.code .symbols_sep, -pre.code .tstring, pre.code .dstring { color: #036A07; } -pre.code .fid, pre.code .rubyid_new, pre.code .rubyid_to_s, -pre.code .rubyid_to_sym, pre.code .rubyid_to_f, -pre.code .dot + pre.code .id, -pre.code .rubyid_to_i pre.code .rubyid_each { color: #0085FF; } -pre.code .comment { color: #0066FF; } -pre.code .const, pre.code .constant { color: #585CF6; } -pre.code .label, -pre.code .symbol { color: #C5060B; } -pre.code .kw, -pre.code .rubyid_require, -pre.code .rubyid_extend, -pre.code .rubyid_include { color: #0000FF; } -pre.code .ivar { color: #318495; } -pre.code .gvar, -pre.code .rubyid_backref, -pre.code .rubyid_nth_ref { color: #6D79DE; } -pre.code .regexp, .dregexp { color: #036A07; } -pre.code a { border-bottom: 1px dotted #bbf; } -/* inline code */ -*:not(pre) > code { - padding: 1px 3px 1px 3px; - border: 1px solid #E1E1E8; - background: #F7F7F9; - border-radius: 4px; -} - -/* Color fix for links */ -#content .summary_desc pre.code .id > .object_link a, /* identifier */ -#content .docstring pre.code .id > .object_link a { color: #0085FF; } -#content .summary_desc pre.code .const > .object_link a, /* constant */ -#content .docstring pre.code .const > .object_link a { color: #585CF6; } diff --git a/docs/file.README.html b/docs/file.README.html deleted file mode 100644 index dea57474f..000000000 --- a/docs/file.README.html +++ /dev/null @@ -1,546 +0,0 @@ - - - - - - - File: README - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
      - - -

      SidekiqUniqueJobs Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs Build Status Code Climate Test Coverage

      - -

      Table of contents

      - - - -

      Introduction

      - -

      The goal of this gem is to ensure your Sidekiq jobs are unique. We do this by creating unique keys in Redis based on how you configure uniqueness.

      - -

      Documentation

      - -

      This is the documentation for the master branch. You can find the documentation for each release by navigating to its tag: https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10.

      - -

      Below are links to the latest major versions (4 & 5):

      - - - -

      Requirements

      - -

      See https://github.com/mperham/sidekiq#requirements for what is required. Starting from 5.0.0 only sidekiq >= 4 is supported and support for MRI <= 2.1 is dropped. ActiveJob is not supported

      - -

      Version 6 requires Redis >= 3 and pure Sidekiq, no ActiveJob supported anymore. See About ActiveJob for why.

      - -

      Installation

      - -

      Add this line to your application's Gemfile:

      - -
      gem 'sidekiq-unique-jobs'
      -
      - -

      And then execute:

      - -
      $ bundle
      -
      - -

      Or install it yourself as:

      - -
      $ gem install sidekiq-unique-jobs
      -
      - -

      Support Me

      - -

      Want to show me some ❤️ for the hard work I do on this gem? You can use the following PayPal link https://paypal.me/mhenrixon. Any amount is welcome and let me tell you it feels good to be appreciated. Even a dollar makes me super excited about all of this.

      - -

      General Information

      - -

      See Interaction w/ Sidekiq on how the gem interacts with Sidekiq.

      - -

      See Locking & Unlocking for an overview of the differences on when the various lock types are locked and unlocked.

      - -

      Options

      - -

      Lock Expiration

      - -

      This is probably not the configuration option you want...

      - -

      Since the client and the server are disconnected and not running inside the same process, setting a lock expiration is probably not what you want. Any keys that are used by this gem WILL be removed at the time of the expiration. For jobs that are scheduled in the future the key will expire when that job is scheduled + whatever expiration you have set.

      - -

      In previous versions there was a default expiration of 30 minutes which didn't work for a lot of long running jobs. Since version 6 there will be no expiration of any jobs from the default configuration. Please don't use lock_expiration unless you really know what you are doing.

      - -
      sidekiq_options lock_expiration: nil # default - don't expire keys
      -sidekiq_options lock_expiration: 20.days # expire this lock in 20 days
      -
      - -

      Lock Timeout

      - -

      This is the timeout (how long to wait) when creating the lock. By default we don't use a timeout so we won't wait for the lock to be created. If you want it is possible to set this like below.

      - -
      sidekiq_options lock_timeout: 0 # default - don't wait at all
      -sidekiq_options lock_timeout: 5 # wait 5 seconds
      -sidekiq_options lock_timeout: nil # lock indefinitely, this process won't continue until it gets a lock. VERY DANGEROUS!!
      -
      - -

      Unique Across Queues

      - -

      This configuration option is slightly misleading. It doesn't disregard the queue on other jobs. Just on itself, this means that a worker that might schedule jobs into multiple queues will be able to have uniqueness enforced on all queues it is pushed to.

      - -
      class Worker
      -  include Sidekiq::Worker
      -
      -  sidekiq_options unique_across_queues: true, queue: 'default'
      -
      -  def perform(args); end
      -end
      -
      - -

      Now if you push override the queue with Worker.set(queue: 'another').perform_async(1) it will still be considered unique when compared to Worker.perform_async(1) (that was actually pushed to the queue default).

      - -

      Unique Across Workers

      - -

      This configuration option is slightly misleading. It doesn't disregard the worker class on other jobs. Just on itself, this means that a worker that the worker class won't be used for generating the unique digest. The only way this option really makes sense is when you want to have uniqueness between two different worker classes.

      - -
      class WorkerOne
      -  include Sidekiq::Worker
      -
      -  sidekiq_options unique_across_workers: true, queue: 'default'
      -
      -  def perform(args); end
      -end
      -
      -class WorkerTwo
      -  include Sidekiq::Worker
      -
      -  sidekiq_options unique_across_workers: true, queue: 'default'
      -
      -  def perform(args); end
      -end
      -
      -
      -WorkerOne.perform_async(1) 
      -# => 'the jobs unique id'
      -
      -WorkerTwo.perform_async(1) 
      -# => nil because WorkerOne just stole the lock
      -
      - -

      Locks

      - -

      Until Executing

      - -

      Locks from when the client pushes the job to the queue. Will be unlocked before the server starts processing the job.

      - -

      NOTE this is probably not so good for jobs that shouldn't be running simultaneously (aka slow jobs).

      - -
      sidekiq_options lock: :until_executing
      -
      - -

      Until Executed

      - -

      Locks from when the client pushes the job to the queue. Will be unlocked when the server has successfully processed the job.

      - -
      sidekiq_options lock: :until_executed
      -
      - -

      Until Timeout

      - -

      Locks from when the client pushes the job to the queue. Will be unlocked when the specified timeout has been reached.

      - -
      sidekiq_options lock: :until_expired
      -
      - -

      Unique Until And While Executing

      - -

      Locks when the client pushes the job to the queue. The queue will be unlocked when the server starts processing the job. The server then goes on to creating a runtime lock for the job to prevent simultaneous jobs from being executed. As soon as the server starts processing a job, the client can push the same job to the queue.

      - -
      sidekiq_options lock: :until_and_while_executing
      -
      - -

      While Executing

      - -

      With this lock type it is possible to put any number of these jobs on the queue, but as the server pops the job from the queue it will create a lock and then wait until other locks are done processing. It looks like multiple jobs are running at the same time but in fact the second job will only be waiting for the first job to finish.

      - -

      NOTE Unless this job is configured with a lock_timeout: nil or lock_timeout: > 0 then all jobs that are attempted to be executed will just be dropped without waiting.

      - -
      sidekiq_options lock: :while_executing, lock_timeout: nil
      -
      - -

      There is an example of this to try it out in the rails_example application. Run foreman start in the root of the directory and open the url: localhost:5000/work/duplicate_while_executing.

      - -

      In the console you should see something like:

      - -
      0:32:24 worker.1 | 2017-04-23T08:32:24.955Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: start
      -10:32:24 worker.1 | 2017-04-23T08:32:24.956Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: start
      -10:32:24 worker.1 | 2017-04-23T08:32:24.957Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: start
      -10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: start
      -10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 WhileExecutingWorker INFO: perform(1, 2)
      -10:32:34 worker.1 | 2017-04-23T08:32:34.964Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: done: 10.009 sec
      -10:32:34 worker.1 | 2017-04-23T08:32:34.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 WhileExecutingWorker INFO: perform(1, 2)
      -10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 WhileExecutingWorker INFO: perform(1, 2)
      -10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: done: 20.009 sec
      -10:32:54 worker.1 | 2017-04-23T08:32:54.970Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f WhileExecutingWorker INFO: perform(1, 2)
      -10:32:54 worker.1 | 2017-04-23T08:32:54.969Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: done: 30.012 sec
      -10:33:04 worker.1 | 2017-04-23T08:33:04.973Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: done: 40.014 sec
      -
      - -

      Conflict Strategy

      - -

      Decides how we handle conflict. We can either reject the job to the dead queue or reschedule it. Both are useful for jobs that absolutely need to run and have been configured to use the lock WhileExecuting that is used only by the sidekiq server process.

      - -

      The last one is log which can be be used with the lock UntilExecuted and UntilExpired. Now we write a log entry saying the job could not be pushed because it is a duplicate of another job with the same arguments

      - -

      Log

      - -

      This strategy is intended to be used with UntilExecuted and UntilExpired. It will log a line about that this is job is a duplicate of another.

      - -

      sidekiq_options lock: :until_executed, on_conflict: :log

      - -

      Raise

      - -

      This strategy is intended to be used with WhileExecuting. Basically it will allow us to let the server process crash with a specific error message and be retried without messing up the Sidekiq stats.

      - -

      sidekiq_options lock: :while_executing, on_conflict: :raise, retry: 10

      - -

      Reject

      - -

      This strategy is intended to be used with WhileExecuting and will push the job to the dead queue on conflict.

      - -

      sidekiq_options lock: :while_executing, on_conflict: :reject

      - -

      Replace

      - -

      This strategy is intended to be used with client locks like UntilExecuted. -It will delete any existing job for these arguments from retry, schedule and -queue and retry the lock again.

      - -

      This is slightly dangerous and should probably only be used for jobs that are -always scheduled in the future. Currently only attempting to retry one time.

      - -

      sidekiq_options lock: :until_executed, on_conflict: :replace

      - -

      Reschedule

      - -

      This strategy is intended to be used with WhileExecuting and will delay the job to be tried again in 5 seconds. This will mess up the sidekiq stats but will prevent exceptions from being logged and confuse your sysadmins.

      - -

      sidekiq_options lock: :while_executing, on_conflict: :reschedule

      - -

      Usage

      - -

      All that is required is that you specifically set the sidekiq option for unique to a valid value like below:

      - -
      sidekiq_options lock: :while_executing
      -
      - -

      Requiring the gem in your gemfile should be sufficient to enable unique jobs.

      - -

      Finer Control over Uniqueness

      - -

      Sometimes it is desired to have a finer control over which arguments are used in determining uniqueness of the job, and others may be transient. For this use-case, you need to define either a unique_args method, or a ruby proc.

      - -

      The unique_args method need to return an array of values to use for uniqueness check.

      - -

      The method or the proc can return a modified version of args without the transient arguments included, as shown below:

      - -
      class UniqueJobWithFilterMethod
      -  include Sidekiq::Worker
      -  sidekiq_options lock: :until_and_while_executing,
      -                  unique_args: :unique_args # this is default and will be used if such a method is defined
      -
      -  def self.unique_args(args)
      -    [ args[0], args[2][:type] ]
      -  end
      -
      -  ...
      -
      -end
      -
      -class UniqueJobWithFilterProc
      -  include Sidekiq::Worker
      -  sidekiq_options lock: :until_executed,
      -                  unique_args: ->(args) { [ args.first ] }
      -
      -  ...
      -
      -end
      -
      - -

      It is also quite possible to ensure different types of unique args based on context. I can't vouch for the below example but see #203 for the discussion.

      - -
      class UniqueJobWithFilterMethod
      -  include Sidekiq::Worker
      -  sidekiq_options lock: :until_and_while_executing, unique_args: :unique_args
      -
      -  def self.unique_args(args)
      -    if Sidekiq::ProcessSet.new.size > 1
      -      # sidekiq runtime; uniqueness for the object (first arg)
      -      args.first
      -    else
      -      # queuing from the app; uniqueness for all params
      -      args
      -    end
      -  end
      -end
      -
      - -

      After Unlock Callback

      - -

      If you need to perform any additional work after the lock has been released you can provide an #after_unlock instance method. The method will be called when the lock has been unlocked. Most times this means after yield but there are two exceptions to that.

      - -

      Exception 1: UntilExecuting unlocks and calls back before yielding. -Exception 2: UntilExpired expires eventually, no after_unlock hook is called.

      - -
      class UniqueJobWithFilterMethod
      -  include Sidekiq::Worker
      -  sidekiq_options lock: :while_executing,
      -
      -  def after_unlock
      -   # block has yielded and lock is released
      -  end
      -  ...
      -end.
      -
      - -

      Logging

      - -

      To see logging in sidekiq when duplicate payload has been filtered out you can enable on a per worker basis using the sidekiq options. The default value is false

      - -
      class UniqueJobWithFilterMethod
      -  include Sidekiq::Worker
      -  sidekiq_options lock: :while_executing,
      -                  log_duplicate_payload: true
      -
      -  ...
      -
      -end
      -
      - -

      Cleanup Dead Locks

      - -

      For sidekiq versions before 5.1 a sidekiq_retries_exhausted block is required per worker class.

      - -
      class MyWorker
      -  sidekiq_retries_exhausted do |msg, _ex|
      -    SidekiqUniqueJobs::Digests.del(digest: msg['unique_digest']) if msg['unique_digest']
      -  end
      -end
      -
      - -

      Starting in v5.1, Sidekiq can also fire a global callback when a job dies:

      - -
      # this goes in your initializer
      -Sidekiq.configure_server do |config|
      -  config.death_handlers << ->(job, _ex) do
      -    SidekiqUniqueJobs::Digests.del(digest: job['unique_digest']) if job['unique_digest']
      -  end
      -end
      -
      - -

      Debugging

      - -

      There are several ways of removing keys that are stuck. The prefered way is by using the unique extension to Sidekiq::Web. The old console and command line versions still work but might be deprecated in the future. It is better to search for the digest itself and delete the keys matching that digest.

      - -

      Sidekiq Web

      - -

      To use the web extension you need to require it in your routes.

      - -
      # app/config/routes.rb
      -require 'sidekiq_unique_jobs/web'
      -mount Sidekiq::Web, at: '/sidekiq'
      -
      - -

      There is no need to require 'sidekiq/web' since sidekiq_unique_jobs/web -already does this.

      - -

      To filter/search for keys we can use the wildcard *. If we have a unique digest 'uniquejobs:9e9b5ce5d423d3ea470977004b50ff84 we can search for it by enter *ff84 and it should return all digests that end with ff84.

      - -

      Show Unique Digests

      - -

      Unique Digests

      - -

      Show keys for digest

      - -

      Unique Digests

      - -

      Communication

      - -

      There is a Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs for praise or scorn. This would be a good place to have lengthy discuss or brilliant suggestions or simply just nudge me if I forget about anything.

      - -

      Testing

      - -

      This has been probably the most confusing part of this gem. People get really confused with how unreliable the unique jobs have been. I there for decided to do what Mike is doing for sidekiq enterprise. Read the section about unique jobs.

      - -

      https://www.dailydrip.com/topics/sidekiq/drips/sidekiq-enterprise-unique-jobs

      - -
      SidekiqUniqueJobs.configure do |config|
      -  config.enabled = !Rails.env.test?
      -end
      -
      - -

      If you truly wanted to test the sidekiq client push you could do something like below. Note that it will only work for the jobs that lock when the client pushes the job to redis (UntilExecuted, UntilAndWhileExecuting and UntilExpired).

      - -
      RSpec.describe Workers::CoolOne do
      -  before do
      -    SidekiqUniqueJobs.config.enabled = false
      -  end
      -
      -  # ... your tests that don't test uniqueness
      -
      -  context 'when Sidekiq::Testing.disabled?' do
      -    before do
      -      Sidekiq::Testing.disable!
      -      Sidekiq.redis(&:flushdb)
      -    end
      -
      -    after do
      -      Sidekiq.redis(&:flushdb)
      -    end
      -
      -    it 'prevents duplicate jobs from being scheduled' do
      -      SidekiqUniqueJobs.use_config(enabled: true) do
      -        expect(described_class.perform_in(3600, 1)).not_to eq(nil)
      -        expect(described_class.perform_async(1)).to eq(nil)
      -      end
      -    end
      -  end
      -end
      -
      - -

      I would strongly suggest you let this gem test uniqueness. If you care about how the gem is integration tested have a look at the following specs:

      - - - -

      Contributing

      - -
        -
      1. Fork it
      2. -
      3. Create your feature branch (git checkout -b my-new-feature)
      4. -
      5. Commit your changes (git commit -am 'Add some feature')
      6. -
      7. Push to the branch (git push origin my-new-feature)
      8. -
      9. Create new Pull Request
      10. -
      - -

      Contributors

      - -

      You can find a list of contributors over on https://github.com/mhenrixon/sidekiq-unique-jobs/graphs/contributors

      -
      - - - -
      - - \ No newline at end of file diff --git a/docs/file_list.html b/docs/file_list.html deleted file mode 100644 index b98a664b6..000000000 --- a/docs/file_list.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - File List - - - -
      -
      -

      File List

      - - - -
      - - -
      - - diff --git a/docs/frames.html b/docs/frames.html deleted file mode 100644 index 1529bf66b..000000000 --- a/docs/frames.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Documentation by YARD 0.9.18 - - - - diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 33ed6467d..000000000 --- a/docs/index.html +++ /dev/null @@ -1,546 +0,0 @@ - - - - - - - File: README - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
      - - -

      SidekiqUniqueJobs Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs Build Status Code Climate Test Coverage

      - -

      Table of contents

      - - - -

      Introduction

      - -

      The goal of this gem is to ensure your Sidekiq jobs are unique. We do this by creating unique keys in Redis based on how you configure uniqueness.

      - -

      Documentation

      - -

      This is the documentation for the master branch. You can find the documentation for each release by navigating to its tag: https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10.

      - -

      Below are links to the latest major versions (4 & 5):

      - - - -

      Requirements

      - -

      See https://github.com/mperham/sidekiq#requirements for what is required. Starting from 5.0.0 only sidekiq >= 4 is supported and support for MRI <= 2.1 is dropped. ActiveJob is not supported

      - -

      Version 6 requires Redis >= 3 and pure Sidekiq, no ActiveJob supported anymore. See About ActiveJob for why.

      - -

      Installation

      - -

      Add this line to your application's Gemfile:

      - -
      gem 'sidekiq-unique-jobs'
      -
      - -

      And then execute:

      - -
      $ bundle
      -
      - -

      Or install it yourself as:

      - -
      $ gem install sidekiq-unique-jobs
      -
      - -

      Support Me

      - -

      Want to show me some ❤️ for the hard work I do on this gem? You can use the following PayPal link https://paypal.me/mhenrixon. Any amount is welcome and let me tell you it feels good to be appreciated. Even a dollar makes me super excited about all of this.

      - -

      General Information

      - -

      See Interaction w/ Sidekiq on how the gem interacts with Sidekiq.

      - -

      See Locking & Unlocking for an overview of the differences on when the various lock types are locked and unlocked.

      - -

      Options

      - -

      Lock Expiration

      - -

      This is probably not the configuration option you want...

      - -

      Since the client and the server are disconnected and not running inside the same process, setting a lock expiration is probably not what you want. Any keys that are used by this gem WILL be removed at the time of the expiration. For jobs that are scheduled in the future the key will expire when that job is scheduled + whatever expiration you have set.

      - -

      In previous versions there was a default expiration of 30 minutes which didn't work for a lot of long running jobs. Since version 6 there will be no expiration of any jobs from the default configuration. Please don't use lock_expiration unless you really know what you are doing.

      - -
      sidekiq_options lock_expiration: nil # default - don't expire keys
      -sidekiq_options lock_expiration: 20.days # expire this lock in 20 days
      -
      - -

      Lock Timeout

      - -

      This is the timeout (how long to wait) when creating the lock. By default we don't use a timeout so we won't wait for the lock to be created. If you want it is possible to set this like below.

      - -
      sidekiq_options lock_timeout: 0 # default - don't wait at all
      -sidekiq_options lock_timeout: 5 # wait 5 seconds
      -sidekiq_options lock_timeout: nil # lock indefinitely, this process won't continue until it gets a lock. VERY DANGEROUS!!
      -
      - -

      Unique Across Queues

      - -

      This configuration option is slightly misleading. It doesn't disregard the queue on other jobs. Just on itself, this means that a worker that might schedule jobs into multiple queues will be able to have uniqueness enforced on all queues it is pushed to.

      - -
      class Worker
      -  include Sidekiq::Worker
      -
      -  sidekiq_options unique_across_queues: true, queue: 'default'
      -
      -  def perform(args); end
      -end
      -
      - -

      Now if you push override the queue with Worker.set(queue: 'another').perform_async(1) it will still be considered unique when compared to Worker.perform_async(1) (that was actually pushed to the queue default).

      - -

      Unique Across Workers

      - -

      This configuration option is slightly misleading. It doesn't disregard the worker class on other jobs. Just on itself, this means that a worker that the worker class won't be used for generating the unique digest. The only way this option really makes sense is when you want to have uniqueness between two different worker classes.

      - -
      class WorkerOne
      -  include Sidekiq::Worker
      -
      -  sidekiq_options unique_across_workers: true, queue: 'default'
      -
      -  def perform(args); end
      -end
      -
      -class WorkerTwo
      -  include Sidekiq::Worker
      -
      -  sidekiq_options unique_across_workers: true, queue: 'default'
      -
      -  def perform(args); end
      -end
      -
      -
      -WorkerOne.perform_async(1) 
      -# => 'the jobs unique id'
      -
      -WorkerTwo.perform_async(1) 
      -# => nil because WorkerOne just stole the lock
      -
      - -

      Locks

      - -

      Until Executing

      - -

      Locks from when the client pushes the job to the queue. Will be unlocked before the server starts processing the job.

      - -

      NOTE this is probably not so good for jobs that shouldn't be running simultaneously (aka slow jobs).

      - -
      sidekiq_options lock: :until_executing
      -
      - -

      Until Executed

      - -

      Locks from when the client pushes the job to the queue. Will be unlocked when the server has successfully processed the job.

      - -
      sidekiq_options lock: :until_executed
      -
      - -

      Until Timeout

      - -

      Locks from when the client pushes the job to the queue. Will be unlocked when the specified timeout has been reached.

      - -
      sidekiq_options lock: :until_expired
      -
      - -

      Unique Until And While Executing

      - -

      Locks when the client pushes the job to the queue. The queue will be unlocked when the server starts processing the job. The server then goes on to creating a runtime lock for the job to prevent simultaneous jobs from being executed. As soon as the server starts processing a job, the client can push the same job to the queue.

      - -
      sidekiq_options lock: :until_and_while_executing
      -
      - -

      While Executing

      - -

      With this lock type it is possible to put any number of these jobs on the queue, but as the server pops the job from the queue it will create a lock and then wait until other locks are done processing. It looks like multiple jobs are running at the same time but in fact the second job will only be waiting for the first job to finish.

      - -

      NOTE Unless this job is configured with a lock_timeout: nil or lock_timeout: > 0 then all jobs that are attempted to be executed will just be dropped without waiting.

      - -
      sidekiq_options lock: :while_executing, lock_timeout: nil
      -
      - -

      There is an example of this to try it out in the rails_example application. Run foreman start in the root of the directory and open the url: localhost:5000/work/duplicate_while_executing.

      - -

      In the console you should see something like:

      - -
      0:32:24 worker.1 | 2017-04-23T08:32:24.955Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: start
      -10:32:24 worker.1 | 2017-04-23T08:32:24.956Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: start
      -10:32:24 worker.1 | 2017-04-23T08:32:24.957Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: start
      -10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: start
      -10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 WhileExecutingWorker INFO: perform(1, 2)
      -10:32:34 worker.1 | 2017-04-23T08:32:34.964Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: done: 10.009 sec
      -10:32:34 worker.1 | 2017-04-23T08:32:34.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 WhileExecutingWorker INFO: perform(1, 2)
      -10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 WhileExecutingWorker INFO: perform(1, 2)
      -10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: done: 20.009 sec
      -10:32:54 worker.1 | 2017-04-23T08:32:54.970Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f WhileExecutingWorker INFO: perform(1, 2)
      -10:32:54 worker.1 | 2017-04-23T08:32:54.969Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: done: 30.012 sec
      -10:33:04 worker.1 | 2017-04-23T08:33:04.973Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: done: 40.014 sec
      -
      - -

      Conflict Strategy

      - -

      Decides how we handle conflict. We can either reject the job to the dead queue or reschedule it. Both are useful for jobs that absolutely need to run and have been configured to use the lock WhileExecuting that is used only by the sidekiq server process.

      - -

      The last one is log which can be be used with the lock UntilExecuted and UntilExpired. Now we write a log entry saying the job could not be pushed because it is a duplicate of another job with the same arguments

      - -

      Log

      - -

      This strategy is intended to be used with UntilExecuted and UntilExpired. It will log a line about that this is job is a duplicate of another.

      - -

      sidekiq_options lock: :until_executed, on_conflict: :log

      - -

      Raise

      - -

      This strategy is intended to be used with WhileExecuting. Basically it will allow us to let the server process crash with a specific error message and be retried without messing up the Sidekiq stats.

      - -

      sidekiq_options lock: :while_executing, on_conflict: :raise, retry: 10

      - -

      Reject

      - -

      This strategy is intended to be used with WhileExecuting and will push the job to the dead queue on conflict.

      - -

      sidekiq_options lock: :while_executing, on_conflict: :reject

      - -

      Replace

      - -

      This strategy is intended to be used with client locks like UntilExecuted. -It will delete any existing job for these arguments from retry, schedule and -queue and retry the lock again.

      - -

      This is slightly dangerous and should probably only be used for jobs that are -always scheduled in the future. Currently only attempting to retry one time.

      - -

      sidekiq_options lock: :until_executed, on_conflict: :replace

      - -

      Reschedule

      - -

      This strategy is intended to be used with WhileExecuting and will delay the job to be tried again in 5 seconds. This will mess up the sidekiq stats but will prevent exceptions from being logged and confuse your sysadmins.

      - -

      sidekiq_options lock: :while_executing, on_conflict: :reschedule

      - -

      Usage

      - -

      All that is required is that you specifically set the sidekiq option for unique to a valid value like below:

      - -
      sidekiq_options lock: :while_executing
      -
      - -

      Requiring the gem in your gemfile should be sufficient to enable unique jobs.

      - -

      Finer Control over Uniqueness

      - -

      Sometimes it is desired to have a finer control over which arguments are used in determining uniqueness of the job, and others may be transient. For this use-case, you need to define either a unique_args method, or a ruby proc.

      - -

      The unique_args method need to return an array of values to use for uniqueness check.

      - -

      The method or the proc can return a modified version of args without the transient arguments included, as shown below:

      - -
      class UniqueJobWithFilterMethod
      -  include Sidekiq::Worker
      -  sidekiq_options lock: :until_and_while_executing,
      -                  unique_args: :unique_args # this is default and will be used if such a method is defined
      -
      -  def self.unique_args(args)
      -    [ args[0], args[2][:type] ]
      -  end
      -
      -  ...
      -
      -end
      -
      -class UniqueJobWithFilterProc
      -  include Sidekiq::Worker
      -  sidekiq_options lock: :until_executed,
      -                  unique_args: ->(args) { [ args.first ] }
      -
      -  ...
      -
      -end
      -
      - -

      It is also quite possible to ensure different types of unique args based on context. I can't vouch for the below example but see #203 for the discussion.

      - -
      class UniqueJobWithFilterMethod
      -  include Sidekiq::Worker
      -  sidekiq_options lock: :until_and_while_executing, unique_args: :unique_args
      -
      -  def self.unique_args(args)
      -    if Sidekiq::ProcessSet.new.size > 1
      -      # sidekiq runtime; uniqueness for the object (first arg)
      -      args.first
      -    else
      -      # queuing from the app; uniqueness for all params
      -      args
      -    end
      -  end
      -end
      -
      - -

      After Unlock Callback

      - -

      If you need to perform any additional work after the lock has been released you can provide an #after_unlock instance method. The method will be called when the lock has been unlocked. Most times this means after yield but there are two exceptions to that.

      - -

      Exception 1: UntilExecuting unlocks and calls back before yielding. -Exception 2: UntilExpired expires eventually, no after_unlock hook is called.

      - -
      class UniqueJobWithFilterMethod
      -  include Sidekiq::Worker
      -  sidekiq_options lock: :while_executing,
      -
      -  def after_unlock
      -   # block has yielded and lock is released
      -  end
      -  ...
      -end.
      -
      - -

      Logging

      - -

      To see logging in sidekiq when duplicate payload has been filtered out you can enable on a per worker basis using the sidekiq options. The default value is false

      - -
      class UniqueJobWithFilterMethod
      -  include Sidekiq::Worker
      -  sidekiq_options lock: :while_executing,
      -                  log_duplicate_payload: true
      -
      -  ...
      -
      -end
      -
      - -

      Cleanup Dead Locks

      - -

      For sidekiq versions before 5.1 a sidekiq_retries_exhausted block is required per worker class.

      - -
      class MyWorker
      -  sidekiq_retries_exhausted do |msg, _ex|
      -    SidekiqUniqueJobs::Digests.del(digest: msg['unique_digest']) if msg['unique_digest']
      -  end
      -end
      -
      - -

      Starting in v5.1, Sidekiq can also fire a global callback when a job dies:

      - -
      # this goes in your initializer
      -Sidekiq.configure_server do |config|
      -  config.death_handlers << ->(job, _ex) do
      -    SidekiqUniqueJobs::Digests.del(digest: job['unique_digest']) if job['unique_digest']
      -  end
      -end
      -
      - -

      Debugging

      - -

      There are several ways of removing keys that are stuck. The prefered way is by using the unique extension to Sidekiq::Web. The old console and command line versions still work but might be deprecated in the future. It is better to search for the digest itself and delete the keys matching that digest.

      - -

      Sidekiq Web

      - -

      To use the web extension you need to require it in your routes.

      - -
      # app/config/routes.rb
      -require 'sidekiq_unique_jobs/web'
      -mount Sidekiq::Web, at: '/sidekiq'
      -
      - -

      There is no need to require 'sidekiq/web' since sidekiq_unique_jobs/web -already does this.

      - -

      To filter/search for keys we can use the wildcard *. If we have a unique digest 'uniquejobs:9e9b5ce5d423d3ea470977004b50ff84 we can search for it by enter *ff84 and it should return all digests that end with ff84.

      - -

      Show Unique Digests

      - -

      Unique Digests

      - -

      Show keys for digest

      - -

      Unique Digests

      - -

      Communication

      - -

      There is a Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs for praise or scorn. This would be a good place to have lengthy discuss or brilliant suggestions or simply just nudge me if I forget about anything.

      - -

      Testing

      - -

      This has been probably the most confusing part of this gem. People get really confused with how unreliable the unique jobs have been. I there for decided to do what Mike is doing for sidekiq enterprise. Read the section about unique jobs.

      - -

      https://www.dailydrip.com/topics/sidekiq/drips/sidekiq-enterprise-unique-jobs

      - -
      SidekiqUniqueJobs.configure do |config|
      -  config.enabled = !Rails.env.test?
      -end
      -
      - -

      If you truly wanted to test the sidekiq client push you could do something like below. Note that it will only work for the jobs that lock when the client pushes the job to redis (UntilExecuted, UntilAndWhileExecuting and UntilExpired).

      - -
      RSpec.describe Workers::CoolOne do
      -  before do
      -    SidekiqUniqueJobs.config.enabled = false
      -  end
      -
      -  # ... your tests that don't test uniqueness
      -
      -  context 'when Sidekiq::Testing.disabled?' do
      -    before do
      -      Sidekiq::Testing.disable!
      -      Sidekiq.redis(&:flushdb)
      -    end
      -
      -    after do
      -      Sidekiq.redis(&:flushdb)
      -    end
      -
      -    it 'prevents duplicate jobs from being scheduled' do
      -      SidekiqUniqueJobs.use_config(enabled: true) do
      -        expect(described_class.perform_in(3600, 1)).not_to eq(nil)
      -        expect(described_class.perform_async(1)).to eq(nil)
      -      end
      -    end
      -  end
      -end
      -
      - -

      I would strongly suggest you let this gem test uniqueness. If you care about how the gem is integration tested have a look at the following specs:

      - - - -

      Contributing

      - -
        -
      1. Fork it
      2. -
      3. Create your feature branch (git checkout -b my-new-feature)
      4. -
      5. Commit your changes (git commit -am 'Add some feature')
      6. -
      7. Push to the branch (git push origin my-new-feature)
      8. -
      9. Create new Pull Request
      10. -
      - -

      Contributors

      - -

      You can find a list of contributors over on https://github.com/mhenrixon/sidekiq-unique-jobs/graphs/contributors

      -
      - - - -
      - - \ No newline at end of file diff --git a/docs/js/app.js b/docs/js/app.js deleted file mode 100644 index c3f326d3c..000000000 --- a/docs/js/app.js +++ /dev/null @@ -1,292 +0,0 @@ -(function() { - -var localStorage = {}, sessionStorage = {}; -try { localStorage = window.localStorage; } catch (e) { } -try { sessionStorage = window.sessionStorage; } catch (e) { } - -function createSourceLinks() { - $('.method_details_list .source_code'). - before("[View source]"); - $('.toggleSource').toggle(function() { - $(this).parent().nextAll('.source_code').slideDown(100); - $(this).text("Hide source"); - }, - function() { - $(this).parent().nextAll('.source_code').slideUp(100); - $(this).text("View source"); - }); -} - -function createDefineLinks() { - var tHeight = 0; - $('.defines').after(" more..."); - $('.toggleDefines').toggle(function() { - tHeight = $(this).parent().prev().height(); - $(this).prev().css('display', 'inline'); - $(this).parent().prev().height($(this).parent().height()); - $(this).text("(less)"); - }, - function() { - $(this).prev().hide(); - $(this).parent().prev().height(tHeight); - $(this).text("more..."); - }); -} - -function createFullTreeLinks() { - var tHeight = 0; - $('.inheritanceTree').toggle(function() { - tHeight = $(this).parent().prev().height(); - $(this).parent().toggleClass('showAll'); - $(this).text("(hide)"); - $(this).parent().prev().height($(this).parent().height()); - }, - function() { - $(this).parent().toggleClass('showAll'); - $(this).parent().prev().height(tHeight); - $(this).text("show all"); - }); -} - -function searchFrameButtons() { - $('.full_list_link').click(function() { - toggleSearchFrame(this, $(this).attr('href')); - return false; - }); - window.addEventListener('message', function(e) { - if (e.data === 'navEscape') { - $('#nav').slideUp(100); - $('#search a').removeClass('active inactive'); - $(window).focus(); - } - }); - - $(window).resize(function() { - if ($('#search:visible').length === 0) { - $('#nav').removeAttr('style'); - $('#search a').removeClass('active inactive'); - $(window).focus(); - } - }); -} - -function toggleSearchFrame(id, link) { - var frame = $('#nav'); - $('#search a').removeClass('active').addClass('inactive'); - if (frame.attr('src') === link && frame.css('display') !== "none") { - frame.slideUp(100); - $('#search a').removeClass('active inactive'); - } - else { - $(id).addClass('active').removeClass('inactive'); - if (frame.attr('src') !== link) frame.attr('src', link); - frame.slideDown(100); - } -} - -function linkSummaries() { - $('.summary_signature').click(function() { - document.location = $(this).find('a').attr('href'); - }); -} - -function summaryToggle() { - $('.summary_toggle').click(function(e) { - e.preventDefault(); - localStorage.summaryCollapsed = $(this).text(); - $('.summary_toggle').each(function() { - $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); - var next = $(this).parent().parent().nextAll('ul.summary').first(); - if (next.hasClass('compact')) { - next.toggle(); - next.nextAll('ul.summary').first().toggle(); - } - else if (next.hasClass('summary')) { - var list = $('
        '); - list.html(next.html()); - list.find('.summary_desc, .note').remove(); - list.find('a').each(function() { - $(this).html($(this).find('strong').html()); - $(this).parent().html($(this)[0].outerHTML); - }); - next.before(list); - next.toggle(); - } - }); - return false; - }); - if (localStorage.summaryCollapsed == "collapse") { - $('.summary_toggle').first().click(); - } else { localStorage.summaryCollapsed = "expand"; } -} - -function constantSummaryToggle() { - $('.constants_summary_toggle').click(function(e) { - e.preventDefault(); - localStorage.summaryCollapsed = $(this).text(); - $('.constants_summary_toggle').each(function() { - $(this).text($(this).text() == "collapse" ? "expand" : "collapse"); - var next = $(this).parent().parent().nextAll('dl.constants').first(); - if (next.hasClass('compact')) { - next.toggle(); - next.nextAll('dl.constants').first().toggle(); - } - else if (next.hasClass('constants')) { - var list = $('
        '); - list.html(next.html()); - list.find('dt').each(function() { - $(this).addClass('summary_signature'); - $(this).text( $(this).text().split('=')[0]); - if ($(this).has(".deprecated").length) { - $(this).addClass('deprecated'); - }; - }); - // Add the value of the constant as "Tooltip" to the summary object - list.find('pre.code').each(function() { - console.log($(this).parent()); - var dt_element = $(this).parent().prev(); - var tooltip = $(this).text(); - if (dt_element.hasClass("deprecated")) { - tooltip = 'Deprecated. ' + tooltip; - }; - dt_element.attr('title', tooltip); - }); - list.find('.docstring, .tags, dd').remove(); - next.before(list); - next.toggle(); - } - }); - return false; - }); - if (localStorage.summaryCollapsed == "collapse") { - $('.constants_summary_toggle').first().click(); - } else { localStorage.summaryCollapsed = "expand"; } -} - -function generateTOC() { - if ($('#filecontents').length === 0) return; - var _toc = $('
          '); - var show = false; - var toc = _toc; - var counter = 0; - var tags = ['h2', 'h3', 'h4', 'h5', 'h6']; - var i; - if ($('#filecontents h1').length > 1) tags.unshift('h1'); - for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; } - var lastTag = parseInt(tags[0][1], 10); - $(tags.join(', ')).each(function() { - if ($(this).parents('.method_details .docstring').length != 0) return; - if (this.id == "filecontents") return; - show = true; - var thisTag = parseInt(this.tagName[1], 10); - if (this.id.length === 0) { - var proposedId = $(this).attr('toc-id'); - if (typeof(proposedId) != "undefined") this.id = proposedId; - else { - var proposedId = $(this).text().replace(/[^a-z0-9-]/ig, '_'); - if ($('#' + proposedId).length > 0) { proposedId += counter; counter++; } - this.id = proposedId; - } - } - if (thisTag > lastTag) { - for (i = 0; i < thisTag - lastTag; i++) { - var tmp = $('
            '); toc.append(tmp); toc = tmp; - } - } - if (thisTag < lastTag) { - for (i = 0; i < lastTag - thisTag; i++) toc = toc.parent(); - } - var title = $(this).attr('toc-title'); - if (typeof(title) == "undefined") title = $(this).text(); - toc.append('
          1. ' + title + '
          2. '); - lastTag = thisTag; - }); - if (!show) return; - html = ''; - $('#content').prepend(html); - $('#toc').append(_toc); - $('#toc .hide_toc').toggle(function() { - $('#toc .top').slideUp('fast'); - $('#toc').toggleClass('hidden'); - $('#toc .title small').toggle(); - }, function() { - $('#toc .top').slideDown('fast'); - $('#toc').toggleClass('hidden'); - $('#toc .title small').toggle(); - }); -} - -function navResizeFn(e) { - if (e.which !== 1) { - navResizeFnStop(); - return; - } - - sessionStorage.navWidth = e.pageX.toString(); - $('.nav_wrap').css('width', e.pageX); - $('.nav_wrap').css('-ms-flex', 'inherit'); -} - -function navResizeFnStop() { - $(window).unbind('mousemove', navResizeFn); - window.removeEventListener('message', navMessageFn, false); -} - -function navMessageFn(e) { - if (e.data.action === 'mousemove') navResizeFn(e.data.event); - if (e.data.action === 'mouseup') navResizeFnStop(); -} - -function navResizer() { - $('#resizer').mousedown(function(e) { - e.preventDefault(); - $(window).mousemove(navResizeFn); - window.addEventListener('message', navMessageFn, false); - }); - $(window).mouseup(navResizeFnStop); - - if (sessionStorage.navWidth) { - navResizeFn({which: 1, pageX: parseInt(sessionStorage.navWidth, 10)}); - } -} - -function navExpander() { - var done = false, timer = setTimeout(postMessage, 500); - function postMessage() { - if (done) return; - clearTimeout(timer); - var opts = { action: 'expand', path: pathId }; - document.getElementById('nav').contentWindow.postMessage(opts, '*'); - done = true; - } - - window.addEventListener('message', function(event) { - if (event.data === 'navReady') postMessage(); - return false; - }, false); -} - -function mainFocus() { - var hash = window.location.hash; - if (hash !== '' && $(hash)[0]) { - $(hash)[0].scrollIntoView(); - } - - setTimeout(function() { $('#main').focus(); }, 10); -} - -$(document).ready(function() { - navResizer(); - navExpander(); - createSourceLinks(); - createDefineLinks(); - createFullTreeLinks(); - searchFrameButtons(); - linkSummaries(); - summaryToggle(); - constantSummaryToggle(); - generateTOC(); - mainFocus(); -}); - -})(); diff --git a/docs/js/full_list.js b/docs/js/full_list.js deleted file mode 100644 index 3e4afd6f4..000000000 --- a/docs/js/full_list.js +++ /dev/null @@ -1,216 +0,0 @@ -(function() { - -var $clicked = $(null); -var searchTimeout = null; -var searchCache = []; -var caseSensitiveMatch = false; -var ignoreKeyCodeMin = 8; -var ignoreKeyCodeMax = 46; -var commandKey = 91; - -RegExp.escape = function(text) { - return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); -} - -function escapeShortcut() { - $(document).keydown(function(evt) { - if (evt.which == 27) { - window.parent.postMessage('navEscape', '*'); - } - }); -} - -function navResizer() { - $(window).mousemove(function(e) { - window.parent.postMessage({ - action: 'mousemove', event: {pageX: e.pageX, which: e.which} - }, '*'); - }).mouseup(function(e) { - window.parent.postMessage({action: 'mouseup'}, '*'); - }); - window.parent.postMessage("navReady", "*"); -} - -function clearSearchTimeout() { - clearTimeout(searchTimeout); - searchTimeout = null; -} - -function enableLinks() { - // load the target page in the parent window - $('#full_list li').on('click', function(evt) { - $('#full_list li').removeClass('clicked'); - $clicked = $(this); - $clicked.addClass('clicked'); - evt.stopPropagation(); - - if (evt.target.tagName === 'A') return true; - - var elem = $clicked.find('> .item .object_link a')[0]; - var e = evt.originalEvent; - var newEvent = new MouseEvent(evt.originalEvent.type); - newEvent.initMouseEvent(e.type, e.canBubble, e.cancelable, e.view, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget); - elem.dispatchEvent(newEvent); - evt.preventDefault(); - return false; - }); -} - -function enableToggles() { - // show/hide nested classes on toggle click - $('#full_list a.toggle').on('click', function(evt) { - evt.stopPropagation(); - evt.preventDefault(); - $(this).parent().parent().toggleClass('collapsed'); - highlight(); - }); -} - -function populateSearchCache() { - $('#full_list li .item').each(function() { - var $node = $(this); - var $link = $node.find('.object_link a'); - if ($link.length > 0) { - searchCache.push({ - node: $node, - link: $link, - name: $link.text(), - fullName: $link.attr('title').split(' ')[0] - }); - } - }); -} - -function enableSearch() { - $('#search input').keyup(function(event) { - if (ignoredKeyPress(event)) return; - if (this.value === "") { - clearSearch(); - } else { - performSearch(this.value); - } - }); - - $('#full_list').after(""); -} - -function ignoredKeyPress(event) { - if ( - (event.keyCode > ignoreKeyCodeMin && event.keyCode < ignoreKeyCodeMax) || - (event.keyCode == commandKey) - ) { - return true; - } else { - return false; - } -} - -function clearSearch() { - clearSearchTimeout(); - $('#full_list .found').removeClass('found').each(function() { - var $link = $(this).find('.object_link a'); - $link.text($link.text()); - }); - $('#full_list, #content').removeClass('insearch'); - $clicked.parents().removeClass('collapsed'); - highlight(); -} - -function performSearch(searchString) { - clearSearchTimeout(); - $('#full_list, #content').addClass('insearch'); - $('#noresults').text('').hide(); - partialSearch(searchString, 0); -} - -function partialSearch(searchString, offset) { - var lastRowClass = ''; - var i = null; - for (i = offset; i < Math.min(offset + 50, searchCache.length); i++) { - var item = searchCache[i]; - var searchName = (searchString.indexOf('::') != -1 ? item.fullName : item.name); - var matchString = buildMatchString(searchString); - var matchRegexp = new RegExp(matchString, caseSensitiveMatch ? "" : "i"); - if (searchName.match(matchRegexp) == null) { - item.node.removeClass('found'); - item.link.text(item.link.text()); - } - else { - item.node.addClass('found'); - item.node.removeClass(lastRowClass).addClass(lastRowClass == 'r1' ? 'r2' : 'r1'); - lastRowClass = item.node.hasClass('r1') ? 'r1' : 'r2'; - item.link.html(item.name.replace(matchRegexp, "$&")); - } - } - if(i == searchCache.length) { - searchDone(); - } else { - searchTimeout = setTimeout(function() { - partialSearch(searchString, i); - }, 0); - } -} - -function searchDone() { - searchTimeout = null; - highlight(); - if ($('#full_list li:visible').size() === 0) { - $('#noresults').text('No results were found.').hide().fadeIn(); - } else { - $('#noresults').text('').hide(); - } - $('#content').removeClass('insearch'); -} - -function buildMatchString(searchString, event) { - caseSensitiveMatch = searchString.match(/[A-Z]/) != null; - var regexSearchString = RegExp.escape(searchString); - if (caseSensitiveMatch) { - regexSearchString += "|" + - $.map(searchString.split(''), function(e) { return RegExp.escape(e); }). - join('.+?'); - } - return regexSearchString; -} - -function highlight() { - $('#full_list li:visible').each(function(n) { - $(this).removeClass('even odd').addClass(n % 2 == 0 ? 'odd' : 'even'); - }); -} - -/** - * Expands the tree to the target element and its immediate - * children. - */ -function expandTo(path) { - var $target = $(document.getElementById('object_' + path)); - $target.addClass('clicked'); - $target.removeClass('collapsed'); - $target.parentsUntil('#full_list', 'li').removeClass('collapsed'); - if($target[0]) { - window.scrollTo(window.scrollX, $target.offset().top - 250); - highlight(); - } -} - -function windowEvents(event) { - var msg = event.data; - if (msg.action === "expand") { - expandTo(msg.path); - } - return false; -} - -window.addEventListener("message", windowEvents, false); - -$(document).ready(function() { - escapeShortcut(); - navResizer(); - enableLinks(); - enableToggles(); - populateSearchCache(); - enableSearch(); -}); - -})(); diff --git a/docs/js/jquery.js b/docs/js/jquery.js deleted file mode 100644 index 979ed0824..000000000 --- a/docs/js/jquery.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.7.1 jquery.com | jquery.org/license */ -(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
      a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
      "+""+"
      ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
      t
      ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
      ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; -f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

      ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
      ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
      ","
      "],thead:[1,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],col:[2,"","
      "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
      ","
      "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() -{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
      ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/docs/method_list.html b/docs/method_list.html deleted file mode 100644 index c4963eb8b..000000000 --- a/docs/method_list.html +++ /dev/null @@ -1,1291 +0,0 @@ - - - - - - - - - - - - - - - - - - Method List - - - -
      -
      -

      Method List

      - - - -
      - -
        - - -
      • -
        - #add_uniqueness - SidekiqUniqueJobs::Job -
        -
      • - - -
      • -
        - #add_uniqueness_to_item - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #after_unlock_hook - SidekiqUniqueJobs::SidekiqWorkerMethods -
        -
      • - - -
      • -
        - #all - SidekiqUniqueJobs::Digests -
        -
      • - - -
      • -
        - #available_count - SidekiqUniqueJobs::Locksmith -
        -
      • - - -
      • -
        - banner - SidekiqUniqueJobs::Cli -
        -
      • - - -
      • -
        - #call - SidekiqUniqueJobs::OnConflict::Replace -
        -
      • - - -
      • -
        - #call - SidekiqUniqueJobs::OnConflict::NullStrategy -
        -
      • - - -
      • -
        - #call - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #call - SidekiqUniqueJobs::OnConflict::Reschedule -
        -
      • - - -
      • -
        - #call - SidekiqUniqueJobs::Server::Middleware -
        -
      • - - -
      • -
        - #call - SidekiqUniqueJobs::OnConflict::Raise -
        -
      • - - -
      • -
        - #call - SidekiqUniqueJobs::Client::Middleware -
        -
      • - - -
      • -
        - #call - SidekiqUniqueJobs::OnConflict::Strategy -
        -
      • - - -
      • -
        - call - SidekiqUniqueJobs::Scripts -
        -
      • - - -
      • -
        - #call - SidekiqUniqueJobs::OnConflict::Log -
        -
      • - - -
      • -
        - #clear - Sidekiq::Worker::ClassMethods -
        -
      • - - -
      • -
        - #clear_all_ext - Sidekiq::Worker::Overrides::Testing -
        -
      • - - -
      • -
        - #clear_ext - Sidekiq::JobSet::UniqueExtension -
        -
      • - - -
      • -
        - #clear_ext - Sidekiq::Queue::UniqueExtension -
        -
      • - - -
      • -
        - config - SidekiqUniqueJobs -
        -
      • - - -
      • -
        - configure - SidekiqUniqueJobs -
        -
      • - - -
      • -
        - #configure_client_middleware - SidekiqUniqueJobs::Middleware -
        -
      • - - -
      • -
        - #configure_middleware - SidekiqUniqueJobs::Middleware -
        -
      • - - -
      • -
        - #configure_server_middleware - SidekiqUniqueJobs::Middleware -
        -
      • - - -
      • -
        - #console - SidekiqUniqueJobs::Cli -
        -
      • - - -
      • -
        - #count - SidekiqUniqueJobs::Digests -
        -
      • - - -
      • -
        - #cparams - SidekiqUniqueJobs::Web::Helpers -
        -
      • - - -
      • -
        - #create_digest - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #current_time - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #deadset - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #deadset_kill - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #deadset_kill? - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #default_lock_timeout - SidekiqUniqueJobs::Timeout::Calculator -
        -
      • - - -
      • -
        - #default_unique_args_method - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #default_worker_options - SidekiqUniqueJobs::SidekiqWorkerMethods -
        -
      • - - -
      • -
        - #del - SidekiqUniqueJobs::Cli -
        -
      • - - -
      • -
        - #del - SidekiqUniqueJobs::Util -
        -
      • - - -
      • -
        - #del - SidekiqUniqueJobs::Digests -
        -
      • - - -
      • -
        - delete - SidekiqUniqueJobs::Unlockable -
        -
      • - - -
      • -
        - #delete - SidekiqUniqueJobs::Locksmith -
        -
      • - - -
      • -
        - #delete - SidekiqUniqueJobs::Lock::BaseLock -
        -
      • - - -
      • -
        - #delete! - SidekiqUniqueJobs::Locksmith -
        -
      • - - -
      • -
        - #delete! - SidekiqUniqueJobs::Lock::BaseLock -
        -
      • - - -
      • -
        - #delete_by_value_ext - Sidekiq::JobSet::UniqueExtension -
        -
      • - - -
      • -
        - #delete_ext - Sidekiq::SortedEntry::UniqueExtension -
        -
      • - - -
      • -
        - #delete_ext - Sidekiq::ScheduledSet::UniqueExtension -
        -
      • - - -
      • -
        - #delete_ext - Sidekiq::Job::UniqueExtension -
        -
      • - - -
      • -
        - #delete_job_by_digest - SidekiqUniqueJobs::OnConflict::Replace -
        -
      • - - -
      • -
        - #delete_lock - SidekiqUniqueJobs::OnConflict::Replace -
        -
      • - - -
      • -
        - digest - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #digestable_hash - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #execute - SidekiqUniqueJobs::Lock::UntilExecuting -
        -
      • - - -
      • -
        - #execute - SidekiqUniqueJobs::Lock::UntilExecuted -
        -
      • - - -
      • -
        - #execute - SidekiqUniqueJobs::Lock::WhileExecuting -
        -
      • - - -
      • -
        - #execute - SidekiqUniqueJobs::Lock::UntilAndWhileExecuting -
        -
      • - - -
      • -
        - #execute - SidekiqUniqueJobs::Lock::BaseLock -
        -
      • - - -
      • -
        - #execute - SidekiqUniqueJobs::Lock::UntilExpired -
        -
      • - - -
      • -
        - #execute - SidekiqUniqueJobs::Lock::WhileExecutingReject -
        -
      • - - -
      • -
        - execute_script - SidekiqUniqueJobs::Scripts -
        -
      • - - -
      • -
        - #exists? - SidekiqUniqueJobs::Locksmith -
        -
      • - - -
      • -
        - #extract_options! - Array -
        -
      • - - -
      • -
        - #filter_by_proc - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #filter_by_symbol - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #filtered_args - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - find_strategy - SidekiqUniqueJobs::OnConflict -
        -
      • - - -
      • -
        - handle_error - SidekiqUniqueJobs::Scripts -
        -
      • - - -
      • -
        - #initialize - SidekiqUniqueJobs::OnConflict::Strategy -
        -
      • - - -
      • -
        - #initialize - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #initialize - SidekiqUniqueJobs::Lock::BaseLock -
        -
      • - - -
      • -
        - #initialize - SidekiqUniqueJobs::OnConflict::Reschedule -
        -
      • - - -
      • -
        - #initialize - SidekiqUniqueJobs::Lock::WhileExecuting -
        -
      • - - -
      • -
        - #initialize - SidekiqUniqueJobs::ScriptError -
        -
      • - - -
      • -
        - #initialize - SidekiqUniqueJobs::Conflict -
        -
      • - - -
      • -
        - #initialize - SidekiqUniqueJobs::OnConflict::Replace -
        -
      • - - -
      • -
        - #initialize - SidekiqUniqueJobs::Timeout::Calculator -
        -
      • - - -
      • -
        - #initialize - SidekiqUniqueJobs::Locksmith -
        -
      • - - -
      • -
        - #item - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #item - SidekiqUniqueJobs::OnConflict::Strategy -
        -
      • - - -
      • -
        - #item - SidekiqUniqueJobs::Timeout::Calculator -
        -
      • - - -
      • -
        - jsonify - SidekiqUniqueJobs::Normalizer -
        -
      • - - -
      • -
        - #keys - SidekiqUniqueJobs::Cli -
        -
      • - - -
      • -
        - #keys - SidekiqUniqueJobs::Util -
        -
      • - - -
      • -
        - #keys_with_ttl - SidekiqUniqueJobs::Util -
        -
      • - - -
      • -
        - #kill_job_with_options - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #kill_job_without_options - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #kill_with_options? - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #lock - SidekiqUniqueJobs::OptionsWithFallback -
        -
      • - - -
      • -
        - #lock - SidekiqUniqueJobs::Lock::BaseLock -
        -
      • - - -
      • -
        - #lock - SidekiqUniqueJobs::Locksmith -
        -
      • - - -
      • -
        - #lock - SidekiqUniqueJobs::Lock::WhileExecuting -
        -
      • - - -
      • -
        - #lock_class - SidekiqUniqueJobs::OptionsWithFallback -
        -
      • - - -
      • -
        - #lock_expiration - SidekiqUniqueJobs::Timeout::Calculator -
        -
      • - - -
      • -
        - #lock_timeout - SidekiqUniqueJobs::Timeout::Calculator -
        -
      • - - -
      • -
        - #lock_type - SidekiqUniqueJobs::OptionsWithFallback -
        -
      • - - -
      • -
        - #locked? - SidekiqUniqueJobs::Lock::BaseLock -
        -
      • - - -
      • -
        - #locked? - SidekiqUniqueJobs::Locksmith -
        -
      • - - -
      • -
        - #log_debug - SidekiqUniqueJobs::Logging -
        -
      • - - -
      • -
        - #log_duplicate_payload? - SidekiqUniqueJobs::OptionsWithFallback -
        -
      • - - -
      • -
        - #log_error - SidekiqUniqueJobs::Logging -
        -
      • - - -
      • -
        - #log_fatal - SidekiqUniqueJobs::Logging -
        -
      • - - -
      • -
        - #log_info - SidekiqUniqueJobs::Logging -
        -
      • - - -
      • -
        - #log_warn - SidekiqUniqueJobs::Logging -
        -
      • - - -
      • -
        - #logger - SidekiqUniqueJobs::Logging -
        -
      • - - -
      • -
        - logger - SidekiqUniqueJobs -
        -
      • - - -
      • -
        - logger= - SidekiqUniqueJobs -
        -
      • - - -
      • -
        - #logging_context - SidekiqUniqueJobs::Logging -
        -
      • - - -
      • -
        - #options - SidekiqUniqueJobs::OptionsWithFallback -
        -
      • - - -
      • -
        - #page - SidekiqUniqueJobs::Digests -
        -
      • - - -
      • -
        - #payload - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #push_to_deadset - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #queue - SidekiqUniqueJobs::OnConflict::Replace -
        -
      • - - -
      • -
        - #redirect_to - SidekiqUniqueJobs::Web::Helpers -
        -
      • - - -
      • -
        - #redis - SidekiqUniqueJobs::Connection -
        -
      • - - -
      • -
        - redis_version - SidekiqUniqueJobs -
        -
      • - - -
      • -
        - registered - SidekiqUniqueJobs::Web -
        -
      • - - -
      • -
        - #replace? - SidekiqUniqueJobs::OnConflict::Strategy -
        -
      • - - -
      • -
        - #runtime_lock - SidekiqUniqueJobs::Lock::UntilAndWhileExecuting -
        -
      • - - -
      • -
        - #safe_relative_time - SidekiqUniqueJobs::Web::Helpers -
        -
      • - - -
      • -
        - #scheduled_at - SidekiqUniqueJobs::Timeout::Calculator -
        -
      • - - -
      • -
        - script_path - SidekiqUniqueJobs::Scripts -
        -
      • - - -
      • -
        - script_sha - SidekiqUniqueJobs::Scripts -
        -
      • - - -
      • -
        - script_source - SidekiqUniqueJobs::Scripts -
        -
      • - - -
      • -
        - #send_to_deadset - SidekiqUniqueJobs::OnConflict::Reject -
        -
      • - - -
      • -
        - #sidekiq_worker_class? - SidekiqUniqueJobs::SidekiqWorkerMethods -
        -
      • - - -
      • -
        - #slice - Hash -
        -
      • - - -
      • -
        - #slice! - Hash -
        -
      • - - -
      • -
        - #strategy - SidekiqUniqueJobs::Lock::WhileExecutingReject -
        -
      • - - -
      • -
        - #stringify_keys - Hash -
        -
      • - - -
      • -
        - #time_until_scheduled - SidekiqUniqueJobs::Timeout::Calculator -
        -
      • - - -
      • -
        - #transform_keys - Hash -
        -
      • - - -
      • -
        - #unique_across_queues? - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #unique_across_workers? - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #unique_args - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #unique_args_enabled? - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #unique_args_method - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #unique_digest - SidekiqUniqueJobs::OnConflict::Replace -
        -
      • - - -
      • -
        - #unique_digest - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #unique_disabled? - SidekiqUniqueJobs::OptionsWithFallback -
        -
      • - - -
      • -
        - #unique_enabled? - SidekiqUniqueJobs::OptionsWithFallback -
        -
      • - - -
      • -
        - #unique_prefix - SidekiqUniqueJobs::UniqueArgs -
        -
      • - - -
      • -
        - #unique_template - SidekiqUniqueJobs::Web::Helpers -
        -
      • - - -
      • -
        - #unique_type - SidekiqUniqueJobs::OptionsWithFallback -
        -
      • - - -
      • -
        - #unlock - SidekiqUniqueJobs::Lock::UntilExpired -
        -
      • - - -
      • -
        - #unlock - SidekiqUniqueJobs::Locksmith -
        -
      • - - -
      • -
        - unlock - SidekiqUniqueJobs::Unlockable -
        -
      • - - -
      • -
        - #unlock - SidekiqUniqueJobs::Lock::BaseLock -
        -
      • - - -
      • -
        - #unlock! - SidekiqUniqueJobs::Locksmith -
        -
      • - - -
      • -
        - use_config - SidekiqUniqueJobs -
        -
      • - - -
      • -
        - use_options - Sidekiq -
        -
      • - - -
      • -
        - #use_options - Sidekiq::Worker::ClassMethods -
        -
      • - - -
      • -
        - #worker_class - SidekiqUniqueJobs::SidekiqWorkerMethods -
        -
      • - - -
      • -
        - #worker_class_constantize - SidekiqUniqueJobs::SidekiqWorkerMethods -
        -
      • - - -
      • -
        - #worker_method_defined? - SidekiqUniqueJobs::SidekiqWorkerMethods -
        -
      • - - -
      • -
        - #worker_options - SidekiqUniqueJobs::SidekiqWorkerMethods -
        -
      • - - - -
      -
      - - diff --git a/docs/top-level-namespace.html b/docs/top-level-namespace.html deleted file mode 100644 index d7e422303..000000000 --- a/docs/top-level-namespace.html +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - Top Level Namespace - - — Documentation by YARD 0.9.18 - - - - - - - - - - - - - - - - - - - -
      - - -

      Top Level Namespace - - - -

      -
      - - - - - - - - - - - -
      - -

      Defined Under Namespace

      -

      - - - Modules: Sidekiq, SidekiqUniqueJobs - - - - Classes: Array, Hash - - -

      - - - - - - - - - -
      - - - -
      - - \ No newline at end of file From f28ed94c86bd882bc86dfc7be4a7be1f769ff7f5 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 12:36:21 +0100 Subject: [PATCH 08/23] Enforce some more rubocop validations --- .rubocop.yml | 19 ++++-- .rubocop_todo.yml | 67 ------------------- Gemfile | 37 +++++----- rails_example/Gemfile | 40 +++++------ sidekiq-unique-jobs.gemspec | 46 ++++++------- .../sidekiq_unique_jobs/unique_args_spec.rb | 10 ++- 6 files changed, 81 insertions(+), 138 deletions(-) delete mode 100644 .rubocop_todo.yml diff --git a/.rubocop.yml b/.rubocop.yml index 6a501a3fa..599578476 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,3 @@ -inherit_from: .rubocop_todo.yml - require: - rubocop-rspec @@ -11,6 +9,8 @@ AllCops: TargetRubyVersion: 2.3 Include: - "**/Rakefile" + - "**/Gemfile" + - "*.gemspec" - "lib/**/*.rb" - "bin/**/*.rb" - "spec/**/*.rb" @@ -18,7 +18,6 @@ AllCops: Exclude: - "Gemfile.lock" - "**/*.erb" - - "rails_example/**/*" Lint/HandleExceptions: Enabled: true @@ -43,6 +42,7 @@ Metrics/BlockLength: Exclude: - "**/spec/**/*.rb" - "**/*.rake" + - "Rakefile" Metrics/PerceivedComplexity: Max: 8 @@ -55,8 +55,6 @@ Naming/ConstantName: Naming/FileName: Enabled: true - Exclude: - - "**/Gemfile" Naming/UncommunicativeMethodParamName: AllowedNames: @@ -65,10 +63,17 @@ Naming/UncommunicativeMethodParamName: RSpec/AlignLeftLetBrace: Enabled: true +RSpec/ExampleLength: + Enabled: false + +RSpec/ExpectActual: + Enabled: false + RSpec/FilePath: Enabled: true - Exclude: - - "spec/stub_requests/webmock_builder_spec.rb" + +RSpec/MultipleExpectations: + Enabled: false RSpec/NestedGroups: Max: 4 diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml deleted file mode 100644 index 9b68c0598..000000000 --- a/.rubocop_todo.yml +++ /dev/null @@ -1,67 +0,0 @@ -# This configuration was generated by -# `rubocop --auto-gen-config` -# on 2019-02-01 21:51:49 +0100 using RuboCop version 0.63.1. -# The point is for the user to remove these configuration records -# one by one as the offenses are removed from the code base. -# Note that changes in the inspected code, or installation of new -# versions of RuboCop, may require this file to be generated again. - -# Offense count: 1 -# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms. -# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS -Naming/FileName: - Exclude: - - "**/Gemfile" - - "lib/sidekiq-unique-jobs.rb" - -# Offense count: 2 -RSpec/DescribeClass: - Exclude: - - "spec/unit/sidekiq_unique_jobs/core_ext_spec.rb" - -# Offense count: 43 -# Configuration parameters: Max. -RSpec/ExampleLength: - Enabled: false - -# Offense count: 29 -RSpec/ExpectActual: - Exclude: - - "spec/routing/**/*" - - "spec/examples/expiring_job_spec.rb" - - "spec/examples/my_unique_job_spec.rb" - -# Offense count: 10 -RSpec/ExpectInHook: - Exclude: - - "spec/integration/sidekiq/retry_set_spec.rb" - - "spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb" - - "spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb" - - "spec/unit/sidekiq_unique_jobs/util_spec.rb" - -# Offense count: 27 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: have_received, receive -RSpec/MessageSpies: - Exclude: - - "spec/examples/spawn_simple_worker_spec.rb" - - "spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb" - - "spec/support/shared_examples/a_performing_worker.rb" - - "spec/unit/sidekiq_unique_jobs/cli_spec.rb" - - "spec/unit/sidekiq_unique_jobs/middleware_spec.rb" - - "spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb" - - "spec/unit/sidekiq_unique_jobs/scripts_spec.rb" - -# Offense count: 76 -# Configuration parameters: AggregateFailuresByDefault. -RSpec/MultipleExpectations: - Max: 9 - -# Offense count: 8 -RSpec/RepeatedExample: - Exclude: - - "spec/unit/sidekiq_unique_jobs/unique_args_spec.rb" - -# Offense count: 56 -Style/Documentation: - Enabled: false diff --git a/Gemfile b/Gemfile index cbe422e9e..b492e1bd0 100644 --- a/Gemfile +++ b/Gemfile @@ -1,25 +1,26 @@ # frozen_string_literal: true -source 'https://rubygems.org' +source "https://rubygems.org" gemspec -gem 'appraisal', '~> 2.2.0' -gem 'rspec-its', require: false -gem 'rspec-retry', require: false -gem 'rspec-eventually', require: false +gem "appraisal", "~> 2.2.0" +gem "awesome_print" +gem "rspec-eventually", require: false +gem "rspec-its", require: false +gem "rspec-retry", require: false platforms :mri_25 do - gem 'benchmark-ips' - gem 'fasterer' - gem 'guard' - gem 'guard-reek' - gem 'guard-rspec' - gem 'guard-rubocop' - gem 'memory_profiler' - gem 'reek', '>= 5.3', - gem 'pry' - gem 'rubocop' - gem 'rubocop-rspec' - gem 'simplecov-json' - gem 'rb-readline' + gem "benchmark-ips" + gem "fasterer" + gem "guard" + gem "guard-reek" + gem "guard-rspec" + gem "guard-rubocop" + gem "memory_profiler" + gem "pry" + gem "rb-readline" + gem "reek", ">= 5.3" + gem "rubocop" + gem "rubocop-rspec" + gem "simplecov-json" end diff --git a/rails_example/Gemfile b/rails_example/Gemfile index 5e06e0d96..5e1aaf6ab 100644 --- a/rails_example/Gemfile +++ b/rails_example/Gemfile @@ -1,27 +1,27 @@ # frozen_string_literal: true -source 'https://rubygems.org' +source "https://rubygems.org" -ruby '2.5.1' +ruby "2.5.3" -gem 'bigdecimal' -gem 'json' -gem 'pg' -gem 'puma' -gem 'rack-protection' -gem 'rails', '~> 5.2' -gem 'sidekiq' -gem 'sidekiq-unique-jobs', path: '..' -gem 'sinatra' -gem 'slim-rails' +gem "bigdecimal" +gem "json" +gem "pg" +gem "puma" +gem "rack-protection" +gem "rails", "~> 5.2" +gem "sidekiq" +gem "sidekiq-unique-jobs", path: ".." +gem "sinatra" +gem "slim-rails" group :development, :test do - gem 'capybara' - gem 'dotenv-rails' - gem 'factory_bot_rails' - gem 'fuubar' - gem 'pry-rails' - gem 'pry-byebug' - gem 'rspec-eventually' - gem 'rspec-rails' + gem "capybara" + gem "dotenv-rails" + gem "factory_bot_rails" + gem "fuubar" + gem "pry-byebug" + gem "pry-rails" + gem "rspec-eventually" + gem "rspec-rails" end diff --git a/sidekiq-unique-jobs.gemspec b/sidekiq-unique-jobs.gemspec index 9dd551769..5ffe5a46c 100644 --- a/sidekiq-unique-jobs.gemspec +++ b/sidekiq-unique-jobs.gemspec @@ -1,20 +1,20 @@ # frozen_string_literal: true -lib = File.expand_path("../lib", __FILE__) +lib = File.expand_path("lib", __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require 'sidekiq_unique_jobs/version' +require "sidekiq_unique_jobs/version" Gem::Specification.new do |spec| - spec.name = 'sidekiq-unique-jobs' + spec.name = "sidekiq-unique-jobs" spec.version = SidekiqUniqueJobs::VERSION - spec.authors = ['Mikael Henriksson'] - spec.email = ['mikael@zoolutions.se'] + spec.authors = ["Mikael Henriksson"] + spec.email = ["mikael@zoolutions.se"] - spec.summary = 'Prevent duplicate jobs in Sidekiq' - spec.description = 'An attempt to prevent simultaneous Sidekiq jobs with the same unique arguments to run' - spec.homepage = 'https://mhenrixon.github.com/sidekiq-unique-jobs' - spec.license = 'MIT' + spec.summary = "Prevent duplicate jobs in Sidekiq" + spec.description = "An attempt to prevent simultaneous Sidekiq jobs with the same unique arguments to run" + spec.homepage = "https://mhenrixon.github.com/sidekiq-unique-jobs" + spec.license = "MIT" if spec.respond_to?(:metadata) spec.metadata["homepage_uri"] = spec.homepage @@ -25,35 +25,35 @@ Gem::Specification.new do |spec| "public gem pushes." end - spec.bindir = 'bin' + spec.bindir = "bin" spec.executables = %w[uniquejobs] - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do + spec.files = Dir.chdir(File.expand_path(__dir__)) do `git ls-files -z`.split("\x0").reject do |file| file.match(%r{^(test|spec|features|gemfiles|pkg|rails_example|tmp)/}) end end - spec.require_paths = ['lib'] - spec.add_dependency 'concurrent-ruby', '~> 1.0', '>= 1.0.5' - spec.add_dependency 'sidekiq', '>= 4.0', '< 6.0' - spec.add_dependency 'thor', '~> 0' + spec.require_paths = ["lib"] + spec.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.5" + spec.add_dependency "sidekiq", ">= 4.0", "< 6.0" + spec.add_dependency "thor", "~> 0" - spec.add_development_dependency 'bundler', '>= 2.0' - spec.add_development_dependency 'rspec', '~> 3.7' - spec.add_development_dependency 'rake', '~> 12.3' - spec.add_development_dependency 'timecop', '~> 0.9' - spec.add_development_dependency 'rack-test' - spec.add_development_dependency 'sinatra' + spec.add_development_dependency "bundler", ">= 2.0" + spec.add_development_dependency "rack-test" + spec.add_development_dependency "rake", "~> 12.3" + spec.add_development_dependency "rspec", "~> 3.7" + spec.add_development_dependency "sinatra" + spec.add_development_dependency "timecop", "~> 0.9" # ===== Utilities ===== spec.add_development_dependency "travis", ">= 1.8.9" # ===== Documentation ===== - spec.add_development_dependency "yard", "~> 0.9.18" - spec.add_development_dependency "redcarpet", "~> 3.4" spec.add_development_dependency "github-markup", "~> 3.0" spec.add_development_dependency "github_changelog_generator", "~> 1.14" + spec.add_development_dependency "redcarpet", "~> 3.4" + spec.add_development_dependency "yard", "~> 0.9.18" # ===== Release Management ===== spec.add_development_dependency "gem-release", ">= 2.0" diff --git a/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb b/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb index 33a69b2bb..eb2334635 100644 --- a/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb @@ -75,18 +75,22 @@ { "class" => "UntilExecutedJob", "queue" => "myqueue", "unique_args" => [[1, 2]] } end - it { is_expected.to eq(expected_hash) } + shared_examples "a digestable hash" do + it { is_expected.to eq(expected_hash) } + end + + it_behaves_like "a digestable hash" with_sidekiq_options_for(UntilExecutedJob, unique_args: :unique_args, unique_on_all_queues: true) do let(:expected_hash) { { "class" => "UntilExecutedJob", "unique_args" => [[1, 2]] } } - it { is_expected.to eq(expected_hash) } + it_behaves_like "a digestable hash" end with_sidekiq_options_for(UntilExecutedJob, unique_across_workers: true) do let(:expected_hash) { { "queue" => "myqueue", "unique_args" => [[1, 2]] } } - it { is_expected.to eq(expected_hash) } + it_behaves_like "a digestable hash" end end From efbb9e2d0c20027ee0acc2336093f0a1c5752fde Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 12:37:01 +0100 Subject: [PATCH 09/23] Separate requires and module definition --- lib/sidekiq_unique_jobs.rb | 74 +----------------- .../sidekiq_unique_jobs.rb | 75 +++++++++++++++++++ 2 files changed, 76 insertions(+), 73 deletions(-) create mode 100644 lib/sidekiq_unique_jobs/sidekiq_unique_jobs.rb diff --git a/lib/sidekiq_unique_jobs.rb b/lib/sidekiq_unique_jobs.rb index b6f35d218..966fb6682 100644 --- a/lib/sidekiq_unique_jobs.rb +++ b/lib/sidekiq_unique_jobs.rb @@ -33,76 +33,4 @@ require "sidekiq_unique_jobs/sidekiq_unique_ext" require "sidekiq_unique_jobs/on_conflict" -# -# Contains configuration and utility methods that belongs top level -# -# @author Mikael Henriksson -module SidekiqUniqueJobs - include SidekiqUniqueJobs::Connection - - module_function - - Config = Concurrent::MutableStruct.new( - :default_lock_timeout, - :enabled, - :unique_prefix, - :logger, - ) - - # The current configuration (See: {.configure} on how to configure) - def config - # Arguments here need to match the definition of the new class (see above) - @config ||= Config.new( - 0, - true, - "uniquejobs", - Sidekiq.logger, - ) - end - - # The current logger - # @return [Logger] the configured logger - def logger - config.logger - end - - # Set a new logger - # @param [Logger] other a new logger - def logger=(other) - config.logger = other - end - - # Change global configuration while yielding - # @yield control to the caller - def use_config(tmp_config) - raise ::ArgumentError, "#{name}.#{__method__} needs a block" unless block_given? - - old_config = config.to_h - configure(tmp_config) - yield - configure(old_config) - end - - # Configure the gem - # - # This is usually called once at startup of an application - # @param [Hash] options global gem options - # @option options [Integer] :default_lock_timeout (default is 0) - # @option options [true,false] :enabled (default is true) - # @option options [String] :unique_prefix (default is 'uniquejobs') - # @option options [Logger] :logger (default is Sidekiq.logger) - # @yield control to the caller when given block - def configure(options = {}) - if block_given? - yield config - else - options.each do |key, val| - config.send("#{key}=", val) - end - end - end - - def redis_version - @redis_version ||= redis { |conn| conn.info("server")["redis_version"] } - end -end +require "sidekiq_unique_jobs/sidekiq_unique_jobs" diff --git a/lib/sidekiq_unique_jobs/sidekiq_unique_jobs.rb b/lib/sidekiq_unique_jobs/sidekiq_unique_jobs.rb new file mode 100644 index 000000000..0f42dd5cb --- /dev/null +++ b/lib/sidekiq_unique_jobs/sidekiq_unique_jobs.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +# +# Contains configuration and utility methods that belongs top level +# +# @author Mikael Henriksson +module SidekiqUniqueJobs + include SidekiqUniqueJobs::Connection + + module_function + + Config = Concurrent::MutableStruct.new( + :default_lock_timeout, + :enabled, + :unique_prefix, + :logger, + ) + + # The current configuration (See: {.configure} on how to configure) + def config + # Arguments here need to match the definition of the new class (see above) + @config ||= Config.new( + 0, + true, + "uniquejobs", + Sidekiq.logger, + ) + end + + # The current logger + # @return [Logger] the configured logger + def logger + config.logger + end + + # Set a new logger + # @param [Logger] other a new logger + def logger=(other) + config.logger = other + end + + # Change global configuration while yielding + # @yield control to the caller + def use_config(tmp_config) + raise ::ArgumentError, "#{name}.#{__method__} needs a block" unless block_given? + + old_config = config.to_h + configure(tmp_config) + yield + configure(old_config) + end + + # Configure the gem + # + # This is usually called once at startup of an application + # @param [Hash] options global gem options + # @option options [Integer] :default_lock_timeout (default is 0) + # @option options [true,false] :enabled (default is true) + # @option options [String] :unique_prefix (default is 'uniquejobs') + # @option options [Logger] :logger (default is Sidekiq.logger) + # @yield control to the caller when given block + def configure(options = {}) + if block_given? + yield config + else + options.each do |key, val| + config.send("#{key}=", val) + end + end + end + + def redis_version + @redis_version ||= redis { |conn| conn.info("server")["redis_version"] } + end +end From 2c3df2c36e9f6a52109074219a3a9e17b1f798fa Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 17:39:40 +0100 Subject: [PATCH 10/23] Configure rubocop-rspec --- .rspec | 1 - .rubocop.yml | 27 +++++++- .travis.yml | 10 +-- rails_example/spec/factories/posts.rb | 8 +-- spec/examples/another_unique_job_spec.rb | 2 - spec/examples/custom_queue_job_spec.rb | 2 - ...ustom_queue_job_with_filter_method_spec.rb | 2 - .../custom_queue_job_with_filter_proc_spec.rb | 2 - spec/examples/expiring_job_spec.rb | 2 - spec/examples/inline_worker_spec.rb | 2 - spec/examples/just_a_worker_spec.rb | 2 - spec/examples/long_running_job_spec.rb | 2 - spec/examples/main_job_spec.rb | 2 - spec/examples/my_job_spec.rb | 2 - spec/examples/my_unique_job_spec.rb | 2 - .../my_unique_job_with_filter_method_spec.rb | 2 - .../my_unique_job_with_filter_proc_spec.rb | 2 - spec/examples/notify_worker_spec.rb | 2 - spec/examples/plain_class_spec.rb | 2 - spec/examples/simple_worker_spec.rb | 2 - spec/examples/spawn_simple_worker_spec.rb | 8 ++- spec/examples/test_class_spec.rb | 2 - .../unique_across_workers_job_spec.rb | 2 - .../unique_job_on_conflict_raise_spec.rb | 2 - .../unique_job_on_conflict_reject_spec.rb | 2 - .../unique_job_on_conflict_reschedule_spec.rb | 2 - .../unique_job_with_nil_unique_args_spec.rb | 2 - ...que_job_with_no_unique_args_method_spec.rb | 2 - ..._job_without_unique_args_parameter_spec.rb | 2 - .../examples/unique_on_all_queues_job_spec.rb | 2 - .../until_and_while_executing_job_spec.rb | 2 - spec/examples/until_executed2_job_spec.rb | 2 - spec/examples/until_executed_job_spec.rb | 2 - spec/examples/until_executing_job_spec.rb | 2 - spec/examples/until_expired_job_spec.rb | 2 - .../examples/until_global_expired_job_spec.rb | 2 - spec/examples/while_executing_job_spec.rb | 2 - spec/examples/without_argument_job_spec.rb | 2 - spec/integration/sidekiq/retry_set_spec.rb | 18 +++-- .../client/middleware_spec.rb | 9 ++- .../sidekiq_unique_jobs/legacy_lock_spec.rb | 17 ++--- .../lock/until_and_while_executing_spec.rb | 2 - .../lock/until_executed_spec.rb | 8 +-- .../lock/until_executing_spec.rb | 8 +-- .../lock/until_expired_spec.rb | 2 - .../lock/while_executing_reject_spec.rb | 2 - .../lock/while_executing_spec.rb | 2 - .../sidekiq_unique_jobs/locksmith_spec.rb | 2 - .../until_and_while_executing_spec.rb | 8 ++- .../server/middleware_spec.rb | 2 - .../sidekiq_unique_jobs/web_spec.rb | 1 - spec/spec_helper.rb | 3 +- .../shared_examples/a_performing_worker.rb | 9 +-- spec/unit/sidekiq_unique_jobs/cli_spec.rb | 12 ++-- .../client/middleware_spec.rb | 2 - .../unit/sidekiq_unique_jobs/core_ext_spec.rb | 2 - spec/unit/sidekiq_unique_jobs/digests_spec.rb | 2 - .../lock/base_lock_spec.rb | 2 - .../lock/until_and_while_executing_spec.rb | 2 - .../lock/until_executed_spec.rb | 2 - .../lock/until_executing_spec.rb | 2 - .../lock/until_expired_spec.rb | 2 - .../lock/while_executing_reject_spec.rb | 2 - .../lock/while_executing_spec.rb | 2 - .../sidekiq_unique_jobs/middleware_spec.rb | 66 +++++++++++-------- .../sidekiq_unique_jobs/normalizer_spec.rb | 2 - .../on_conflict/log_spec.rb | 2 - .../on_conflict/raise_spec.rb | 2 - .../on_conflict/reject_spec.rb | 54 ++++++++++----- .../on_conflict/replace_spec.rb | 2 - .../on_conflict/reschedule_spec.rb | 2 - .../on_conflict/strategy_spec.rb | 2 - .../sidekiq_unique_jobs/on_conflict_spec.rb | 2 - .../options_with_fallback_spec.rb | 2 - .../server/middleware_spec.rb | 2 - .../sidekiq_unique_jobs/sidekiq/api_spec.rb | 4 +- .../sidekiq_worker_methods_spec.rb | 2 - .../timeout/calculator_spec.rb | 2 - .../sidekiq_unique_jobs/unique_args_spec.rb | 5 +- .../sidekiq_unique_jobs/unlockable_spec.rb | 2 - spec/unit/sidekiq_unique_jobs/util_spec.rb | 11 ++-- spec/unit/sidekiq_unique_jobs_spec.rb | 2 - 82 files changed, 170 insertions(+), 241 deletions(-) diff --git a/.rspec b/.rspec index 34c5164d9..83e16f804 100644 --- a/.rspec +++ b/.rspec @@ -1,3 +1,2 @@ ---format documentation --color --require spec_helper diff --git a/.rubocop.yml b/.rubocop.yml index 599578476..2c31971cd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -19,6 +19,10 @@ AllCops: - "Gemfile.lock" - "**/*.erb" +Lint/AmbiguousBlockAssociation: + Exclude: + - "spec/**/*" + Lint/HandleExceptions: Enabled: true @@ -43,6 +47,7 @@ Metrics/BlockLength: - "**/spec/**/*.rb" - "**/*.rake" - "Rakefile" + - "*.gemspec" Metrics/PerceivedComplexity: Max: 8 @@ -55,6 +60,8 @@ Naming/ConstantName: Naming/FileName: Enabled: true + Exclude: + - lib/sidekiq-unique-jobs.rb Naming/UncommunicativeMethodParamName: AllowedNames: @@ -63,14 +70,26 @@ Naming/UncommunicativeMethodParamName: RSpec/AlignLeftLetBrace: Enabled: true +RSpec/DescribeClass: + Exclude: + - spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb + - spec/unit/sidekiq_unique_jobs/core_ext_spec.rb + RSpec/ExampleLength: Enabled: false RSpec/ExpectActual: Enabled: false +RSpec/ExpectChange: + Exclude: + - spec/integration/sidekiq_unique_jobs/lock/**/*_spec.rb + RSpec/FilePath: Enabled: true +RSpec/MessageSpies: + Exclude: + - spec/unit/sidekiq_unique_jobs/scripts_spec.rb RSpec/MultipleExpectations: Enabled: false @@ -79,8 +98,9 @@ RSpec/NestedGroups: Max: 4 Enabled: true -Style/FrozenStringLiteralComment: - Enabled: true +RSpec/RepeatedExample: + Exclude: + - spec/unit/sidekiq_unique_jobs/unique_args_spec.rb Style/Documentation: Enabled: true @@ -95,6 +115,9 @@ Style/Documentation: - "lib/sidekiq_unique_jobs/on_conflict.rb" - "lib/sidekiq_unique_jobs/timeout.rb" +Style/FrozenStringLiteralComment: + Enabled: true + Style/GlobalVars: Enabled: true diff --git a/.travis.yml b/.travis.yml index b50fbeddc..40cff33f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,15 +27,15 @@ after_script: - if [[ "${COV}" = "true" ]]; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT; fi; rvm: - - 2.5.1 - - 2.4.2 - - 2.3.2 - - jruby-9.2.0.0 + - 2.6.1 + - 2.4.5 + - 2.3.8 + - jruby-9.2.5.0 matrix: fast_finish: true include: - - rvm: 2.5.1 + - rvm: 2.5.3 gemfile: gemfiles/sidekiq_develop.gemfile env: COV=true diff --git a/rails_example/spec/factories/posts.rb b/rails_example/spec/factories/posts.rb index 6f62863d5..a0e0a6ecc 100644 --- a/rails_example/spec/factories/posts.rb +++ b/rails_example/spec/factories/posts.rb @@ -2,9 +2,9 @@ FactoryBot.define do factory :post do - title 'MyString' - body 'MyText' - excerpt 'MyString' - read_count 1 + title { 'MyString' } + body { 'MyText' } + excerpt { 'MyString' } + read_count { 1 } end end diff --git a/spec/examples/another_unique_job_spec.rb b/spec/examples/another_unique_job_spec.rb index 527daddc3..5f5978476 100644 --- a/spec/examples/another_unique_job_spec.rb +++ b/spec/examples/another_unique_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe AnotherUniqueJob, redis: :redis do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/custom_queue_job_spec.rb b/spec/examples/custom_queue_job_spec.rb index c260f4126..289e1c553 100644 --- a/spec/examples/custom_queue_job_spec.rb +++ b/spec/examples/custom_queue_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe CustomQueueJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/custom_queue_job_with_filter_method_spec.rb b/spec/examples/custom_queue_job_with_filter_method_spec.rb index 662490af7..3e1deba9a 100644 --- a/spec/examples/custom_queue_job_with_filter_method_spec.rb +++ b/spec/examples/custom_queue_job_with_filter_method_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe CustomQueueJobWithFilterMethod do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/custom_queue_job_with_filter_proc_spec.rb b/spec/examples/custom_queue_job_with_filter_proc_spec.rb index c5bb40942..9c2a53f07 100644 --- a/spec/examples/custom_queue_job_with_filter_proc_spec.rb +++ b/spec/examples/custom_queue_job_with_filter_proc_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe CustomQueueJobWithFilterProc do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/expiring_job_spec.rb b/spec/examples/expiring_job_spec.rb index 769f0ad30..fe7536a5b 100644 --- a/spec/examples/expiring_job_spec.rb +++ b/spec/examples/expiring_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe ExpiringJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/inline_worker_spec.rb b/spec/examples/inline_worker_spec.rb index e228b1d5d..fdf5c873a 100644 --- a/spec/examples/inline_worker_spec.rb +++ b/spec/examples/inline_worker_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe InlineWorker do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/just_a_worker_spec.rb b/spec/examples/just_a_worker_spec.rb index 2cb00a25f..a8117f06e 100644 --- a/spec/examples/just_a_worker_spec.rb +++ b/spec/examples/just_a_worker_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe JustAWorker do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/long_running_job_spec.rb b/spec/examples/long_running_job_spec.rb index 145bbd00d..b20f308b3 100644 --- a/spec/examples/long_running_job_spec.rb +++ b/spec/examples/long_running_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe LongRunningJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/main_job_spec.rb b/spec/examples/main_job_spec.rb index 415ad88eb..558be2d08 100644 --- a/spec/examples/main_job_spec.rb +++ b/spec/examples/main_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe MainJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/my_job_spec.rb b/spec/examples/my_job_spec.rb index 737977423..ed1792126 100644 --- a/spec/examples/my_job_spec.rb +++ b/spec/examples/my_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe MyJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/my_unique_job_spec.rb b/spec/examples/my_unique_job_spec.rb index 4a1439023..a9e8d33e7 100644 --- a/spec/examples/my_unique_job_spec.rb +++ b/spec/examples/my_unique_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe MyUniqueJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/my_unique_job_with_filter_method_spec.rb b/spec/examples/my_unique_job_with_filter_method_spec.rb index 71f8725f9..5aab178c6 100644 --- a/spec/examples/my_unique_job_with_filter_method_spec.rb +++ b/spec/examples/my_unique_job_with_filter_method_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe MyUniqueJobWithFilterMethod do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/my_unique_job_with_filter_proc_spec.rb b/spec/examples/my_unique_job_with_filter_proc_spec.rb index 8b181c4be..b556bf9b2 100644 --- a/spec/examples/my_unique_job_with_filter_proc_spec.rb +++ b/spec/examples/my_unique_job_with_filter_proc_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe MyUniqueJobWithFilterProc do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/notify_worker_spec.rb b/spec/examples/notify_worker_spec.rb index 662a2368f..84098fd89 100644 --- a/spec/examples/notify_worker_spec.rb +++ b/spec/examples/notify_worker_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe NotifyWorker do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/plain_class_spec.rb b/spec/examples/plain_class_spec.rb index 68fcf0187..01b3f037c 100644 --- a/spec/examples/plain_class_spec.rb +++ b/spec/examples/plain_class_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe PlainClass do describe ".run" do subject { described_class.run(arg) } diff --git a/spec/examples/simple_worker_spec.rb b/spec/examples/simple_worker_spec.rb index a87bb557b..60954f3e6 100644 --- a/spec/examples/simple_worker_spec.rb +++ b/spec/examples/simple_worker_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SimpleWorker do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/spawn_simple_worker_spec.rb b/spec/examples/spawn_simple_worker_spec.rb index fefcce5b5..f25c85fbd 100644 --- a/spec/examples/spawn_simple_worker_spec.rb +++ b/spec/examples/spawn_simple_worker_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SpawnSimpleWorker do it_behaves_like "sidekiq with options" do let(:options) do @@ -19,9 +17,13 @@ describe "#perform" do let(:args) { %w[one two] } + before do + allow(SimpleWorker).to receive(:perform_async).with(args).and_return(true) + end + it "spawns another job" do - expect(SimpleWorker).to receive(:perform_async).with(args).and_return(true) described_class.new.perform(args) + expect(SimpleWorker).to have_received(:perform_async).with(args) end end end diff --git a/spec/examples/test_class_spec.rb b/spec/examples/test_class_spec.rb index 5566ee42c..c26cf1686 100644 --- a/spec/examples/test_class_spec.rb +++ b/spec/examples/test_class_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe TestClass do describe ".run" do subject { described_class.run(arg) } diff --git a/spec/examples/unique_across_workers_job_spec.rb b/spec/examples/unique_across_workers_job_spec.rb index e6933fd96..fbf2f415d 100644 --- a/spec/examples/unique_across_workers_job_spec.rb +++ b/spec/examples/unique_across_workers_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UniqueAcrossWorkersJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_on_conflict_raise_spec.rb b/spec/examples/unique_job_on_conflict_raise_spec.rb index 568e4bb09..aeb917e0c 100644 --- a/spec/examples/unique_job_on_conflict_raise_spec.rb +++ b/spec/examples/unique_job_on_conflict_raise_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UniqueJobOnConflictRaise do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_on_conflict_reject_spec.rb b/spec/examples/unique_job_on_conflict_reject_spec.rb index 604c92950..65b21a0db 100644 --- a/spec/examples/unique_job_on_conflict_reject_spec.rb +++ b/spec/examples/unique_job_on_conflict_reject_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UniqueJobOnConflictReject do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_on_conflict_reschedule_spec.rb b/spec/examples/unique_job_on_conflict_reschedule_spec.rb index 87b2279be..2a2f334dd 100644 --- a/spec/examples/unique_job_on_conflict_reschedule_spec.rb +++ b/spec/examples/unique_job_on_conflict_reschedule_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UniqueJobOnConflictReschedule do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_with_nil_unique_args_spec.rb b/spec/examples/unique_job_with_nil_unique_args_spec.rb index 4aedd5e87..c2cf06994 100644 --- a/spec/examples/unique_job_with_nil_unique_args_spec.rb +++ b/spec/examples/unique_job_with_nil_unique_args_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UniqueJobWithNilUniqueArgs do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_with_no_unique_args_method_spec.rb b/spec/examples/unique_job_with_no_unique_args_method_spec.rb index b8e8fecaa..0f6a470bb 100644 --- a/spec/examples/unique_job_with_no_unique_args_method_spec.rb +++ b/spec/examples/unique_job_with_no_unique_args_method_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UniqueJobWithNoUniqueArgsMethod do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_without_unique_args_parameter_spec.rb b/spec/examples/unique_job_without_unique_args_parameter_spec.rb index 4266eca10..690ef2136 100644 --- a/spec/examples/unique_job_without_unique_args_parameter_spec.rb +++ b/spec/examples/unique_job_without_unique_args_parameter_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UniqueJobWithoutUniqueArgsParameter do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_on_all_queues_job_spec.rb b/spec/examples/unique_on_all_queues_job_spec.rb index edc3f4e2a..f78fd42f1 100644 --- a/spec/examples/unique_on_all_queues_job_spec.rb +++ b/spec/examples/unique_on_all_queues_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UniqueOnAllQueuesJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_and_while_executing_job_spec.rb b/spec/examples/until_and_while_executing_job_spec.rb index d182e79d6..5fa7c0f3f 100644 --- a/spec/examples/until_and_while_executing_job_spec.rb +++ b/spec/examples/until_and_while_executing_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UntilAndWhileExecutingJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_executed2_job_spec.rb b/spec/examples/until_executed2_job_spec.rb index 54252f44a..8f4b80762 100644 --- a/spec/examples/until_executed2_job_spec.rb +++ b/spec/examples/until_executed2_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UntilExecuted2Job do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_executed_job_spec.rb b/spec/examples/until_executed_job_spec.rb index 60b9e1e52..5e5270161 100644 --- a/spec/examples/until_executed_job_spec.rb +++ b/spec/examples/until_executed_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UntilExecutedJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_executing_job_spec.rb b/spec/examples/until_executing_job_spec.rb index 82edae904..0ce604953 100644 --- a/spec/examples/until_executing_job_spec.rb +++ b/spec/examples/until_executing_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UntilExecutingJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_expired_job_spec.rb b/spec/examples/until_expired_job_spec.rb index 14df8bcef..ee6196972 100644 --- a/spec/examples/until_expired_job_spec.rb +++ b/spec/examples/until_expired_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UntilExpiredJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_global_expired_job_spec.rb b/spec/examples/until_global_expired_job_spec.rb index 58412f82a..db330d399 100644 --- a/spec/examples/until_global_expired_job_spec.rb +++ b/spec/examples/until_global_expired_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe UntilGlobalExpiredJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/while_executing_job_spec.rb b/spec/examples/while_executing_job_spec.rb index 35d5597a6..e585ec35a 100644 --- a/spec/examples/while_executing_job_spec.rb +++ b/spec/examples/while_executing_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe WhileExecutingJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/without_argument_job_spec.rb b/spec/examples/without_argument_job_spec.rb index 4d81d9654..b531193d7 100644 --- a/spec/examples/without_argument_job_spec.rb +++ b/spec/examples/without_argument_job_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe WithoutArgumentJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/integration/sidekiq/retry_set_spec.rb b/spec/integration/sidekiq/retry_set_spec.rb index 1116ed51c..9dc34e9b6 100644 --- a/spec/integration/sidekiq/retry_set_spec.rb +++ b/spec/integration/sidekiq/retry_set_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe Sidekiq::RetrySet, redis: :redis do let(:locksmith) { SidekiqUniqueJobs::Locksmith.new(item) } let(:args) { [1, 2] } @@ -29,20 +27,28 @@ before do zadd("retry", retry_at.to_s, Sidekiq.dump_json(item)) - expect(retry_count).to eq(1) end + specify { expect(retry_count).to eq(1) } + context "when a job is locked" do + let(:locked_jid) { locksmith.lock } + before do - expect(locksmith.lock).to eq(jid) + locked_jid + end + + specify { expect(locked_jid).to eq(jid) } + specify do expect(unique_keys).to match_array(%W[ #{unique_digest}:EXISTS #{unique_digest}:GRABBED ]) - expect(ttl("#{unique_digest}:EXISTS")).to eq(lock_expiration) - expect(ttl("#{unique_digest}:GRABBED")).to eq(-1) end + specify { expect(ttl("#{unique_digest}:EXISTS")).to eq(lock_expiration) } + specify { expect(ttl("#{unique_digest}:GRABBED")).to eq(-1) } + it "can be put back on queue" do expect { described_class.new.retry_all } .to change { queue_count(queue) } diff --git a/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb b/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb index 247f113c0..2d9bd6c11 100644 --- a/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Client::Middleware, redis: :redis, redis_db: 1 do describe "when a job is already scheduled" do it "processes jobs properly" do @@ -181,7 +179,7 @@ def self.do_it(_one) end it "logs duplicate payload when config turned on" do - expect(Sidekiq.logger).to receive(:warn).with(/^payload is not unique/) + allow(Sidekiq.logger).to receive(:warn) with_sidekiq_options_for(UntilExecutedJob, log_duplicate_payload: true) do 2.times do @@ -190,11 +188,11 @@ def self.do_it(_one) expect(queue_count("customqueue")).to eq(1) end + expect(Sidekiq.logger).to have_received(:warn).with(/^payload is not unique/) end it "does not log duplicate payload when config turned off" do - expect(SidekiqUniqueJobs.logger).not_to receive(:warn).with(/^payload is not unique/) - + allow(SidekiqUniqueJobs.logger).to receive(:warn) with_sidekiq_options_for(UntilExecutedJob, log_duplicate_payload: false) do 2.times do Sidekiq::Client.push("class" => UntilExecutedJob, "queue" => "customqueue", "args" => [1, 2]) @@ -202,5 +200,6 @@ def self.do_it(_one) expect(queue_count("customqueue")).to eq(1) end + expect(SidekiqUniqueJobs.logger).not_to have_received(:warn).with(/^payload is not unique/) end end diff --git a/spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb b/spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb index caf589024..7d5986a1f 100644 --- a/spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/legacy_lock_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - # rubocop:disable RSpec/FilePath RSpec.describe SidekiqUniqueJobs::Locksmith, redis: :redis do let(:locksmith_one) { described_class.new(lock_item) } @@ -48,21 +46,21 @@ end context "with a legacy lock" do - before do - result = SidekiqUniqueJobs::Scripts.call( + let(:lock_value) { jid_one } + + let!(:old_lock) do + SidekiqUniqueJobs::Scripts.call( :acquire_lock, redis_pool, keys: [unique_digest], argv: [lock_value, lock_expiration], ) - - expect(result).to eq(1) - expect(unique_keys).to include(unique_digest) end - context "when lock_expiration is unset" do - let(:lock_value) { jid_one } + specify { expect(old_lock).to eq(1) } + specify { expect(unique_keys).to include(unique_digest) } + context "when lock_expiration is unset" do it "unlocks immediately" do locksmith_one.unlock!(jid_one) @@ -81,7 +79,6 @@ end context "when lock_expiration is set" do - let(:lock_value) { jid_one } let(:lock_expiration) { 10 } it "can signal to expire the lock after 10" do diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb index d045d8ee4..29918ab29 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::UntilAndWhileExecuting, redis: :redis, redis_db: 3 do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb index 2dfebce33..e20bb1a12 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuted, redis: :redis do include SidekiqHelpers @@ -56,7 +54,7 @@ it "deletes the lock without fuss" do worker_class.use_options(lock_expiration: nil) do process_one.lock - expect { delete }.to change(unique_keys, :size).from(2).to(0) + expect { delete }.to change { unique_keys.size }.from(2).to(0) end end end @@ -65,7 +63,7 @@ it "does not delete the lock" do worker_class.use_options(lock_expiration: 100) do process_one.lock - expect { delete }.not_to change(unique_keys, :size) + expect { delete }.not_to change { unique_keys.size } end end end @@ -79,7 +77,7 @@ before { process_one.lock } it "deletes the lock without fuss" do - expect { delete! }.to change(unique_keys, :size).from(2).to(0) + expect { delete! }.to change { unique_keys.size }.from(2).to(0) end end end diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb index 6c94b4a87..2942d09c2 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuting, redis: :redis do include SidekiqHelpers @@ -55,7 +53,7 @@ it "deletes the lock without fuss" do worker_class.use_options(lock_expiration: nil) do process_one.lock - expect { delete }.to change(unique_keys, :size).from(2).to(0) + expect { delete }.to change { unique_keys.size }.from(2).to(0) end end end @@ -64,7 +62,7 @@ it "does not delete the lock" do worker_class.use_options(lock_expiration: 100) do process_one.lock - expect { delete }.not_to change(unique_keys, :size) + expect { delete }.not_to change { unique_keys.size } end end end @@ -78,7 +76,7 @@ before { process_one.lock } it "deletes the lock without fuss" do - expect { delete! }.to change(unique_keys, :size).from(2).to(0) + expect { delete! }.to change { unique_keys.size }.from(2).to(0) end end end diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb index 69d9a4254..adc58dba4 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::UntilExpired, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb index 4bee3ce53..3b64e451b 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::WhileExecutingReject, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb index 97542f09d..81aba006e 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb b/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb index 8992428b2..f38aa1a4d 100644 --- a/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Locksmith, redis: :redis do let(:locksmith_one) { described_class.new(item_one) } let(:locksmith_two) { described_class.new(item_two) } diff --git a/spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb index fd59788b5..312cb7cab 100644 --- a/spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/server/middleware/until_and_while_executing_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - # rubocop:disable RSpec/FilePath, RSpec/DescribeMethod RSpec.describe SidekiqUniqueJobs::Server::Middleware, "unique: :until_and_while_executing", redis: :redis do let(:server) { described_class.new } @@ -38,10 +36,14 @@ let(:version_run_key) { "uniquejobs:f07093737839f88af8593c945143574d:RUN:VERSION" } context "when item_one is locked" do + let(:pushed_jid) { push_item(item_one) } + before do - expect(push_item(item_one)).to eq(jid_one) + pushed_jid end + specify { expect(pushed_jid).to eq(jid_one) } + context "with a lock_timeout of 0" do let(:lock_timeout) { 0 } diff --git a/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb b/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb index 0242d8b9a..8b66ebfc6 100644 --- a/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Server::Middleware, redis: :redis, redis_db: 9 do let(:middleware) { SidekiqUniqueJobs::Server::Middleware.new } diff --git a/spec/integration/sidekiq_unique_jobs/web_spec.rb b/spec/integration/sidekiq_unique_jobs/web_spec.rb index 0e43ee4ee..43093ec98 100644 --- a/spec/integration/sidekiq_unique_jobs/web_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/web_spec.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require "spec_helper" require "sidekiq/web" require "sidekiq_unique_jobs/web" require "rack/test" diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d1851d935..50cd408e3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,7 +2,7 @@ require "bundler/setup" -if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.5.1" +if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.5" && RUBY_VERSION < "2.6" require "simplecov" unless %w[false 0].include?(ENV["COV"]) begin @@ -17,6 +17,7 @@ require "awesome_print" require "sidekiq" +require "sidekiq/api" require "sidekiq/util" require "sidekiq-unique-jobs" require "timecop" diff --git a/spec/support/shared_examples/a_performing_worker.rb b/spec/support/shared_examples/a_performing_worker.rb index 3572bac61..ab825478d 100644 --- a/spec/support/shared_examples/a_performing_worker.rb +++ b/spec/support/shared_examples/a_performing_worker.rb @@ -1,24 +1,25 @@ # frozen_string_literal: true RSpec.shared_examples "a performing worker" do |splat_arguments: true| - let(:worker_instance) { instance_spy(described_class) } + let(:worker_instance) { described_class.new } before do allow(described_class).to receive(:new).and_return(worker_instance) + allow(worker_instance).to receive(:perform).with(any_args) end it "receives the expected arguments" do SidekiqUniqueJobs.use_config(enabled: false) do Sidekiq::Testing.inline! do if args == no_args - expect(worker_instance).to receive(:perform).with(no_args) described_class.perform_async + expect(worker_instance).to have_received(:perform).with(no_args) elsif splat_arguments - expect(worker_instance).to receive(:perform).with(*args) described_class.perform_async(*args) + expect(worker_instance).to have_received(:perform).with(*args) else - expect(worker_instance).to receive(:perform).with(args) described_class.perform_async(args) + expect(worker_instance).to have_received(:perform).with(args) end end end diff --git a/spec/unit/sidekiq_unique_jobs/cli_spec.rb b/spec/unit/sidekiq_unique_jobs/cli_spec.rb index 32ca0c34b..378ea466e 100644 --- a/spec/unit/sidekiq_unique_jobs/cli_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/cli_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - require "thor/runner" require "irb" @@ -114,17 +112,21 @@ end end - describe ".console", ruby_ver: ">= 2.5.1" do + describe ".console" do subject(:console) { capture(:stdout) { described_class.start(%w[console]) } } + let(:console_class) { defined?(Pry) ? Pry : IRB } + specify do - expect(Object).to receive(:include).with(SidekiqUniqueJobs::Util).and_return(true) - allow(Pry).to receive(:start).and_return(true) + allow(Object).to receive(:include) + allow(console_class).to receive(:start).and_return(true) expect(console).to eq <<~HEADER Use `keys '*', 1000 to display the first 1000 unique keys matching '*' Use `del '*', 1000, true (default) to see how many keys would be deleted for the pattern '*' Use `del '*', 1000, false to delete the first 1000 keys matching '*' HEADER + + expect(Object).to have_received(:include).with(SidekiqUniqueJobs::Util) end end end diff --git a/spec/unit/sidekiq_unique_jobs/client/middleware_spec.rb b/spec/unit/sidekiq_unique_jobs/client/middleware_spec.rb index 3b4a039ad..6bb379cf5 100644 --- a/spec/unit/sidekiq_unique_jobs/client/middleware_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/client/middleware_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - require "sidekiq/worker" require "sidekiq-unique-jobs" diff --git a/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb b/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb index c98da3de1..6d29bc099 100644 --- a/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe "core_ext.rb" do describe Hash do let(:hash) { { test: :me, not: :me } } diff --git a/spec/unit/sidekiq_unique_jobs/digests_spec.rb b/spec/unit/sidekiq_unique_jobs/digests_spec.rb index 0329b78e8..50029cc81 100644 --- a/spec/unit/sidekiq_unique_jobs/digests_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/digests_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Digests, redis: :redis do before do (1..10).each do |arg| diff --git a/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb index abcbd0e81..08a72f50d 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::BaseLock do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb index 73213c70c..20467d314 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::UntilAndWhileExecuting do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb index f3b7121b9..e632bb09d 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuted do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb index 1d76c678c..72f2b1bbb 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuting do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb index d9d27d6b1..cc6c823ce 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::UntilExpired do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb index be1689dbf..d7c4e6fb7 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::WhileExecutingReject do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb index cad705984..d7a488d36 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/middleware_spec.rb b/spec/unit/sidekiq_unique_jobs/middleware_spec.rb index 27a17982a..2d4aa3fe9 100644 --- a/spec/unit/sidekiq_unique_jobs/middleware_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/middleware_spec.rb @@ -1,46 +1,56 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Middleware do describe SidekiqUniqueJobs do - describe ".configure_middleware" do - it "configures both client and server middleware" do - expect(described_class).to receive(:configure_server_middleware) - expect(described_class).to receive(:configure_client_middleware) + let(:client_config) { class_double(Sidekiq) } + let(:server_config) { class_double(Sidekiq) } + let(:client_middleware) { instance_spy(Sidekiq::Middleware::Chain) } + let(:server_middleware) { instance_spy(Sidekiq::Middleware::Chain) } - described_class.configure_middleware - end + before do + allow(Sidekiq).to receive(:configure_client).and_yield(client_config) + allow(Sidekiq).to receive(:configure_server).and_yield(server_config) + + allow(client_config).to receive(:client_middleware).and_yield(client_middleware) + + allow(server_config).to receive(:client_middleware).and_yield(client_middleware) + allow(server_config).to receive(:server_middleware).and_yield(server_middleware) end - describe ".configure_server_middleware" do - let(:server_config) { class_double(Sidekiq) } - let(:server_middleware) { instance_double(Sidekiq::Middleware::Chain) } - let(:client_middleware) { instance_double(Sidekiq::Middleware::Chain) } + shared_examples "configures client" do + it "adds client middleware when required" do + expect(client_config).to have_received(:client_middleware) + expect(client_middleware).to have_received(:add).with(SidekiqUniqueJobs::Client::Middleware).at_least(:once) + end + end + shared_examples "configures server" do it "adds client and server middleware when required" do - expect(Sidekiq).to receive(:configure_server).and_yield(server_config) + expect(server_config).to have_received(:client_middleware).at_least(:once) + expect(client_middleware).to have_received(:add).with(SidekiqUniqueJobs::Client::Middleware).at_least(:once) - expect(server_config).to receive(:client_middleware).and_yield(client_middleware) - expect(client_middleware).to receive(:add).with(SidekiqUniqueJobs::Client::Middleware) - - expect(server_config).to receive(:server_middleware).and_yield(server_middleware) - expect(server_middleware).to receive(:add).with(SidekiqUniqueJobs::Server::Middleware) - described_class.configure_server_middleware + expect(server_config).to have_received(:server_middleware) + expect(server_middleware).to have_received(:add).with(SidekiqUniqueJobs::Server::Middleware) end end - describe ".configure_client_middleware" do - let(:client_config) { class_double(Sidekiq) } - let(:client_middleware) { instance_double(Sidekiq::Middleware::Chain) } + describe ".configure_middleware" do + before { described_class.configure_middleware } - it "adds client middleware when required" do - expect(Sidekiq).to receive(:configure_client).and_yield(client_config) - expect(client_config).to receive(:client_middleware).and_yield(client_middleware) - expect(client_middleware).to receive(:add).with(SidekiqUniqueJobs::Client::Middleware) + it_behaves_like "configures client" + it_behaves_like "configures server" + end - described_class.configure_client_middleware - end + describe ".configure_server_middleware" do + before { described_class.configure_server_middleware } + + it_behaves_like "configures server" + end + + describe ".configure_client_middleware" do + before { described_class.configure_client_middleware } + + it_behaves_like "configures client" end end end diff --git a/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb b/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb index 937f3eabf..e1bfefa94 100644 --- a/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Normalizer do describe ".jsonify" do specify do diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb index c2527454a..4d620c041 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::OnConflict::Log do let(:strategy) { described_class.new(item) } let(:unique_digest) { "uniquejobs:random-digest-value" } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb index 63d010ecd..86f3bd44c 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::OnConflict::Raise do let(:strategy) { described_class.new(item) } let(:unique_digest) { "uniquejobs:random-digest-value" } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb index ee0dc6b7e..ffe60cc37 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::OnConflict::Reject do include_context "with a stubbed locksmith" let(:strategy) { described_class.new(item) } @@ -29,20 +27,26 @@ subject(:send_to_deadset) { strategy.send_to_deadset } context "when deadset_kill?" do - before { allow(strategy).to receive(:deadset_kill?).and_return(true) } + before do + allow(strategy).to receive(:deadset_kill?).and_return(true) + allow(strategy).to receive(:deadset_kill) + send_to_deadset + end it "calls deadset_kill" do - expect(strategy).to receive(:deadset_kill) - send_to_deadset + expect(strategy).to have_received(:deadset_kill) end end context "when not deadset_kill?" do - before { allow(strategy).to receive(:deadset_kill?).and_return(false) } + before do + allow(strategy).to receive(:deadset_kill?).and_return(false) + allow(strategy).to receive(:push_to_deadset) + send_to_deadset + end it "calls push_to_deadset" do - expect(strategy).to receive(:push_to_deadset) - send_to_deadset + expect(strategy).to have_received(:push_to_deadset) end end end @@ -51,20 +55,26 @@ subject(:deadset_kill) { strategy.deadset_kill } context "when kill_with_options?" do - before { allow(strategy).to receive(:kill_with_options?).and_return(true) } + before do + allow(strategy).to receive(:kill_with_options?).and_return(true) + allow(strategy).to receive(:kill_job_with_options) + deadset_kill + end it "calls kill_job_with_options" do - expect(strategy).to receive(:kill_job_with_options) - deadset_kill + expect(strategy).to have_received(:kill_job_with_options) end end context "when not kill_with_options?" do - before { allow(strategy).to receive(:kill_with_options?).and_return(false) } + before do + allow(strategy).to receive(:kill_with_options?).and_return(false) + allow(strategy).to receive(:kill_job_without_options) + deadset_kill + end it "calls kill_job_without_options" do - expect(strategy).to receive(:kill_job_without_options) - deadset_kill + expect(strategy).to have_received(:kill_job_without_options) end end end @@ -72,18 +82,26 @@ describe "#kill_job_with_options" do subject(:kill_job_with_options) { strategy.kill_job_with_options } - it "calls deadset.kill with options hash", sidekiq_ver: ">= 5.1.0" do - expect(deadset).to receive(:kill).with(payload, notify_failure: false) + before do + allow(deadset).to receive(:kill) kill_job_with_options end + + it "calls deadset.kill with options hash", sidekiq_ver: ">= 5.1.0" do + expect(deadset).to have_received(:kill).with(payload, notify_failure: false) + end end describe "#kill_job_without_options" do subject(:kill_job_without_options) { strategy.kill_job_without_options } - it "calls deadset.kill without options hash", sidekiq_ver: ">= 5.0.0 && < 5.1.0" do - expect(deadset).to receive(:kill).with(payload) + before do + allow(deadset).to receive(:kill) kill_job_without_options end + + it "calls deadset.kill without options hash", sidekiq_ver: ">= 5.0.0 && < 5.1.0" do + expect(deadset).to have_received(:kill).with(payload) + end end end diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb index d30330104..d9d8a6941 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::OnConflict::Replace, redis: :redis do let(:strategy) { described_class.new(item) } let(:unique_digest) { "uniquejobs:56c68cab5038eb57959538866377560d" } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb index 2b02d8d8a..65549be68 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::OnConflict::Reschedule do let(:strategy) { described_class.new(item) } let(:unique_digest) { "uniquejobs:random-digest-value" } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb index 53c2311f3..71c3a1885 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::OnConflict::Strategy, redis: :redis do let(:strategy) { described_class.new(item) } let(:unique_digest) { "uniquejobs:56c68cab5038eb57959538866377560d" } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb index 438f3ed6d..bd7ac6ae9 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::OnConflict do describe "::STRAGEGIES" do subject { described_class::STRATEGIES } diff --git a/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb b/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb index 3c1e0dbf4..6a60e971f 100644 --- a/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::OptionsWithFallback do class ClassWithOptions include SidekiqUniqueJobs::OptionsWithFallback diff --git a/spec/unit/sidekiq_unique_jobs/server/middleware_spec.rb b/spec/unit/sidekiq_unique_jobs/server/middleware_spec.rb index a16669760..91d869eca 100644 --- a/spec/unit/sidekiq_unique_jobs/server/middleware_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/server/middleware_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - # rubocop:disable RSpec/InstanceVariable RSpec.describe SidekiqUniqueJobs::Server::Middleware do let(:middleware) { described_class.new } diff --git a/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb b/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb index 28f064392..07517bd96 100644 --- a/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true -require "spec_helper" - -RSpec.describe Sidekiq::Api, redis: :redis do +RSpec.describe "Sidekiq::Api", redis: :redis do let(:item) do { "class" => "JustAWorker", "queue" => "testqueue", diff --git a/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb b/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb index da58f8344..5afd9ea3f 100644 --- a/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::SidekiqWorkerMethods do class WorkerWithSidekiqMethods include SidekiqUniqueJobs::SidekiqWorkerMethods diff --git a/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb b/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb index f24c6468d..fb05fafe6 100644 --- a/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Timeout::Calculator do let(:calculator) { described_class.new("class" => worker_class_name, "at" => schedule_time) } let(:worker_class_name) { "MyUniqueJob" } diff --git a/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb b/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb index eb2334635..899c13f9b 100644 --- a/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::UniqueArgs do let(:unique_args) { described_class.new(item) } let(:worker_class) { UntilExecutedJob } @@ -97,6 +95,9 @@ describe "#unique_args_enabled?" do subject(:unique_args_enabled?) { unique_args.unique_args_enabled? } + shared_examples "" do + end + with_default_worker_options(unique: :until_executed, unique_args: ->(args) { args[1]["test"] }) do with_sidekiq_options_for(UntilExecutedJob, unique_args: :unique_args) do it { is_expected.to eq(:unique_args) } diff --git a/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb b/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb index f9e438aff..653866818 100644 --- a/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Unlockable, redis: :redis do def item_with_digest SidekiqUniqueJobs::UniqueArgs.digest(item) diff --git a/spec/unit/sidekiq_unique_jobs/util_spec.rb b/spec/unit/sidekiq_unique_jobs/util_spec.rb index 4a46a47e5..bb9ea4093 100644 --- a/spec/unit/sidekiq_unique_jobs/util_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/util_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs::Util, redis: :redis do let(:item_hash) do { @@ -35,16 +33,17 @@ end shared_context "with an old lock" do - before do - result = SidekiqUniqueJobs::Scripts.call( + let!(:old_lock) do + SidekiqUniqueJobs::Scripts.call( :acquire_lock, nil, keys: [unique_digest], argv: [jid, 7200], ) - expect(result).to eq(1) - expect(described_class.keys).to include(unique_digest) end + + specify { expect(old_lock).to eq(1) } + specify { expect(described_class.keys).to include(unique_digest) } end describe ".keys" do diff --git a/spec/unit/sidekiq_unique_jobs_spec.rb b/spec/unit/sidekiq_unique_jobs_spec.rb index ea6528f01..f417526ef 100644 --- a/spec/unit/sidekiq_unique_jobs_spec.rb +++ b/spec/unit/sidekiq_unique_jobs_spec.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require "spec_helper" - RSpec.describe SidekiqUniqueJobs do describe ".config" do subject(:config) { described_class.config } From cf832a72c312bfb6eefddf71cc4854c6e250e081 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 17:48:23 +0100 Subject: [PATCH 11/23] Strip trailing whitespace in markdown --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index aaeaf0ab6..174dec6ed 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,4 +11,4 @@ indent_style = space indent_size = 2 [*.{md,slim,haml}] -trim_trailing_whitespace = false +trim_trailing_whitespace = true From b109683a533f08cce260ea5a9b2d6f7db9d7d3f6 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 18:06:19 +0100 Subject: [PATCH 12/23] Update tools --- Rakefile | 14 +++++++++----- lib/tasks/changelog.rake | 9 +++++++-- update_docs.sh | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 7 deletions(-) create mode 100755 update_docs.sh diff --git a/Rakefile b/Rakefile index 96cecfedc..0d4953197 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,5 @@ # frozen_string_literal: true -require "bundler/gem_tasks" require "rspec/core/rake_task" require "rubocop/rake_task" @@ -11,15 +10,20 @@ RSpec::Core::RakeTask.new(:spec) require "yard" YARD::Rake::YardocTask.new do |t| - t.files = %w[lib/**/*.rb"] + t.files = %w[lib/sidekiq_unique_jobs/**/*.rb"] t.options = %w[ --no-private - --output-dir docs - --readme README.md - --output-dir docs --markup=markdown --markup-provider=redcarpet + --readme README.md ] end task default: [:style, :spec] + +task :release do + sh("./update_docs.sh") + sh("gem release --tag --push") + Rake::Task["changelog"].invoke + sh("gem bump") +end diff --git a/lib/tasks/changelog.rake b/lib/tasks/changelog.rake index 72ae7f0af..3d03d2e92 100644 --- a/lib/tasks/changelog.rake +++ b/lib/tasks/changelog.rake @@ -3,7 +3,7 @@ desc "Generate a Changelog" task :changelog do # rubocop:disable Style/MutableConstant - CHANGELOG_COMMAND ||= %w[ + CHANGELOG_CMD ||= %w[ github_changelog_generator -u mhenrixon @@ -12,7 +12,12 @@ task :changelog do --no-verbose --token ] + ADD_CHANGELOG_CMD ||= "git add --all" + COMMIT_CHANGELOG_CMD ||= "git commit -a -m 'Update changelog'" # rubocop:enable Style/MutableConstant - sh(*CHANGELOG_COMMAND.push(ENV["CHANGELOG_GITHUB_TOKEN"])) + sh("git checkout master") + sh(*CHANGELOG_CMD.push(ENV["CHANGELOG_GITHUB_TOKEN"])) + sh(ADD_CHANGELOG_CMD) + sh(COMMIT_CHANGELOG_CMD) end diff --git a/update_docs.sh b/update_docs.sh new file mode 100755 index 000000000..085a9957b --- /dev/null +++ b/update_docs.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +git checkout master +git fetch +stash_created=0 + +if [[ "$(git diff --stat)" != "" ]]; then + stash_created=1 + git stash push -u -a -m "Before updating docs" +fi; + +git pull --rebase + +rake yard + +git checkout gh-pages + +echo "Cleaning up current documentation" +find . ! -path '*/.git*' ! -path '*/doc*' ! -path '*/update_docs.sh*' ! -path '*/_config.yml*' ! -path '*/_index.html*' ! -path '.' | xargs rm -rf + +echo "Copying new documentation" +mv doc/* ./ + +echo "Sending new documentation to github" +git add --all +git commit -a -m 'Update documentation' +git push --force + +if [[ $stash_created == 1 ]]; then + git stash pop +fi; + +git checkout master From 29d2f59a487b47fc18c7699f9efc77407a57607f Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 18:06:28 +0100 Subject: [PATCH 13/23] Ignore doc folder --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 4785f39cd..593365911 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ rails_example/spec/examples.txt /.byebug_history /.yardoc/ + +/docs/ From 4b3139d4dd47db4417f7555c21d92d180d78b6ae Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 18:06:36 +0100 Subject: [PATCH 14/23] Refresh README --- README.md | 101 ++++++++++++++++++++---------------------------------- 1 file changed, 37 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 493b738b3..a86c627e6 100644 --- a/README.md +++ b/README.md @@ -41,61 +41,57 @@ - - ## Introduction The goal of this gem is to ensure your Sidekiq jobs are unique. We do this by creating unique keys in Redis based on how you configure uniqueness. - ## Documentation -This is the documentation for the master branch. You can find the documentation for each release by navigating to its tag: https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10. +This is the documentation for the master branch. You can find the documentation for each release by navigating to its tag: [v5.0.10][] Below are links to the latest major versions (4 & 5): -- [v5.0.10](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10) -- [v4.0.18](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.18) +- [v5.0.10][] +- [v4.0.18][] - ## Requirements -See https://github.com/mperham/sidekiq#requirements for what is required. Starting from 5.0.0 only sidekiq >= 4 is supported and support for MRI <= 2.1 is dropped. ActiveJob is not supported +See [Sidekiq requirements][] for what is required. Starting from 5.0.0 only sidekiq >= 4 is supported and support for MRI <= 2.1 is dropped. ActiveJob is not supported Version 6 requires Redis >= 3 and pure Sidekiq, no ActiveJob supported anymore. See [About ActiveJob](https://github.com/mhenrixon/sidekiq-unique-jobs/wiki/About-ActiveJob) for why. - ## Installation Add this line to your application's Gemfile: - gem 'sidekiq-unique-jobs' +``` +gem 'sidekiq-unique-jobs' +``` And then execute: - $ bundle +``` +bundle +``` Or install it yourself as: - $ gem install sidekiq-unique-jobs - +``` +gem install sidekiq-unique-jobs +``` - ## Support Me -Want to show me some ❤️ for the hard work I do on this gem? You can use the following PayPal link https://paypal.me/mhenrixon. Any amount is welcome and let me tell you it feels good to be appreciated. Even a dollar makes me super excited about all of this. +Want to show me some ❤️ for the hard work I do on this gem? You can use the following [PayPal link][]. Any amount is welcome and let me tell you it feels good to be appreciated. Even a dollar makes me super excited about all of this. - ## General Information See [Interaction w/ Sidekiq](https://github.com/mhenrixon/sidekiq-unique-jobs/wiki/How-this-gem-interacts-with-Sidekiq) on how the gem interacts with Sidekiq. See [Locking & Unlocking](https://github.com/mhenrixon/sidekiq-unique-jobs/wiki/Locking-&-Unlocking) for an overview of the differences on when the various lock types are locked and unlocked. - ## Options - ### Lock Expiration This is probably not the configuration option you want... @@ -109,7 +105,6 @@ sidekiq_options lock_expiration: nil # default - don't expire keys sidekiq_options lock_expiration: 20.days # expire this lock in 20 days ``` - ### Lock Timeout This is the timeout (how long to wait) when creating the lock. By default we don't use a timeout so we won't wait for the lock to be created. If you want it is possible to set this like below. @@ -120,7 +115,6 @@ sidekiq_options lock_timeout: 5 # wait 5 seconds sidekiq_options lock_timeout: nil # lock indefinitely, this process won't continue until it gets a lock. VERY DANGEROUS!! ``` - ### Unique Across Queues This configuration option is slightly misleading. It doesn't disregard the queue on other jobs. Just on itself, this means that a worker that might schedule jobs into multiple queues will be able to have uniqueness enforced on all queues it is pushed to. @@ -128,7 +122,7 @@ This configuration option is slightly misleading. It doesn't disregard the queue ```ruby class Worker include Sidekiq::Worker - + sidekiq_options unique_across_queues: true, queue: 'default' def perform(args); end @@ -137,7 +131,6 @@ end Now if you push override the queue with `Worker.set(queue: 'another').perform_async(1)` it will still be considered unique when compared to `Worker.perform_async(1)` (that was actually pushed to the queue `default`). - ### Unique Across Workers This configuration option is slightly misleading. It doesn't disregard the worker class on other jobs. Just on itself, this means that a worker that the worker class won't be used for generating the unique digest. The only way this option really makes sense is when you want to have uniqueness between two different worker classes. @@ -145,7 +138,7 @@ This configuration option is slightly misleading. It doesn't disregard the worke ```ruby class WorkerOne include Sidekiq::Worker - + sidekiq_options unique_across_workers: true, queue: 'default' def perform(args); end @@ -153,24 +146,22 @@ end class WorkerTwo include Sidekiq::Worker - + sidekiq_options unique_across_workers: true, queue: 'default' def perform(args); end end -WorkerOne.perform_async(1) +WorkerOne.perform_async(1) # => 'the jobs unique id' -WorkerTwo.perform_async(1) +WorkerTwo.perform_async(1) # => nil because WorkerOne just stole the lock ``` - ## Locks - ### Until Executing Locks from when the client pushes the job to the queue. Will be unlocked before the server starts processing the job. @@ -181,7 +172,6 @@ Locks from when the client pushes the job to the queue. Will be unlocked before sidekiq_options lock: :until_executing ``` - ### Until Executed Locks from when the client pushes the job to the queue. Will be unlocked when the server has successfully processed the job. @@ -190,7 +180,6 @@ Locks from when the client pushes the job to the queue. Will be unlocked when th sidekiq_options lock: :until_executed ``` - ### Until Timeout Locks from when the client pushes the job to the queue. Will be unlocked when the specified timeout has been reached. @@ -199,7 +188,6 @@ Locks from when the client pushes the job to the queue. Will be unlocked when th sidekiq_options lock: :until_expired ``` - ### Unique Until And While Executing Locks when the client pushes the job to the queue. The queue will be unlocked when the server starts processing the job. The server then goes on to creating a runtime lock for the job to prevent simultaneous jobs from being executed. As soon as the server starts processing a job, the client can push the same job to the queue. @@ -208,7 +196,6 @@ Locks when the client pushes the job to the queue. The queue will be unlocked wh sidekiq_options lock: :until_and_while_executing ``` - ### While Executing With this lock type it is possible to put any number of these jobs on the queue, but as the server pops the job from the queue it will create a lock and then wait until other locks are done processing. It _looks_ like multiple jobs are running at the same time but in fact the second job will only be waiting for the first job to finish. @@ -238,54 +225,47 @@ In the console you should see something like: 10:33:04 worker.1 | 2017-04-23T08:33:04.973Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: done: 40.014 sec ``` - ## Conflict Strategy -Decides how we handle conflict. We can either reject the job to the dead queue or reschedule it. Both are useful for jobs that absolutely need to run and have been configured to use the lock `WhileExecuting` that is used only by the sidekiq server process. +Decides how we handle conflict. We can either reject the job to the dead queue or reschedule it. Both are useful for jobs that absolutely need to run and have been configured to use the lock `WhileExecuting` that is used only by the sidekiq server process. The last one is log which can be be used with the lock `UntilExecuted` and `UntilExpired`. Now we write a log entry saying the job could not be pushed because it is a duplicate of another job with the same arguments - ### Log This strategy is intended to be used with `UntilExecuted` and `UntilExpired`. It will log a line about that this is job is a duplicate of another. `sidekiq_options lock: :until_executed, on_conflict: :log` - ### Raise This strategy is intended to be used with `WhileExecuting`. Basically it will allow us to let the server process crash with a specific error message and be retried without messing up the Sidekiq stats. `sidekiq_options lock: :while_executing, on_conflict: :raise, retry: 10` - ### Reject This strategy is intended to be used with `WhileExecuting` and will push the job to the dead queue on conflict. `sidekiq_options lock: :while_executing, on_conflict: :reject` - ### Replace This strategy is intended to be used with client locks like `UntilExecuted`. It will delete any existing job for these arguments from retry, schedule and -queue and retry the lock again. +queue and retry the lock again. -This is slightly dangerous and should probably only be used for jobs that are +This is slightly dangerous and should probably only be used for jobs that are always scheduled in the future. Currently only attempting to retry one time. `sidekiq_options lock: :until_executed, on_conflict: :replace` - ### Reschedule This strategy is intended to be used with `WhileExecuting` and will delay the job to be tried again in 5 seconds. This will mess up the sidekiq stats but will prevent exceptions from being logged and confuse your sysadmins. `sidekiq_options lock: :while_executing, on_conflict: :reschedule` - ## Usage All that is required is that you specifically set the sidekiq option for _unique_ to a valid value like below: @@ -296,7 +276,6 @@ sidekiq_options lock: :while_executing Requiring the gem in your gemfile should be sufficient to enable unique jobs. - ### Finer Control over Uniqueness Sometimes it is desired to have a finer control over which arguments are used in determining uniqueness of the job, and others may be _transient_. For this use-case, you need to define either a `unique_args` method, or a ruby proc. @@ -348,10 +327,9 @@ class UniqueJobWithFilterMethod end ``` - ### After Unlock Callback -If you need to perform any additional work after the lock has been released you can provide an `#after_unlock` instance method. The method will be called when the lock has been unlocked. Most times this means after yield but there are two exceptions to that. +If you need to perform any additional work after the lock has been released you can provide an `#after_unlock` instance method. The method will be called when the lock has been unlocked. Most times this means after yield but there are two exceptions to that. **Exception 1:** UntilExecuting unlocks and calls back before yielding. **Exception 2:** UntilExpired expires eventually, no after_unlock hook is called. @@ -368,7 +346,6 @@ class UniqueJobWithFilterMethod end. ``` - ### Logging To see logging in sidekiq when duplicate payload has been filtered out you can enable on a per worker basis using the sidekiq options. The default value is false @@ -384,7 +361,6 @@ class UniqueJobWithFilterMethod end ``` - ### Cleanup Dead Locks For sidekiq versions before 5.1 a `sidekiq_retries_exhausted` block is required per worker class. @@ -408,12 +384,10 @@ Sidekiq.configure_server do |config| end ``` - ## Debugging There are several ways of removing keys that are stuck. The prefered way is by using the unique extension to `Sidekiq::Web`. The old console and command line versions still work but might be deprecated in the future. It is better to search for the digest itself and delete the keys matching that digest. - ### Sidekiq Web To use the web extension you need to require it in your routes. @@ -424,33 +398,28 @@ require 'sidekiq_unique_jobs/web' mount Sidekiq::Web, at: '/sidekiq' ``` -There is no need to `require 'sidekiq/web'` since `sidekiq_unique_jobs/web` +There is no need to `require 'sidekiq/web'` since `sidekiq_unique_jobs/web` already does this. To filter/search for keys we can use the wildcard `*`. If we have a unique digest `'uniquejobs:9e9b5ce5d423d3ea470977004b50ff84` we can search for it by enter `*ff84` and it should return all digests that end with `ff84`. - - #### Show Unique Digests ![Unique Digests](assets/unique_digests_1.png) - #### Show keys for digest ![Unique Digests](assets/unique_digests_2.png) - ## Communication There is a [![Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs](https://badges.gitter.im/mhenrixon/sidekiq-unique-jobs.svg)](https://gitter.im/mhenrixon/sidekiq-unique-jobs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) for praise or scorn. This would be a good place to have lengthy discuss or brilliant suggestions or simply just nudge me if I forget about anything. - ## Testing This has been probably the most confusing part of this gem. People get really confused with how unreliable the unique jobs have been. I there for decided to do what Mike is doing for sidekiq enterprise. Read the section about unique jobs. -https://www.dailydrip.com/topics/sidekiq/drips/sidekiq-enterprise-unique-jobs +[Enterprise unique jobs][] ```ruby SidekiqUniqueJobs.configure do |config| @@ -496,17 +465,21 @@ I would strongly suggest you let this gem test uniqueness. If you care about how - [spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb) - [spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb) - ## Contributing 1. Fork it -2. Create your feature branch (`git checkout -b my-new-feature`) -3. Commit your changes (`git commit -am 'Add some feature'`) -4. Push to the branch (`git push origin my-new-feature`) -5. Create new Pull Request +1. Create your feature branch (`git checkout -b my-new-feature`) +1. Commit your changes (`git commit -am 'Add some feature'`) +1. Push to the branch (`git push origin my-new-feature`) +1. Create new Pull Request +## Contributors - -## Contributors +You can find a list of contributors over on [Contributors][] -You can find a list of contributors over on https://github.com/mhenrixon/sidekiq-unique-jobs/graphs/contributors +[v5.0.10]: https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10. +[v4.0.18]: https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.18 +[Sidekiq requirements]: https://github.com/mperham/sidekiq#requirements +[Enterprise unique jobs]: https://www.dailydrip.com/topics/sidekiq/drips/sidekiq-enterprise-unique-jobs +[Contributors]: https://github.com/mhenrixon/sidekiq-unique-jobs/graphs/contributors +[Paypal link https://paypal.me/mhenrixon]: https://paypal.me/mhenrixon From 07b34b6bd9670ef0af63510b646ed84815117ec7 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 19:08:43 +0100 Subject: [PATCH 15/23] Trigger travis From 32a29451e7e9461f17dfc5121885db92e97c946e Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 19:29:52 +0100 Subject: [PATCH 16/23] Require spec_helper --- .gitignore | 33 +++++++++++---------------------- .travis.yml | 2 +- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 593365911..142d87979 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,17 @@ - *.gem - +*.sublime-* +*.sw? .DS_Store - -Gemfile.lock - -.ruby-version .idea/ -gemfiles/*.lock -*.sw? -coverage/ -tmp/ -rails_example/spec/examples.txt - -*.sublime-* - -/sidekiq/ - .rspec_status - -/gemfiles/.bundle/ - +.ruby-version /.byebug_history - /.yardoc/ - -/docs/ +/doc*/ +/gemfiles/.bundle/ +/sidekiq/ +coverage/ +Gemfile.lock +gemfiles/*.lock +rails_example/spec/examples.txt +tmp/ diff --git a/.travis.yml b/.travis.yml index 40cff33f4..b20423229 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ before_script: script: - if [[ "${COV}" = "true" ]]; then bundle exec rubocop -P; fi; - - bundle exec rspec + - bundle exec rspec --require spec_helper after_script: - if [[ "${COV}" = "true" ]]; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT; fi; From bf74e09110028a651fce681a28b54b70ec138438 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 19:33:04 +0100 Subject: [PATCH 17/23] Move incompatible gems to gemfile --- Gemfile | 7 +++++++ sidekiq-unique-jobs.gemspec | 12 ------------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Gemfile b/Gemfile index b492e1bd0..88f3a39f2 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,10 @@ gem "rspec-retry", require: false platforms :mri_25 do gem "benchmark-ips" gem "fasterer" + gem "fuubar" + gem "gem-release" + gem "github-markup" + gem "github_changelog_generator" gem "guard" gem "guard-reek" gem "guard-rspec" @@ -19,8 +23,11 @@ platforms :mri_25 do gem "memory_profiler" gem "pry" gem "rb-readline" + gem "redcarpet" gem "reek", ">= 5.3" gem "rubocop" gem "rubocop-rspec" gem "simplecov-json" + gem "travis" + gem "yard" end diff --git a/sidekiq-unique-jobs.gemspec b/sidekiq-unique-jobs.gemspec index 5ffe5a46c..0bc08ff8e 100644 --- a/sidekiq-unique-jobs.gemspec +++ b/sidekiq-unique-jobs.gemspec @@ -45,16 +45,4 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rspec", "~> 3.7" spec.add_development_dependency "sinatra" spec.add_development_dependency "timecop", "~> 0.9" - - # ===== Utilities ===== - spec.add_development_dependency "travis", ">= 1.8.9" - - # ===== Documentation ===== - spec.add_development_dependency "github-markup", "~> 3.0" - spec.add_development_dependency "github_changelog_generator", "~> 1.14" - spec.add_development_dependency "redcarpet", "~> 3.4" - spec.add_development_dependency "yard", "~> 0.9.18" - - # ===== Release Management ===== - spec.add_development_dependency "gem-release", ">= 2.0" end From 46132ff40528227b54cb7cbe963c0e7fbd9ebf6c Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 19:47:20 +0100 Subject: [PATCH 18/23] Refresh changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fb6a8622..4a7d54e0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -793,4 +793,4 @@ ## [v2.1.0](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v2.1.0) (2012-08-07) -\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* \ No newline at end of file From 3b5383273d515608a047d0822ea6862d96a1f9be Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 19:50:03 +0100 Subject: [PATCH 19/23] Travis doesn't load .rspec --- spec/examples/another_unique_job_spec.rb | 2 +- spec/examples/custom_queue_job_spec.rb | 2 +- spec/examples/custom_queue_job_with_filter_method_spec.rb | 2 +- spec/examples/custom_queue_job_with_filter_proc_spec.rb | 2 +- spec/examples/expiring_job_spec.rb | 2 +- spec/examples/inline_worker_spec.rb | 2 +- spec/examples/just_a_worker_spec.rb | 2 +- spec/examples/long_running_job_spec.rb | 2 +- spec/examples/main_job_spec.rb | 2 +- spec/examples/my_job_spec.rb | 2 +- spec/examples/my_unique_job_spec.rb | 2 +- spec/examples/my_unique_job_with_filter_method_spec.rb | 2 +- spec/examples/my_unique_job_with_filter_proc_spec.rb | 2 +- spec/examples/notify_worker_spec.rb | 2 +- spec/examples/plain_class_spec.rb | 2 +- spec/examples/simple_worker_spec.rb | 2 +- spec/examples/spawn_simple_worker_spec.rb | 2 +- spec/examples/test_class_spec.rb | 2 +- spec/examples/unique_across_workers_job_spec.rb | 2 +- spec/examples/unique_job_on_conflict_raise_spec.rb | 2 +- spec/examples/unique_job_on_conflict_reject_spec.rb | 2 +- spec/examples/unique_job_on_conflict_reschedule_spec.rb | 2 +- spec/examples/unique_job_with_nil_unique_args_spec.rb | 2 +- spec/examples/unique_job_with_no_unique_args_method_spec.rb | 2 +- spec/examples/unique_job_without_unique_args_parameter_spec.rb | 2 +- spec/examples/unique_on_all_queues_job_spec.rb | 2 +- spec/examples/until_and_while_executing_job_spec.rb | 2 +- spec/examples/until_executed2_job_spec.rb | 2 +- spec/examples/until_executed_job_spec.rb | 2 +- spec/examples/until_executing_job_spec.rb | 2 +- spec/examples/until_expired_job_spec.rb | 2 +- spec/examples/until_global_expired_job_spec.rb | 2 +- spec/examples/while_executing_job_spec.rb | 2 +- spec/examples/without_argument_job_spec.rb | 2 +- spec/integration/sidekiq/retry_set_spec.rb | 2 +- spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb | 2 +- .../sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb | 2 +- .../sidekiq_unique_jobs/lock/until_executed_spec.rb | 2 +- .../sidekiq_unique_jobs/lock/until_executing_spec.rb | 2 +- .../integration/sidekiq_unique_jobs/lock/until_expired_spec.rb | 2 +- .../sidekiq_unique_jobs/lock/while_executing_reject_spec.rb | 2 +- .../sidekiq_unique_jobs/lock/while_executing_spec.rb | 2 +- spec/integration/sidekiq_unique_jobs/locksmith_spec.rb | 2 +- spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb | 2 +- spec/spec_helper.rb | 3 +-- spec/unit/sidekiq_unique_jobs/core_ext_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/digests_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb | 2 +- .../sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb | 2 +- .../sidekiq_unique_jobs/lock/while_executing_reject_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/middleware_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/normalizer_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/unique_args_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/unlockable_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs/util_spec.rb | 2 +- spec/unit/sidekiq_unique_jobs_spec.rb | 2 +- 71 files changed, 71 insertions(+), 71 deletions(-) diff --git a/spec/examples/another_unique_job_spec.rb b/spec/examples/another_unique_job_spec.rb index 5f5978476..f70e39185 100644 --- a/spec/examples/another_unique_job_spec.rb +++ b/spec/examples/another_unique_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe AnotherUniqueJob, redis: :redis do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/custom_queue_job_spec.rb b/spec/examples/custom_queue_job_spec.rb index 289e1c553..a5ea3302c 100644 --- a/spec/examples/custom_queue_job_spec.rb +++ b/spec/examples/custom_queue_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe CustomQueueJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/custom_queue_job_with_filter_method_spec.rb b/spec/examples/custom_queue_job_with_filter_method_spec.rb index 3e1deba9a..fb39aaaba 100644 --- a/spec/examples/custom_queue_job_with_filter_method_spec.rb +++ b/spec/examples/custom_queue_job_with_filter_method_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe CustomQueueJobWithFilterMethod do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/custom_queue_job_with_filter_proc_spec.rb b/spec/examples/custom_queue_job_with_filter_proc_spec.rb index 9c2a53f07..648e12821 100644 --- a/spec/examples/custom_queue_job_with_filter_proc_spec.rb +++ b/spec/examples/custom_queue_job_with_filter_proc_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe CustomQueueJobWithFilterProc do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/expiring_job_spec.rb b/spec/examples/expiring_job_spec.rb index fe7536a5b..ad07bacf3 100644 --- a/spec/examples/expiring_job_spec.rb +++ b/spec/examples/expiring_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe ExpiringJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/inline_worker_spec.rb b/spec/examples/inline_worker_spec.rb index fdf5c873a..2a160a68e 100644 --- a/spec/examples/inline_worker_spec.rb +++ b/spec/examples/inline_worker_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe InlineWorker do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/just_a_worker_spec.rb b/spec/examples/just_a_worker_spec.rb index a8117f06e..7c80bdd59 100644 --- a/spec/examples/just_a_worker_spec.rb +++ b/spec/examples/just_a_worker_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe JustAWorker do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/long_running_job_spec.rb b/spec/examples/long_running_job_spec.rb index b20f308b3..87acf08c0 100644 --- a/spec/examples/long_running_job_spec.rb +++ b/spec/examples/long_running_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe LongRunningJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/main_job_spec.rb b/spec/examples/main_job_spec.rb index 558be2d08..cdca801e4 100644 --- a/spec/examples/main_job_spec.rb +++ b/spec/examples/main_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe MainJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/my_job_spec.rb b/spec/examples/my_job_spec.rb index ed1792126..58c73a746 100644 --- a/spec/examples/my_job_spec.rb +++ b/spec/examples/my_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe MyJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/my_unique_job_spec.rb b/spec/examples/my_unique_job_spec.rb index a9e8d33e7..d4d3887ce 100644 --- a/spec/examples/my_unique_job_spec.rb +++ b/spec/examples/my_unique_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe MyUniqueJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/my_unique_job_with_filter_method_spec.rb b/spec/examples/my_unique_job_with_filter_method_spec.rb index 5aab178c6..60801e4e4 100644 --- a/spec/examples/my_unique_job_with_filter_method_spec.rb +++ b/spec/examples/my_unique_job_with_filter_method_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe MyUniqueJobWithFilterMethod do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/my_unique_job_with_filter_proc_spec.rb b/spec/examples/my_unique_job_with_filter_proc_spec.rb index b556bf9b2..d0bfee19d 100644 --- a/spec/examples/my_unique_job_with_filter_proc_spec.rb +++ b/spec/examples/my_unique_job_with_filter_proc_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe MyUniqueJobWithFilterProc do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/notify_worker_spec.rb b/spec/examples/notify_worker_spec.rb index 84098fd89..1d48e6eb5 100644 --- a/spec/examples/notify_worker_spec.rb +++ b/spec/examples/notify_worker_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe NotifyWorker do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/plain_class_spec.rb b/spec/examples/plain_class_spec.rb index 01b3f037c..7fb44457b 100644 --- a/spec/examples/plain_class_spec.rb +++ b/spec/examples/plain_class_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe PlainClass do describe ".run" do subject { described_class.run(arg) } diff --git a/spec/examples/simple_worker_spec.rb b/spec/examples/simple_worker_spec.rb index 60954f3e6..a5bf4b67d 100644 --- a/spec/examples/simple_worker_spec.rb +++ b/spec/examples/simple_worker_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SimpleWorker do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/spawn_simple_worker_spec.rb b/spec/examples/spawn_simple_worker_spec.rb index f25c85fbd..06a25d4fb 100644 --- a/spec/examples/spawn_simple_worker_spec.rb +++ b/spec/examples/spawn_simple_worker_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SpawnSimpleWorker do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/test_class_spec.rb b/spec/examples/test_class_spec.rb index c26cf1686..58c9ce149 100644 --- a/spec/examples/test_class_spec.rb +++ b/spec/examples/test_class_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe TestClass do describe ".run" do subject { described_class.run(arg) } diff --git a/spec/examples/unique_across_workers_job_spec.rb b/spec/examples/unique_across_workers_job_spec.rb index fbf2f415d..b03a548d2 100644 --- a/spec/examples/unique_across_workers_job_spec.rb +++ b/spec/examples/unique_across_workers_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UniqueAcrossWorkersJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_on_conflict_raise_spec.rb b/spec/examples/unique_job_on_conflict_raise_spec.rb index aeb917e0c..8ab2db595 100644 --- a/spec/examples/unique_job_on_conflict_raise_spec.rb +++ b/spec/examples/unique_job_on_conflict_raise_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UniqueJobOnConflictRaise do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_on_conflict_reject_spec.rb b/spec/examples/unique_job_on_conflict_reject_spec.rb index 65b21a0db..77bfca75a 100644 --- a/spec/examples/unique_job_on_conflict_reject_spec.rb +++ b/spec/examples/unique_job_on_conflict_reject_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UniqueJobOnConflictReject do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_on_conflict_reschedule_spec.rb b/spec/examples/unique_job_on_conflict_reschedule_spec.rb index 2a2f334dd..1d411502f 100644 --- a/spec/examples/unique_job_on_conflict_reschedule_spec.rb +++ b/spec/examples/unique_job_on_conflict_reschedule_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UniqueJobOnConflictReschedule do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_with_nil_unique_args_spec.rb b/spec/examples/unique_job_with_nil_unique_args_spec.rb index c2cf06994..2621cd957 100644 --- a/spec/examples/unique_job_with_nil_unique_args_spec.rb +++ b/spec/examples/unique_job_with_nil_unique_args_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UniqueJobWithNilUniqueArgs do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_with_no_unique_args_method_spec.rb b/spec/examples/unique_job_with_no_unique_args_method_spec.rb index 0f6a470bb..697988184 100644 --- a/spec/examples/unique_job_with_no_unique_args_method_spec.rb +++ b/spec/examples/unique_job_with_no_unique_args_method_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UniqueJobWithNoUniqueArgsMethod do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_job_without_unique_args_parameter_spec.rb b/spec/examples/unique_job_without_unique_args_parameter_spec.rb index 690ef2136..3cd815b8a 100644 --- a/spec/examples/unique_job_without_unique_args_parameter_spec.rb +++ b/spec/examples/unique_job_without_unique_args_parameter_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UniqueJobWithoutUniqueArgsParameter do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/unique_on_all_queues_job_spec.rb b/spec/examples/unique_on_all_queues_job_spec.rb index f78fd42f1..78540235e 100644 --- a/spec/examples/unique_on_all_queues_job_spec.rb +++ b/spec/examples/unique_on_all_queues_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UniqueOnAllQueuesJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_and_while_executing_job_spec.rb b/spec/examples/until_and_while_executing_job_spec.rb index 5fa7c0f3f..5dac90c52 100644 --- a/spec/examples/until_and_while_executing_job_spec.rb +++ b/spec/examples/until_and_while_executing_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UntilAndWhileExecutingJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_executed2_job_spec.rb b/spec/examples/until_executed2_job_spec.rb index 8f4b80762..af7af7275 100644 --- a/spec/examples/until_executed2_job_spec.rb +++ b/spec/examples/until_executed2_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UntilExecuted2Job do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_executed_job_spec.rb b/spec/examples/until_executed_job_spec.rb index 5e5270161..1bda6386a 100644 --- a/spec/examples/until_executed_job_spec.rb +++ b/spec/examples/until_executed_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UntilExecutedJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_executing_job_spec.rb b/spec/examples/until_executing_job_spec.rb index 0ce604953..c7c6f74ef 100644 --- a/spec/examples/until_executing_job_spec.rb +++ b/spec/examples/until_executing_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UntilExecutingJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_expired_job_spec.rb b/spec/examples/until_expired_job_spec.rb index ee6196972..158e90173 100644 --- a/spec/examples/until_expired_job_spec.rb +++ b/spec/examples/until_expired_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UntilExpiredJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/until_global_expired_job_spec.rb b/spec/examples/until_global_expired_job_spec.rb index db330d399..81ed480d2 100644 --- a/spec/examples/until_global_expired_job_spec.rb +++ b/spec/examples/until_global_expired_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe UntilGlobalExpiredJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/while_executing_job_spec.rb b/spec/examples/while_executing_job_spec.rb index e585ec35a..67c2bc96a 100644 --- a/spec/examples/while_executing_job_spec.rb +++ b/spec/examples/while_executing_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe WhileExecutingJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/examples/without_argument_job_spec.rb b/spec/examples/without_argument_job_spec.rb index b531193d7..bb7c48727 100644 --- a/spec/examples/without_argument_job_spec.rb +++ b/spec/examples/without_argument_job_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe WithoutArgumentJob do it_behaves_like "sidekiq with options" do let(:options) do diff --git a/spec/integration/sidekiq/retry_set_spec.rb b/spec/integration/sidekiq/retry_set_spec.rb index 9dc34e9b6..ecfcc5731 100644 --- a/spec/integration/sidekiq/retry_set_spec.rb +++ b/spec/integration/sidekiq/retry_set_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe Sidekiq::RetrySet, redis: :redis do let(:locksmith) { SidekiqUniqueJobs::Locksmith.new(item) } let(:args) { [1, 2] } diff --git a/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb b/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb index 2d9bd6c11..c81e544d2 100644 --- a/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Client::Middleware, redis: :redis, redis_db: 1 do describe "when a job is already scheduled" do it "processes jobs properly" do diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb index 29918ab29..6a79971ca 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilAndWhileExecuting, redis: :redis, redis_db: 3 do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb index e20bb1a12..757d92410 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuted, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb index 2942d09c2..c119226ab 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuting, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb index adc58dba4..cd0ca79f2 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExpired, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb index 3b64e451b..ae1ecdd0f 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecutingReject, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb index 81aba006e..c49947257 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb b/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb index f38aa1a4d..a00195379 100644 --- a/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Locksmith, redis: :redis do let(:locksmith_one) { described_class.new(item_one) } let(:locksmith_two) { described_class.new(item_two) } diff --git a/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb b/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb index 8b66ebfc6..c660e795b 100644 --- a/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Server::Middleware, redis: :redis, redis_db: 9 do let(:middleware) { SidekiqUniqueJobs::Server::Middleware.new } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 50cd408e3..d48e4e1af 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -29,6 +29,7 @@ require "sidekiq/redis_connection" Dir[File.join(File.dirname(__FILE__), "support", "**", "*.rb")].each { |f| require f } +Dir[File.join(File.dirname(__FILE__), "..", "examples", "**", "*.rb")].each { |f| require f } RSpec.configure do |config| config.define_derived_metadata do |meta| @@ -50,8 +51,6 @@ Kernel.srand config.seed end -Dir[File.join(File.dirname(__FILE__), "..", "examples", "**", "*.rb")].each { |f| require f } - def capture(stream) begin stream = stream.to_s diff --git a/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb b/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb index 6d29bc099..14d132d6d 100644 --- a/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe "core_ext.rb" do describe Hash do let(:hash) { { test: :me, not: :me } } diff --git a/spec/unit/sidekiq_unique_jobs/digests_spec.rb b/spec/unit/sidekiq_unique_jobs/digests_spec.rb index 50029cc81..691acbf1b 100644 --- a/spec/unit/sidekiq_unique_jobs/digests_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/digests_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Digests, redis: :redis do before do (1..10).each do |arg| diff --git a/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb index 08a72f50d..3b8c523e7 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::BaseLock do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb index 20467d314..574a014a8 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilAndWhileExecuting do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb index e632bb09d..c20533bff 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuted do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb index 72f2b1bbb..741f9e03d 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuting do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb index cc6c823ce..6d024751a 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExpired do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb index d7c4e6fb7..4a0b9afad 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecutingReject do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb index d7a488d36..20fdfd42d 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting do include_context "with a stubbed locksmith" let(:lock) { described_class.new(item, callback) } diff --git a/spec/unit/sidekiq_unique_jobs/middleware_spec.rb b/spec/unit/sidekiq_unique_jobs/middleware_spec.rb index 2d4aa3fe9..31005c26d 100644 --- a/spec/unit/sidekiq_unique_jobs/middleware_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/middleware_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Middleware do describe SidekiqUniqueJobs do let(:client_config) { class_double(Sidekiq) } diff --git a/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb b/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb index e1bfefa94..f3989040d 100644 --- a/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Normalizer do describe ".jsonify" do specify do diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb index 4d620c041..a08c99a07 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Log do let(:strategy) { described_class.new(item) } let(:unique_digest) { "uniquejobs:random-digest-value" } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb index 86f3bd44c..a5756ec5f 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Raise do let(:strategy) { described_class.new(item) } let(:unique_digest) { "uniquejobs:random-digest-value" } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb index ffe60cc37..d9cfe0521 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Reject do include_context "with a stubbed locksmith" let(:strategy) { described_class.new(item) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb index d9d8a6941..bc22f4289 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Replace, redis: :redis do let(:strategy) { described_class.new(item) } let(:unique_digest) { "uniquejobs:56c68cab5038eb57959538866377560d" } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb index 65549be68..58e8d65b3 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Reschedule do let(:strategy) { described_class.new(item) } let(:unique_digest) { "uniquejobs:random-digest-value" } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb index 71c3a1885..f280502ea 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Strategy, redis: :redis do let(:strategy) { described_class.new(item) } let(:unique_digest) { "uniquejobs:56c68cab5038eb57959538866377560d" } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb index bd7ac6ae9..c29cfb0d3 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict do describe "::STRAGEGIES" do subject { described_class::STRATEGIES } diff --git a/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb b/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb index 6a60e971f..208154feb 100644 --- a/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::OptionsWithFallback do class ClassWithOptions include SidekiqUniqueJobs::OptionsWithFallback diff --git a/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb b/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb index 07517bd96..b5f9bac11 100644 --- a/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe "Sidekiq::Api", redis: :redis do let(:item) do { "class" => "JustAWorker", diff --git a/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb b/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb index 5afd9ea3f..a76a86780 100644 --- a/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::SidekiqWorkerMethods do class WorkerWithSidekiqMethods include SidekiqUniqueJobs::SidekiqWorkerMethods diff --git a/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb b/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb index fb05fafe6..ef27bf6f3 100644 --- a/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/timeout/calculator_spec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Timeout::Calculator do let(:calculator) { described_class.new("class" => worker_class_name, "at" => schedule_time) } let(:worker_class_name) { "MyUniqueJob" } diff --git a/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb b/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb index 899c13f9b..19e93cfa1 100644 --- a/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::UniqueArgs do let(:unique_args) { described_class.new(item) } let(:worker_class) { UntilExecutedJob } diff --git a/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb b/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb index 653866818..8b0bbeb4d 100644 --- a/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Unlockable, redis: :redis do def item_with_digest SidekiqUniqueJobs::UniqueArgs.digest(item) diff --git a/spec/unit/sidekiq_unique_jobs/util_spec.rb b/spec/unit/sidekiq_unique_jobs/util_spec.rb index bb9ea4093..1d5543fca 100644 --- a/spec/unit/sidekiq_unique_jobs/util_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/util_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs::Util, redis: :redis do let(:item_hash) do { diff --git a/spec/unit/sidekiq_unique_jobs_spec.rb b/spec/unit/sidekiq_unique_jobs_spec.rb index f417526ef..3b7b4012e 100644 --- a/spec/unit/sidekiq_unique_jobs_spec.rb +++ b/spec/unit/sidekiq_unique_jobs_spec.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true - +require "spec_helper" RSpec.describe SidekiqUniqueJobs do describe ".config" do subject(:config) { described_class.config } From 1ef491dfb0a4a8c331dfa308c159f58d1344c614 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 19:55:35 +0100 Subject: [PATCH 20/23] Remove awesome print --- Gemfile | 1 - spec/spec_helper.rb | 1 - 2 files changed, 2 deletions(-) diff --git a/Gemfile b/Gemfile index 88f3a39f2..539fdff9e 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,6 @@ source "https://rubygems.org" gemspec gem "appraisal", "~> 2.2.0" -gem "awesome_print" gem "rspec-eventually", require: false gem "rspec-its", require: false gem "rspec-retry", require: false diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d48e4e1af..c33b1f224 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,7 +14,6 @@ require "rspec" require "rspec/its" -require "awesome_print" require "sidekiq" require "sidekiq/api" From d989a79419b410814476aa9d99701b9726471969 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 19:55:49 +0100 Subject: [PATCH 21/23] Update gemfiles --- gemfiles/sidekiq_4.0.gemfile | 34 ++++++++++++++++++++------------ gemfiles/sidekiq_4.1.gemfile | 34 ++++++++++++++++++++------------ gemfiles/sidekiq_4.2.gemfile | 34 ++++++++++++++++++++------------ gemfiles/sidekiq_5.0.gemfile | 34 ++++++++++++++++++++------------ gemfiles/sidekiq_5.1.gemfile | 34 ++++++++++++++++++++------------ gemfiles/sidekiq_5.2.gemfile | 34 ++++++++++++++++++++------------ gemfiles/sidekiq_develop.gemfile | 34 ++++++++++++++++++++------------ 7 files changed, 147 insertions(+), 91 deletions(-) diff --git a/gemfiles/sidekiq_4.0.gemfile b/gemfiles/sidekiq_4.0.gemfile index 37fa2e8f2..8b46dc076 100644 --- a/gemfiles/sidekiq_4.0.gemfile +++ b/gemfiles/sidekiq_4.0.gemfile @@ -3,24 +3,32 @@ source "https://rubygems.org" gem "appraisal", "~> 2.2.0" +gem "rspec-eventually", require: false gem "rspec-its", require: false gem "rspec-retry", require: false -gem "rspec-eventually", require: false gem "sidekiq", "~> 4.0.0" platforms :mri_25 do - gem "benchmark-ips", require: false - gem "fasterer", require: false - gem "guard", require: false - gem "guard-reek", require: false - gem "guard-rspec", require: false - gem "guard-rubocop", require: false - gem "memory_profiler", require: false - gem "pry-byebug", require: false - gem "rubocop", require: false - gem "rubocop-rspec", require: false - gem "simplecov-json", require: false - gem "travis", require: false + gem "benchmark-ips" + gem "fasterer" + gem "fuubar" + gem "gem-release" + gem "github-markup" + gem "github_changelog_generator" + gem "guard" + gem "guard-reek" + gem "guard-rspec" + gem "guard-rubocop" + gem "memory_profiler" + gem "pry" + gem "rb-readline" + gem "redcarpet" + gem "reek", ">= 5.3" + gem "rubocop" + gem "rubocop-rspec" + gem "simplecov-json" + gem "travis" + gem "yard" end gemspec path: "../" diff --git a/gemfiles/sidekiq_4.1.gemfile b/gemfiles/sidekiq_4.1.gemfile index 879617936..c92fb5e34 100644 --- a/gemfiles/sidekiq_4.1.gemfile +++ b/gemfiles/sidekiq_4.1.gemfile @@ -3,24 +3,32 @@ source "https://rubygems.org" gem "appraisal", "~> 2.2.0" +gem "rspec-eventually", require: false gem "rspec-its", require: false gem "rspec-retry", require: false -gem "rspec-eventually", require: false gem "sidekiq", "~> 4.1.0" platforms :mri_25 do - gem "benchmark-ips", require: false - gem "fasterer", require: false - gem "guard", require: false - gem "guard-reek", require: false - gem "guard-rspec", require: false - gem "guard-rubocop", require: false - gem "memory_profiler", require: false - gem "pry-byebug", require: false - gem "rubocop", require: false - gem "rubocop-rspec", require: false - gem "simplecov-json", require: false - gem "travis", require: false + gem "benchmark-ips" + gem "fasterer" + gem "fuubar" + gem "gem-release" + gem "github-markup" + gem "github_changelog_generator" + gem "guard" + gem "guard-reek" + gem "guard-rspec" + gem "guard-rubocop" + gem "memory_profiler" + gem "pry" + gem "rb-readline" + gem "redcarpet" + gem "reek", ">= 5.3" + gem "rubocop" + gem "rubocop-rspec" + gem "simplecov-json" + gem "travis" + gem "yard" end gemspec path: "../" diff --git a/gemfiles/sidekiq_4.2.gemfile b/gemfiles/sidekiq_4.2.gemfile index d7e9bca71..1ec655215 100644 --- a/gemfiles/sidekiq_4.2.gemfile +++ b/gemfiles/sidekiq_4.2.gemfile @@ -3,24 +3,32 @@ source "https://rubygems.org" gem "appraisal", "~> 2.2.0" +gem "rspec-eventually", require: false gem "rspec-its", require: false gem "rspec-retry", require: false -gem "rspec-eventually", require: false gem "sidekiq", "~> 4.2.0" platforms :mri_25 do - gem "benchmark-ips", require: false - gem "fasterer", require: false - gem "guard", require: false - gem "guard-reek", require: false - gem "guard-rspec", require: false - gem "guard-rubocop", require: false - gem "memory_profiler", require: false - gem "pry-byebug", require: false - gem "rubocop", require: false - gem "rubocop-rspec", require: false - gem "simplecov-json", require: false - gem "travis", require: false + gem "benchmark-ips" + gem "fasterer" + gem "fuubar" + gem "gem-release" + gem "github-markup" + gem "github_changelog_generator" + gem "guard" + gem "guard-reek" + gem "guard-rspec" + gem "guard-rubocop" + gem "memory_profiler" + gem "pry" + gem "rb-readline" + gem "redcarpet" + gem "reek", ">= 5.3" + gem "rubocop" + gem "rubocop-rspec" + gem "simplecov-json" + gem "travis" + gem "yard" end gemspec path: "../" diff --git a/gemfiles/sidekiq_5.0.gemfile b/gemfiles/sidekiq_5.0.gemfile index a16fe99e2..2b16b9fd4 100644 --- a/gemfiles/sidekiq_5.0.gemfile +++ b/gemfiles/sidekiq_5.0.gemfile @@ -3,24 +3,32 @@ source "https://rubygems.org" gem "appraisal", "~> 2.2.0" +gem "rspec-eventually", require: false gem "rspec-its", require: false gem "rspec-retry", require: false -gem "rspec-eventually", require: false gem "sidekiq", "~> 5.0.0" platforms :mri_25 do - gem "benchmark-ips", require: false - gem "fasterer", require: false - gem "guard", require: false - gem "guard-reek", require: false - gem "guard-rspec", require: false - gem "guard-rubocop", require: false - gem "memory_profiler", require: false - gem "pry-byebug", require: false - gem "rubocop", require: false - gem "rubocop-rspec", require: false - gem "simplecov-json", require: false - gem "travis", require: false + gem "benchmark-ips" + gem "fasterer" + gem "fuubar" + gem "gem-release" + gem "github-markup" + gem "github_changelog_generator" + gem "guard" + gem "guard-reek" + gem "guard-rspec" + gem "guard-rubocop" + gem "memory_profiler" + gem "pry" + gem "rb-readline" + gem "redcarpet" + gem "reek", ">= 5.3" + gem "rubocop" + gem "rubocop-rspec" + gem "simplecov-json" + gem "travis" + gem "yard" end gemspec path: "../" diff --git a/gemfiles/sidekiq_5.1.gemfile b/gemfiles/sidekiq_5.1.gemfile index 4124fd0ad..b028f3276 100644 --- a/gemfiles/sidekiq_5.1.gemfile +++ b/gemfiles/sidekiq_5.1.gemfile @@ -3,24 +3,32 @@ source "https://rubygems.org" gem "appraisal", "~> 2.2.0" +gem "rspec-eventually", require: false gem "rspec-its", require: false gem "rspec-retry", require: false -gem "rspec-eventually", require: false gem "sidekiq", "~> 5.1.0" platforms :mri_25 do - gem "benchmark-ips", require: false - gem "fasterer", require: false - gem "guard", require: false - gem "guard-reek", require: false - gem "guard-rspec", require: false - gem "guard-rubocop", require: false - gem "memory_profiler", require: false - gem "pry-byebug", require: false - gem "rubocop", require: false - gem "rubocop-rspec", require: false - gem "simplecov-json", require: false - gem "travis", require: false + gem "benchmark-ips" + gem "fasterer" + gem "fuubar" + gem "gem-release" + gem "github-markup" + gem "github_changelog_generator" + gem "guard" + gem "guard-reek" + gem "guard-rspec" + gem "guard-rubocop" + gem "memory_profiler" + gem "pry" + gem "rb-readline" + gem "redcarpet" + gem "reek", ">= 5.3" + gem "rubocop" + gem "rubocop-rspec" + gem "simplecov-json" + gem "travis" + gem "yard" end gemspec path: "../" diff --git a/gemfiles/sidekiq_5.2.gemfile b/gemfiles/sidekiq_5.2.gemfile index 8486d5887..a0b981cb2 100644 --- a/gemfiles/sidekiq_5.2.gemfile +++ b/gemfiles/sidekiq_5.2.gemfile @@ -3,24 +3,32 @@ source "https://rubygems.org" gem "appraisal", "~> 2.2.0" +gem "rspec-eventually", require: false gem "rspec-its", require: false gem "rspec-retry", require: false -gem "rspec-eventually", require: false gem "sidekiq", "~> 5.2.0" platforms :mri_25 do - gem "benchmark-ips", require: false - gem "fasterer", require: false - gem "guard", require: false - gem "guard-reek", require: false - gem "guard-rspec", require: false - gem "guard-rubocop", require: false - gem "memory_profiler", require: false - gem "pry-byebug", require: false - gem "rubocop", require: false - gem "rubocop-rspec", require: false - gem "simplecov-json", require: false - gem "travis", require: false + gem "benchmark-ips" + gem "fasterer" + gem "fuubar" + gem "gem-release" + gem "github-markup" + gem "github_changelog_generator" + gem "guard" + gem "guard-reek" + gem "guard-rspec" + gem "guard-rubocop" + gem "memory_profiler" + gem "pry" + gem "rb-readline" + gem "redcarpet" + gem "reek", ">= 5.3" + gem "rubocop" + gem "rubocop-rspec" + gem "simplecov-json" + gem "travis" + gem "yard" end gemspec path: "../" diff --git a/gemfiles/sidekiq_develop.gemfile b/gemfiles/sidekiq_develop.gemfile index b32106194..a3da1b982 100644 --- a/gemfiles/sidekiq_develop.gemfile +++ b/gemfiles/sidekiq_develop.gemfile @@ -3,24 +3,32 @@ source "https://rubygems.org" gem "appraisal", "~> 2.2.0" +gem "rspec-eventually", require: false gem "rspec-its", require: false gem "rspec-retry", require: false -gem "rspec-eventually", require: false gem "sidekiq", git: "https://github.com/mperham/sidekiq.git" platforms :mri_25 do - gem "benchmark-ips", require: false - gem "fasterer", require: false - gem "guard", require: false - gem "guard-reek", require: false - gem "guard-rspec", require: false - gem "guard-rubocop", require: false - gem "memory_profiler", require: false - gem "pry-byebug", require: false - gem "rubocop", require: false - gem "rubocop-rspec", require: false - gem "simplecov-json", require: false - gem "travis", require: false + gem "benchmark-ips" + gem "fasterer" + gem "fuubar" + gem "gem-release" + gem "github-markup" + gem "github_changelog_generator" + gem "guard" + gem "guard-reek" + gem "guard-rspec" + gem "guard-rubocop" + gem "memory_profiler" + gem "pry" + gem "rb-readline" + gem "redcarpet" + gem "reek", ">= 5.3" + gem "rubocop" + gem "rubocop-rspec" + gem "simplecov-json" + gem "travis" + gem "yard" end gemspec path: "../" From c277dac1017989015d73b5078bdc7d65cdb70710 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 20:17:48 +0100 Subject: [PATCH 22/23] Exclude more paths from validation --- .codeclimate.yml | 9 ++++----- .reek.yml | 1 + .rubocop.yml | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index 4962e39e3..b4ee78655 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -26,8 +26,7 @@ exclude_patterns: - "Gemfile" - "*.gemspec" - "Appraisals" - - "spec/**/*.rb" - - "gemfiles/**/*" - - "rails_example/**/*" - - "redis/**/*" - - "tmp/**/*" + - "gemfiles/" + - "rails_example/" + - "redis/" + - "tmp/" diff --git a/.reek.yml b/.reek.yml index 4856aa0e3..f136fb4c2 100644 --- a/.reek.yml +++ b/.reek.yml @@ -6,6 +6,7 @@ exclude_paths: - tmp - gemfiles - examples + - vendor/bundle detectors: DuplicateMethodCall: exclude: diff --git a/.rubocop.yml b/.rubocop.yml index 2c31971cd..ece036a48 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -18,6 +18,7 @@ AllCops: Exclude: - "Gemfile.lock" - "**/*.erb" + - "gemfiles/**/*" Lint/AmbiguousBlockAssociation: Exclude: From e2c2df906f3d0936434b4ba7b9fc5a9876fc97d9 Mon Sep 17 00:00:00 2001 From: Mika Hel Date: Fri, 8 Feb 2019 20:34:40 +0100 Subject: [PATCH 23/23] =?UTF-8?q?Rubo=F0=9F=91=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/examples/another_unique_job_spec.rb | 1 + spec/examples/custom_queue_job_spec.rb | 1 + spec/examples/custom_queue_job_with_filter_method_spec.rb | 1 + spec/examples/custom_queue_job_with_filter_proc_spec.rb | 1 + spec/examples/expiring_job_spec.rb | 1 + spec/examples/inline_worker_spec.rb | 1 + spec/examples/just_a_worker_spec.rb | 1 + spec/examples/long_running_job_spec.rb | 1 + spec/examples/main_job_spec.rb | 1 + spec/examples/my_job_spec.rb | 1 + spec/examples/my_unique_job_spec.rb | 1 + spec/examples/my_unique_job_with_filter_method_spec.rb | 1 + spec/examples/my_unique_job_with_filter_proc_spec.rb | 1 + spec/examples/notify_worker_spec.rb | 1 + spec/examples/plain_class_spec.rb | 1 + spec/examples/simple_worker_spec.rb | 1 + spec/examples/spawn_simple_worker_spec.rb | 1 + spec/examples/test_class_spec.rb | 1 + spec/examples/unique_across_workers_job_spec.rb | 1 + spec/examples/unique_job_on_conflict_raise_spec.rb | 1 + spec/examples/unique_job_on_conflict_reject_spec.rb | 1 + spec/examples/unique_job_on_conflict_reschedule_spec.rb | 1 + spec/examples/unique_job_with_nil_unique_args_spec.rb | 1 + spec/examples/unique_job_with_no_unique_args_method_spec.rb | 1 + spec/examples/unique_job_without_unique_args_parameter_spec.rb | 1 + spec/examples/unique_on_all_queues_job_spec.rb | 1 + spec/examples/until_and_while_executing_job_spec.rb | 1 + spec/examples/until_executed2_job_spec.rb | 1 + spec/examples/until_executed_job_spec.rb | 1 + spec/examples/until_executing_job_spec.rb | 1 + spec/examples/until_expired_job_spec.rb | 1 + spec/examples/until_global_expired_job_spec.rb | 1 + spec/examples/while_executing_job_spec.rb | 1 + spec/examples/without_argument_job_spec.rb | 1 + spec/integration/sidekiq/retry_set_spec.rb | 1 + spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb | 1 + .../sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb | 1 + spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb | 1 + .../integration/sidekiq_unique_jobs/lock/until_executing_spec.rb | 1 + spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb | 1 + .../sidekiq_unique_jobs/lock/while_executing_reject_spec.rb | 1 + .../integration/sidekiq_unique_jobs/lock/while_executing_spec.rb | 1 + spec/integration/sidekiq_unique_jobs/locksmith_spec.rb | 1 + spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/core_ext_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/digests_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb | 1 + .../sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb | 1 + .../unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/middleware_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/normalizer_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/unique_args_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/unlockable_spec.rb | 1 + spec/unit/sidekiq_unique_jobs/util_spec.rb | 1 + spec/unit/sidekiq_unique_jobs_spec.rb | 1 + 69 files changed, 69 insertions(+) diff --git a/spec/examples/another_unique_job_spec.rb b/spec/examples/another_unique_job_spec.rb index f70e39185..ca9187adf 100644 --- a/spec/examples/another_unique_job_spec.rb +++ b/spec/examples/another_unique_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe AnotherUniqueJob, redis: :redis do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/custom_queue_job_spec.rb b/spec/examples/custom_queue_job_spec.rb index a5ea3302c..d10db86a6 100644 --- a/spec/examples/custom_queue_job_spec.rb +++ b/spec/examples/custom_queue_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe CustomQueueJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/custom_queue_job_with_filter_method_spec.rb b/spec/examples/custom_queue_job_with_filter_method_spec.rb index fb39aaaba..200e82993 100644 --- a/spec/examples/custom_queue_job_with_filter_method_spec.rb +++ b/spec/examples/custom_queue_job_with_filter_method_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe CustomQueueJobWithFilterMethod do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/custom_queue_job_with_filter_proc_spec.rb b/spec/examples/custom_queue_job_with_filter_proc_spec.rb index 648e12821..96b9a41fa 100644 --- a/spec/examples/custom_queue_job_with_filter_proc_spec.rb +++ b/spec/examples/custom_queue_job_with_filter_proc_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe CustomQueueJobWithFilterProc do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/expiring_job_spec.rb b/spec/examples/expiring_job_spec.rb index ad07bacf3..fdd65e1e0 100644 --- a/spec/examples/expiring_job_spec.rb +++ b/spec/examples/expiring_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe ExpiringJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/inline_worker_spec.rb b/spec/examples/inline_worker_spec.rb index 2a160a68e..8d3398736 100644 --- a/spec/examples/inline_worker_spec.rb +++ b/spec/examples/inline_worker_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe InlineWorker do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/just_a_worker_spec.rb b/spec/examples/just_a_worker_spec.rb index 7c80bdd59..43383f7c0 100644 --- a/spec/examples/just_a_worker_spec.rb +++ b/spec/examples/just_a_worker_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe JustAWorker do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/long_running_job_spec.rb b/spec/examples/long_running_job_spec.rb index 87acf08c0..4e11b27f4 100644 --- a/spec/examples/long_running_job_spec.rb +++ b/spec/examples/long_running_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe LongRunningJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/main_job_spec.rb b/spec/examples/main_job_spec.rb index cdca801e4..136af20b5 100644 --- a/spec/examples/main_job_spec.rb +++ b/spec/examples/main_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe MainJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/my_job_spec.rb b/spec/examples/my_job_spec.rb index 58c73a746..99fd4b6f6 100644 --- a/spec/examples/my_job_spec.rb +++ b/spec/examples/my_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe MyJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/my_unique_job_spec.rb b/spec/examples/my_unique_job_spec.rb index d4d3887ce..0bd6d45bb 100644 --- a/spec/examples/my_unique_job_spec.rb +++ b/spec/examples/my_unique_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe MyUniqueJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/my_unique_job_with_filter_method_spec.rb b/spec/examples/my_unique_job_with_filter_method_spec.rb index 60801e4e4..bb3c5e1ca 100644 --- a/spec/examples/my_unique_job_with_filter_method_spec.rb +++ b/spec/examples/my_unique_job_with_filter_method_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe MyUniqueJobWithFilterMethod do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/my_unique_job_with_filter_proc_spec.rb b/spec/examples/my_unique_job_with_filter_proc_spec.rb index d0bfee19d..29ab73bcc 100644 --- a/spec/examples/my_unique_job_with_filter_proc_spec.rb +++ b/spec/examples/my_unique_job_with_filter_proc_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe MyUniqueJobWithFilterProc do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/notify_worker_spec.rb b/spec/examples/notify_worker_spec.rb index 1d48e6eb5..ff6029239 100644 --- a/spec/examples/notify_worker_spec.rb +++ b/spec/examples/notify_worker_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe NotifyWorker do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/plain_class_spec.rb b/spec/examples/plain_class_spec.rb index 7fb44457b..f6083b106 100644 --- a/spec/examples/plain_class_spec.rb +++ b/spec/examples/plain_class_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe PlainClass do describe ".run" do diff --git a/spec/examples/simple_worker_spec.rb b/spec/examples/simple_worker_spec.rb index a5bf4b67d..a3555ad44 100644 --- a/spec/examples/simple_worker_spec.rb +++ b/spec/examples/simple_worker_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SimpleWorker do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/spawn_simple_worker_spec.rb b/spec/examples/spawn_simple_worker_spec.rb index 06a25d4fb..0e1f09671 100644 --- a/spec/examples/spawn_simple_worker_spec.rb +++ b/spec/examples/spawn_simple_worker_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SpawnSimpleWorker do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/test_class_spec.rb b/spec/examples/test_class_spec.rb index 58c9ce149..6e7811333 100644 --- a/spec/examples/test_class_spec.rb +++ b/spec/examples/test_class_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe TestClass do describe ".run" do diff --git a/spec/examples/unique_across_workers_job_spec.rb b/spec/examples/unique_across_workers_job_spec.rb index b03a548d2..8e9d79992 100644 --- a/spec/examples/unique_across_workers_job_spec.rb +++ b/spec/examples/unique_across_workers_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UniqueAcrossWorkersJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/unique_job_on_conflict_raise_spec.rb b/spec/examples/unique_job_on_conflict_raise_spec.rb index 8ab2db595..69c26eda9 100644 --- a/spec/examples/unique_job_on_conflict_raise_spec.rb +++ b/spec/examples/unique_job_on_conflict_raise_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UniqueJobOnConflictRaise do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/unique_job_on_conflict_reject_spec.rb b/spec/examples/unique_job_on_conflict_reject_spec.rb index 77bfca75a..57347cc58 100644 --- a/spec/examples/unique_job_on_conflict_reject_spec.rb +++ b/spec/examples/unique_job_on_conflict_reject_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UniqueJobOnConflictReject do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/unique_job_on_conflict_reschedule_spec.rb b/spec/examples/unique_job_on_conflict_reschedule_spec.rb index 1d411502f..f8d813bb1 100644 --- a/spec/examples/unique_job_on_conflict_reschedule_spec.rb +++ b/spec/examples/unique_job_on_conflict_reschedule_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UniqueJobOnConflictReschedule do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/unique_job_with_nil_unique_args_spec.rb b/spec/examples/unique_job_with_nil_unique_args_spec.rb index 2621cd957..2fd162a59 100644 --- a/spec/examples/unique_job_with_nil_unique_args_spec.rb +++ b/spec/examples/unique_job_with_nil_unique_args_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UniqueJobWithNilUniqueArgs do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/unique_job_with_no_unique_args_method_spec.rb b/spec/examples/unique_job_with_no_unique_args_method_spec.rb index 697988184..b506130f4 100644 --- a/spec/examples/unique_job_with_no_unique_args_method_spec.rb +++ b/spec/examples/unique_job_with_no_unique_args_method_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UniqueJobWithNoUniqueArgsMethod do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/unique_job_without_unique_args_parameter_spec.rb b/spec/examples/unique_job_without_unique_args_parameter_spec.rb index 3cd815b8a..dd4e4a703 100644 --- a/spec/examples/unique_job_without_unique_args_parameter_spec.rb +++ b/spec/examples/unique_job_without_unique_args_parameter_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UniqueJobWithoutUniqueArgsParameter do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/unique_on_all_queues_job_spec.rb b/spec/examples/unique_on_all_queues_job_spec.rb index 78540235e..58e93e19e 100644 --- a/spec/examples/unique_on_all_queues_job_spec.rb +++ b/spec/examples/unique_on_all_queues_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UniqueOnAllQueuesJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/until_and_while_executing_job_spec.rb b/spec/examples/until_and_while_executing_job_spec.rb index 5dac90c52..b107d98f9 100644 --- a/spec/examples/until_and_while_executing_job_spec.rb +++ b/spec/examples/until_and_while_executing_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UntilAndWhileExecutingJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/until_executed2_job_spec.rb b/spec/examples/until_executed2_job_spec.rb index af7af7275..a3d813e34 100644 --- a/spec/examples/until_executed2_job_spec.rb +++ b/spec/examples/until_executed2_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UntilExecuted2Job do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/until_executed_job_spec.rb b/spec/examples/until_executed_job_spec.rb index 1bda6386a..05ebe5d46 100644 --- a/spec/examples/until_executed_job_spec.rb +++ b/spec/examples/until_executed_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UntilExecutedJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/until_executing_job_spec.rb b/spec/examples/until_executing_job_spec.rb index c7c6f74ef..6ad28f657 100644 --- a/spec/examples/until_executing_job_spec.rb +++ b/spec/examples/until_executing_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UntilExecutingJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/until_expired_job_spec.rb b/spec/examples/until_expired_job_spec.rb index 158e90173..2ff813ba0 100644 --- a/spec/examples/until_expired_job_spec.rb +++ b/spec/examples/until_expired_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UntilExpiredJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/until_global_expired_job_spec.rb b/spec/examples/until_global_expired_job_spec.rb index 81ed480d2..e9169676c 100644 --- a/spec/examples/until_global_expired_job_spec.rb +++ b/spec/examples/until_global_expired_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe UntilGlobalExpiredJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/while_executing_job_spec.rb b/spec/examples/while_executing_job_spec.rb index 67c2bc96a..61a3b5b52 100644 --- a/spec/examples/while_executing_job_spec.rb +++ b/spec/examples/while_executing_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe WhileExecutingJob do it_behaves_like "sidekiq with options" do diff --git a/spec/examples/without_argument_job_spec.rb b/spec/examples/without_argument_job_spec.rb index bb7c48727..408e0ce2d 100644 --- a/spec/examples/without_argument_job_spec.rb +++ b/spec/examples/without_argument_job_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe WithoutArgumentJob do it_behaves_like "sidekiq with options" do diff --git a/spec/integration/sidekiq/retry_set_spec.rb b/spec/integration/sidekiq/retry_set_spec.rb index ecfcc5731..2e2a26c69 100644 --- a/spec/integration/sidekiq/retry_set_spec.rb +++ b/spec/integration/sidekiq/retry_set_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe Sidekiq::RetrySet, redis: :redis do let(:locksmith) { SidekiqUniqueJobs::Locksmith.new(item) } diff --git a/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb b/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb index c81e544d2..2d11b620e 100644 --- a/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/client/middleware_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Client::Middleware, redis: :redis, redis_db: 1 do describe "when a job is already scheduled" do diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb index 6a79971ca..31e5d9530 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilAndWhileExecuting, redis: :redis, redis_db: 3 do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb index 757d92410..13d53fb88 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuted, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb index c119226ab..65eb41001 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_executing_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuting, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb index cd0ca79f2..5aefc863e 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/until_expired_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExpired, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb index ae1ecdd0f..609268eb8 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecutingReject, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb b/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb index c49947257..bff6aa301 100644 --- a/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/lock/while_executing_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting, redis: :redis do include SidekiqHelpers diff --git a/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb b/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb index a00195379..f65320e72 100644 --- a/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/locksmith_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Locksmith, redis: :redis do let(:locksmith_one) { described_class.new(item_one) } diff --git a/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb b/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb index c660e795b..e26c215b5 100644 --- a/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb +++ b/spec/integration/sidekiq_unique_jobs/server/middleware_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Server::Middleware, redis: :redis, redis_db: 9 do let(:middleware) { SidekiqUniqueJobs::Server::Middleware.new } diff --git a/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb b/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb index 14d132d6d..207054dc2 100644 --- a/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/core_ext_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe "core_ext.rb" do describe Hash do diff --git a/spec/unit/sidekiq_unique_jobs/digests_spec.rb b/spec/unit/sidekiq_unique_jobs/digests_spec.rb index 691acbf1b..bf2c84db0 100644 --- a/spec/unit/sidekiq_unique_jobs/digests_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/digests_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Digests, redis: :redis do before do diff --git a/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb index 3b8c523e7..d2fe1d94f 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/base_lock_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::BaseLock do include_context "with a stubbed locksmith" diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb index 574a014a8..f92627e08 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilAndWhileExecuting do include_context "with a stubbed locksmith" diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb index c20533bff..a9a3965bb 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_executed_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuted do include_context "with a stubbed locksmith" diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb index 741f9e03d..3ea1fdae9 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_executing_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExecuting do include_context "with a stubbed locksmith" diff --git a/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb index 6d024751a..b572c2509 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/until_expired_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::UntilExpired do include_context "with a stubbed locksmith" diff --git a/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb index 4a0b9afad..e50121654 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/while_executing_reject_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecutingReject do include_context "with a stubbed locksmith" diff --git a/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb b/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb index 20fdfd42d..d18bf125a 100644 --- a/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/lock/while_executing_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Lock::WhileExecuting do include_context "with a stubbed locksmith" diff --git a/spec/unit/sidekiq_unique_jobs/middleware_spec.rb b/spec/unit/sidekiq_unique_jobs/middleware_spec.rb index 31005c26d..efc676d89 100644 --- a/spec/unit/sidekiq_unique_jobs/middleware_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/middleware_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Middleware do describe SidekiqUniqueJobs do diff --git a/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb b/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb index f3989040d..98023fe99 100644 --- a/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/normalizer_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Normalizer do describe ".jsonify" do diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb index a08c99a07..75e2b0ad5 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/log_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Log do let(:strategy) { described_class.new(item) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb index a5756ec5f..1976cba64 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/raise_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Raise do let(:strategy) { described_class.new(item) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb index d9cfe0521..df929de10 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/reject_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Reject do include_context "with a stubbed locksmith" diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb index bc22f4289..690b07ae8 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/replace_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Replace, redis: :redis do let(:strategy) { described_class.new(item) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb index 58e8d65b3..6c5169fb6 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/reschedule_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Reschedule do let(:strategy) { described_class.new(item) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb index f280502ea..4521d077f 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict/strategy_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict::Strategy, redis: :redis do let(:strategy) { described_class.new(item) } diff --git a/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb b/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb index c29cfb0d3..2b1c41638 100644 --- a/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/on_conflict_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::OnConflict do describe "::STRAGEGIES" do diff --git a/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb b/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb index 208154feb..bc227a959 100644 --- a/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/options_with_fallback_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::OptionsWithFallback do class ClassWithOptions diff --git a/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb b/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb index b5f9bac11..7183dfd70 100644 --- a/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/sidekiq/api_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe "Sidekiq::Api", redis: :redis do let(:item) do diff --git a/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb b/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb index a76a86780..508c26953 100644 --- a/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/sidekiq_worker_methods_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::SidekiqWorkerMethods do class WorkerWithSidekiqMethods diff --git a/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb b/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb index 19e93cfa1..56084cbc8 100644 --- a/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/unique_args_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::UniqueArgs do let(:unique_args) { described_class.new(item) } diff --git a/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb b/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb index 8b0bbeb4d..440f024fd 100644 --- a/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/unlockable_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Unlockable, redis: :redis do def item_with_digest diff --git a/spec/unit/sidekiq_unique_jobs/util_spec.rb b/spec/unit/sidekiq_unique_jobs/util_spec.rb index 1d5543fca..8ba6da48e 100644 --- a/spec/unit/sidekiq_unique_jobs/util_spec.rb +++ b/spec/unit/sidekiq_unique_jobs/util_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs::Util, redis: :redis do let(:item_hash) do diff --git a/spec/unit/sidekiq_unique_jobs_spec.rb b/spec/unit/sidekiq_unique_jobs_spec.rb index 3b7b4012e..3d80cf0ee 100644 --- a/spec/unit/sidekiq_unique_jobs_spec.rb +++ b/spec/unit/sidekiq_unique_jobs_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require "spec_helper" RSpec.describe SidekiqUniqueJobs do describe ".config" do