resque-loner 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: de3cf9ac86e6b7d373f9f281805f3a0fe4da5548
4
+ data.tar.gz: daf48d9aa6bc0a2f9a0afdeac093ab55fc04f1b1
5
+ SHA512:
6
+ metadata.gz: f25db5e2368a0b32d8cc5aaf363ee5b63eaa68dd78ef204b705434df500b376bf7c3cfe50f8819df1d99fdecdf685e42b540fed5e9c8f193a02978a4c587275b
7
+ data.tar.gz: d6be67b0d07ae6c98d167edca1cf6537d84458137f89c968af4db5f9b8e445974cfd2bf87bb3ea36d5fde29e81143792843cbbc80845e77e0a70b4a2944e6e63
data/.gitignore CHANGED
@@ -3,3 +3,7 @@
3
3
  **.swp
4
4
  Gemfile.lock
5
5
  .rvmrc
6
+ spec/stdout
7
+ coverage/
8
+ .ruby-version
9
+ .ruby-gemset
@@ -0,0 +1,92 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2014-03-20 16:42:32 -0400 using RuboCop version 0.19.1.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Offense count: 1
9
+ AmbiguousOperator:
10
+ Enabled: false
11
+
12
+ # Offense count: 1
13
+ AmbiguousRegexpLiteral:
14
+ Enabled: false
15
+
16
+ # Offense count: 36
17
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
18
+ ClassAndModuleChildren:
19
+ Enabled: false
20
+
21
+ # Offense count: 5
22
+ ClassVars:
23
+ Enabled: false
24
+
25
+ # Offense count: 75
26
+ Documentation:
27
+ Enabled: false
28
+
29
+ # Offense count: 20
30
+ Encoding:
31
+ Enabled: false
32
+
33
+ # Offense count: 1
34
+ Eval:
35
+ Enabled: false
36
+
37
+ # Offense count: 1
38
+ FavorUnlessOverNegatedIf:
39
+ Enabled: false
40
+
41
+ # Offense count: 2
42
+ # Configuration parameters: Exclude.
43
+ FileName:
44
+ Enabled: false
45
+
46
+ # Offense count: 27
47
+ # Configuration parameters: AllowedVariables.
48
+ GlobalVars:
49
+ Enabled: false
50
+
51
+ # Offense count: 1
52
+ HandleExceptions:
53
+ Enabled: false
54
+
55
+ # Offense count: 75
56
+ LineLength:
57
+ Max: 161
58
+
59
+ # Offense count: 1
60
+ # Configuration parameters: CountComments.
61
+ MethodLength:
62
+ Max: 17
63
+
64
+ # Offense count: 1
65
+ ModuleFunction:
66
+ Enabled: false
67
+
68
+ # Offense count: 2
69
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
70
+ RaiseArgs:
71
+ Enabled: false
72
+
73
+ # Offense count: 3
74
+ RedundantBegin:
75
+ Enabled: false
76
+
77
+ # Offense count: 1
78
+ UnlessElse:
79
+ Enabled: false
80
+
81
+ # Offense count: 1
82
+ UnreachableCode:
83
+ Enabled: false
84
+
85
+ # Offense count: 5
86
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
87
+ VariableName:
88
+ Enabled: false
89
+
90
+ # Offense count: 11
91
+ Void:
92
+ Enabled: false
@@ -0,0 +1 @@
1
+ SimpleCov.start { add_filter '/spec/' } if ENV['COVERAGE']
@@ -0,0 +1,12 @@
1
+ ---
2
+ language: ruby
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.1.1
6
+ env:
7
+ global:
8
+ - RESQUE_LONER_DISABLE_TEST_REDIS_SERVER=1
9
+ - COVERAGE=1
10
+ - secure: c9PvRm9w0ewSsS1QDogwPCvSXO+xgHm0mcVA+iiUknezitNjDwaTuBqGtLJ/PjMnQ16QfG0ApDvSqqOw9rSjwM7meCqiQZlJRqqyd547PNhbP6J56mtuXvxMM7wvulK/aLeIYwDeON0Do52FSY4l2/oN2QvA2hIvX8RTDyrfdaA=
11
+ services:
12
+ - redis-server
@@ -1,3 +1,14 @@
1
+ 1.3.0
2
+ --------------------------------
3
+ Enhancements and bug fixes from @mateusdelbianco. Not allowing a job to
4
+ be executed immediately after execution, another from @mateusdelbianco!
5
+ Merged @andrejj's fix which removes an unused `#first` from a redis
6
+ multi call. @kforsman created an internal helpers module to remove the
7
+ dependency on the deprecated `Resque::Helpers` module. Added RuboCop,
8
+ SimpleCov, and CodeClimate, plus tweaked some stuff in Travis
9
+ configuration.
10
+
11
+
1
12
  1.2.1
2
13
  --------------------------------
3
14
  Merged @aerodynamik's pull request. Enqueuing and marking as
data/Gemfile CHANGED
@@ -1,8 +1,7 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  source 'http://rubygems.org'
3
+
2
4
  gemspec
3
5
 
4
- group :development do
5
- gem 'gemcutter'
6
- gem 'ruby-debug', :platform => :mri_18
7
- gem 'ruby-debug19', :platform => :mri_19
8
- end
6
+ gem 'debugger', group: :development, platform: :mri_19
7
+ gem 'codeclimate-test-reporter', group: :test, require: nil
@@ -1,6 +1,9 @@
1
1
  Resque-Loner
2
2
  ======
3
3
 
4
+ [![Build Status](https://secure.travis-ci.org/resque/resque-loner.png?branch=master)](https://travis-ci.org/resque/resque-loner)
5
+ [![Code Climate](https://codeclimate.com/github/resque/resque-loner.png)](https://codeclimate.com/github/resque/resque-loner)
6
+
4
7
  Resque-Loner is a plugin for defunkt/resque which adds unique jobs to resque: Only one job with the same payload per queue.
5
8
 
6
9
 
@@ -20,7 +23,7 @@ Tests
20
23
  -----------
21
24
  To make sure this plugin works on your installation, you should run the tests. resque-loner is tested in RSpec, but it also includes resque's original testsuite. You can run all tests specific to resque-loner with `rake spec`.
22
25
 
23
- To make sure the plugin did not break resque, you can run `rake test` (the standard resque test suite). This runs all tests from the 1.10.0 version of resque, so make sure you have that version of resque installed, when you run the resque-tests.
26
+ To make sure the plugin did not break resque, you can run `rake test` (the standard resque test suite). This runs all tests from the 1.22.0 version of resque, so make sure you have that version of resque installed, when you run the resque-tests.
24
27
 
25
28
  Example
26
29
  --------
data/Rakefile CHANGED
@@ -1,49 +1,32 @@
1
- #
2
- # Setup
3
- #
4
-
5
1
  $LOAD_PATH.unshift 'lib'
6
2
 
7
- require "rubygems"
8
- require "bundler"
3
+ require 'rubygems'
4
+ require 'bundler'
9
5
  Bundler.setup
10
6
 
11
7
  require 'rspec/core/rake_task'
12
-
13
8
  load 'tasks/redis.rake'
14
9
  require 'rake/testtask'
15
-
16
10
  require 'resque/tasks'
17
-
18
11
  require 'bundler/gem_tasks'
12
+ require 'rubocop/rake_task'
19
13
 
20
14
  def command?(command)
21
15
  system("type #{command} > /dev/null 2>&1")
22
16
  end
23
17
 
18
+ task default: [:rubocop, :spec]
24
19
 
25
- #
26
- # Tests
27
- #
28
-
29
- task :default => :spec
20
+ Rubocop::RakeTask.new
30
21
 
31
- desc "Run specs for resque-loner"
22
+ desc 'Run specs for resque-loner'
32
23
  RSpec::Core::RakeTask.new(:spec) do |t|
33
- t.pattern = "spec/**/*_spec.rb"
24
+ t.pattern = 'spec/**/*_spec.rb'
34
25
  t.rspec_opts = %w(-fd -c)
35
26
  end
36
27
 
37
- # desc "Run resque's test suite to make sure we did not break anything"
38
- # task :test do
39
- # rg = command?(:rg)
40
- # Dir['test/**/*_test.rb'].each do |f|
41
- # rg ? sh("rg #{f}") : ruby(f)
42
- # end
43
- # end
44
-
45
28
  if command?(:rg)
46
- desc "Run the test suite with rg"
29
+ desc 'Run the test suite with rg'
47
30
  task :test do
48
31
  Dir['test/**/*_test.rb'].each do |f|
49
32
  sh("rg #{f}")
@@ -51,33 +34,22 @@ if command?(:rg)
51
34
  end
52
35
  else
53
36
  Rake::TestTask.new do |test|
54
- test.libs << "test"
37
+ test.libs << 'test'
55
38
  test.test_files = FileList['test/**/*_test.rb']
56
39
  end
57
40
  end
58
41
 
59
42
  if command? :kicker
60
- desc "Launch Kicker (like autotest)"
43
+ desc 'Launch Kicker (like autotest)'
61
44
  task :kicker do
62
- puts "Kicking... (ctrl+c to cancel)"
63
- exec "kicker -e rake test lib examples"
45
+ puts 'Kicking... (ctrl+c to cancel)'
46
+ exec 'kicker -e rake test lib examples'
64
47
  end
65
48
  end
66
49
 
67
-
68
- #
69
- # Install
70
- #
71
-
72
- task :install => [ 'redis:install', 'dtach:install' ]
73
-
74
-
75
- #
76
- # Documentation
77
- #
50
+ task :install => ['redis:install', 'dtach:install']
78
51
 
79
52
  begin
80
53
  require 'sdoc_helpers'
81
54
  rescue LoadError
82
55
  end
83
-
@@ -2,24 +2,24 @@
2
2
  # Since there were not enough hooks to hook into, I have to overwrite
3
3
  # 3 methods of Resque::Job - the rest of the implementation is in the
4
4
  # proper Plugin namespace.
5
- #
5
+ #
6
6
  module Resque
7
7
  class Job
8
-
9
-
10
8
  #
11
9
  # Overwriting original create method to mark an item as queued
12
10
  # after Resque::Job.create has called Resque.push
13
11
  #
14
12
  def self.create_with_loner(queue, klass, *args)
15
13
  return create_without_loner(queue, klass, *args) if Resque.inline?
16
- item = { :class => klass.to_s, :args => args }
17
- return "EXISTED" if Resque::Plugins::Loner::Helpers.loner_queued?(queue, item)
14
+ item = { class: klass.to_s, args: args }
15
+ return 'EXISTED' if Resque::Plugins::Loner::Helpers.loner_queued?(queue, item)
18
16
  # multi block returns array of keys
17
+ create_return_value = false
19
18
  Resque.redis.multi do
20
- create_without_loner(queue, klass, *args)
19
+ create_return_value = create_without_loner(queue, klass, *args)
21
20
  Resque::Plugins::Loner::Helpers.mark_loner_as_queued(queue, item)
22
- end.first
21
+ end
22
+ create_return_value
23
23
  end
24
24
 
25
25
  #
@@ -27,13 +27,13 @@ module Resque
27
27
  #
28
28
  def self.reserve_with_loner(queue)
29
29
  item = reserve_without_loner(queue)
30
- Resque::Plugins::Loner::Helpers.mark_loner_as_unqueued( queue, item ) if item && !Resque.inline?
30
+ Resque::Plugins::Loner::Helpers.mark_loner_as_unqueued(queue, item) if item && !Resque.inline?
31
31
  item
32
32
  end
33
33
 
34
34
  #
35
35
  # Overwriting original destroy method to mark all destroyed jobs as unqueued.
36
- # Because the original method only returns the amount of jobs destroyed, but not
36
+ # Because the original method only returns the amount of jobs destroyed, but not
37
37
  # the jobs themselves. Hence Resque::Plugins::Loner::Helpers.job_destroy looks almost
38
38
  # as the original method Resque::Job.destroy. Couldn't make it any dry'er.
39
39
  #
@@ -1,26 +1,21 @@
1
1
  module Resque
2
-
3
- def self.enqueued?( klass, *args)
4
- enqueued_in?(queue_from_class(klass), klass, *args )
2
+ def self.enqueued?(klass, *args)
3
+ enqueued_in?(queue_from_class(klass), klass, *args)
5
4
  end
6
5
 
7
6
  def self.enqueued_in?(queue, klass, *args)
8
- item = { :class => klass.to_s, :args => args }
7
+ item = { class: klass.to_s, args: args }
9
8
  return nil unless Resque::Plugins::Loner::Helpers.item_is_a_unique_job?(item)
10
9
  Resque::Plugins::Loner::Helpers.loner_queued?(queue, item)
11
10
  end
12
11
 
13
12
  def self.remove_queue_with_loner_cleanup(queue)
14
- self.remove_queue_without_loner_cleanup(queue)
13
+ remove_queue_without_loner_cleanup(queue)
15
14
  Resque::Plugins::Loner::Helpers.cleanup_loners(queue)
16
15
  end
17
16
 
18
-
19
17
  class << self
20
-
21
18
  alias_method :remove_queue_without_loner_cleanup, :remove_queue
22
19
  alias_method :remove_queue, :remove_queue_with_loner_cleanup
23
-
24
20
  end
25
-
26
21
  end
@@ -2,5 +2,6 @@ require 'rubygems'
2
2
  require 'resque'
3
3
  require 'resque-loner/unique_job'
4
4
  require 'resque-loner/helpers'
5
+ require 'resque-loner/legacy_helpers'
5
6
  require 'resque-ext/job'
6
- require 'resque-ext/resque'
7
+ require 'resque-ext/resque'
@@ -1,19 +1,21 @@
1
+ require 'resque-loner/legacy_helpers'
2
+
1
3
  module Resque
2
4
  module Plugins
3
5
  module Loner
4
6
  class Helpers
5
- extend Resque::Helpers
7
+ extend Resque::Plugins::Loner::LegacyHelpers
6
8
 
7
9
  def self.loner_queued?(queue, item)
8
10
  return false unless item_is_a_unique_job?(item)
9
- redis.get(unique_job_queue_key(queue, item)) == "1"
11
+ redis.get(unique_job_queue_key(queue, item)) == '1'
10
12
  end
11
13
 
12
14
  def self.mark_loner_as_queued(queue, item)
13
15
  return unless item_is_a_unique_job?(item)
14
16
  key = unique_job_queue_key(queue, item)
15
17
  redis.set(key, 1)
16
- unless(ttl=item_ttl(item)) == -1 # no need to incur overhead for default value
18
+ unless (ttl = item_ttl(item)) == -1 # no need to incur overhead for default value
17
19
  redis.expire(key, ttl)
18
20
  end
19
21
  end
@@ -21,17 +23,21 @@ module Resque
21
23
  def self.mark_loner_as_unqueued(queue, job)
22
24
  item = job.is_a?(Resque::Job) ? job.payload : job
23
25
  return unless item_is_a_unique_job?(item)
24
- redis.del(unique_job_queue_key(queue, item))
26
+ unless (ttl = loner_lock_after_execution_period(item)) == 0
27
+ redis.expire(unique_job_queue_key(queue, item), ttl)
28
+ else
29
+ redis.del(unique_job_queue_key(queue, item))
30
+ end
25
31
  end
26
32
 
27
33
  def self.unique_job_queue_key(queue, item)
28
- job_key = constantize(item[:class] || item["class"]).redis_key(item)
34
+ job_key = constantize(item[:class] || item['class']).redis_key(item)
29
35
  "loners:queue:#{queue}:job:#{job_key}"
30
36
  end
31
37
 
32
38
  def self.item_is_a_unique_job?(item)
33
39
  begin
34
- klass = constantize(item[:class] || item["class"])
40
+ klass = constantize(item[:class] || item['class'])
35
41
  klass.included_modules.include?(::Resque::Plugins::UniqueJob)
36
42
  rescue
37
43
  false # Resque testsuite also submits strings as job classes while Resque.enqueue'ing,
@@ -40,12 +46,20 @@ module Resque
40
46
 
41
47
  def self.item_ttl(item)
42
48
  begin
43
- constantize(item[:class] || item["class"]).loner_ttl
49
+ constantize(item[:class] || item['class']).loner_ttl
44
50
  rescue
45
51
  -1
46
52
  end
47
53
  end
48
54
 
55
+ def self.loner_lock_after_execution_period(item)
56
+ begin
57
+ constantize(item[:class] || item['class']).loner_lock_after_execution_period
58
+ rescue
59
+ 0
60
+ end
61
+ end
62
+
49
63
  def self.job_destroy(queue, klass, *args)
50
64
  klass = klass.to_s
51
65
  redis_queue = "queue:#{queue}"
@@ -57,7 +71,7 @@ module Resque
57
71
  match &= json['args'] == args unless args.empty?
58
72
 
59
73
  if match
60
- Resque::Plugins::Loner::Helpers.mark_loner_as_unqueued( queue, json )
74
+ Resque::Plugins::Loner::Helpers.mark_loner_as_unqueued(queue, json)
61
75
  end
62
76
  end
63
77
  end
@@ -66,7 +80,6 @@ module Resque
66
80
  keys = redis.keys("loners:queue:#{queue}:job:*")
67
81
  redis.del(*keys) unless keys.empty?
68
82
  end
69
-
70
83
  end
71
84
  end
72
85
  end