resque-restriction 0.2.1 → 0.2.2

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.
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  spec/dump.rdb
2
2
  pkg/**
3
+ .idea
4
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.2.2
@@ -4,12 +4,28 @@ module Resque
4
4
  alias_method :origin_reserve, :reserve
5
5
 
6
6
  def reserve(queue)
7
- if queue == 'restriction' && payload = Resque.pop(queue)
8
- constantize(payload['class']).repush(*payload['args'])
9
- return
7
+ if queue =~ /^#{Plugins::Restriction::RESTRICTION_QUEUE_PREFIX}/
8
+ # If processing the restriction queue, when poping and pushing to end,
9
+ # we can't tell when we reach the original one, so just walk the length
10
+ # of the queue so we don't run infinitely long
11
+ Resque.size(queue).times do |i|
12
+ # For the job at the head of the queue, repush to restricition queue
13
+ # if still restricted, otherwise we have a runnable job, so create it
14
+ # and return
15
+ payload = Resque.pop(queue)
16
+ if payload
17
+ if ! constantize(payload['class']).repush(*payload['args'])
18
+ return new(queue, payload)
19
+ end
20
+ end
21
+ end
22
+ return nil
23
+ else
24
+ # drop through to original Job::Reserve if not restriction queue
25
+ origin_reserve(queue)
10
26
  end
11
- origin_reserve(queue)
12
27
  end
28
+
13
29
  end
14
30
  end
15
31
  end
@@ -9,6 +9,7 @@ module Resque
9
9
  :per_month => 31*24*60*60,
10
10
  :per_year => 366*24*60*60
11
11
  }
12
+ RESTRICTION_QUEUE_PREFIX = 'restriction'
12
13
 
13
14
  def settings
14
15
  @options ||= {}
@@ -40,7 +41,7 @@ module Resque
40
41
  # reincrement the keys if one of the periods triggers DontPerform so
41
42
  # that we accurately track capacity
42
43
  keys_decremented.each {|k| Resque.redis.incrby(k, 1) }
43
- Resque.push "restriction", :class => to_s, :args => args
44
+ Resque.push restriction_queue_name, :class => to_s, :args => args
44
45
  raise Resque::Job::DontPerform
45
46
  end
46
47
  end
@@ -72,6 +73,11 @@ module Resque
72
73
  self.to_s
73
74
  end
74
75
 
76
+ def restriction_queue_name
77
+ queue_name = Resque.queue_from_class(self)
78
+ "#{RESTRICTION_QUEUE_PREFIX}_#{queue_name}"
79
+ end
80
+
75
81
  def seconds(period)
76
82
  if SECONDS.keys.include? period
77
83
  SECONDS[period]
@@ -80,18 +86,23 @@ module Resque
80
86
  end
81
87
  end
82
88
 
89
+ # if job is still restricted, push back to restriction queue, otherwise push
90
+ # to real queue. Since the restrictions will be checked again when run from
91
+ # real queue, job will just get pushed back onto restriction queue then if
92
+ # restriction conditions have changed
83
93
  def repush(*args)
84
- no_restrictions = true
85
- queue_name = Resque.queue_from_class(self)
94
+ has_restrictions = false
86
95
  settings.each do |period, number|
87
96
  key = redis_key(period, *args)
88
97
  value = Resque.redis.get(key)
89
- no_restrictions &&= (value.nil? or value == "" or value.to_i > 0)
98
+ has_restrictions = value && value != "" && value.to_i <= 0
99
+ break if has_restrictions
90
100
  end
91
- if no_restrictions
92
- Resque.push queue_name, :class => to_s, :args => args
101
+ if has_restrictions
102
+ Resque.push restriction_queue_name, :class => to_s, :args => args
103
+ return true
93
104
  else
94
- Resque.push "restriction", :class => to_s, :args => args
105
+ return false
95
106
  end
96
107
  end
97
108
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{resque-restriction}
8
- s.version = "0.2.1"
8
+ s.version = "0.2.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Richard Huang"]
12
- s.date = %q{2010-07-10}
12
+ s.date = %q{2010-09-09}
13
13
  s.description = %q{resque-restriction is an extension to resque queue system that restricts the execution number of certain jobs in a period time, the exceeded jobs will be executed at the next period.}
14
14
  s.email = %q{flyerhzm@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -1,20 +1,22 @@
1
1
  require File.join(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe Resque::Job do
4
- it "should repush restriction queue when reserve" do
4
+ before(:each) do
5
5
  Resque.redis.flushall
6
- Resque.push('restriction', :class => 'OneHourRestrictionJob', :args => ['any args'])
7
- Resque::Job.reserve('restriction').should be_nil
8
- Resque::Job.reserve('normal').should == Resque::Job.new('normal', {'class' => 'OneHourRestrictionJob', 'args' => ['any args']})
6
+ end
7
+
8
+ it "should repush restriction queue when reserve" do
9
+ Resque.push('restriction_normal', :class => 'OneHourRestrictionJob', :args => ['any args'])
10
+ Resque::Job.reserve('restriction_normal').should == Resque::Job.new('restriction_normal', {'class' => 'OneHourRestrictionJob', 'args' => ['any args']})
11
+ Resque::Job.reserve('restriction_normal').should be_nil
9
12
  Resque::Job.reserve('normal').should be_nil
10
13
  end
11
14
 
12
15
  it "should push back to restriction queue when still restricted" do
13
- Resque.redis.flushall
14
16
  Resque.redis.set(OneHourRestrictionJob.redis_key(:per_hour), -1)
15
- Resque.push('restriction', :class => 'OneHourRestrictionJob', :args => ['any args'])
16
- Resque::Job.reserve('restriction').should be_nil
17
- Resque.pop('restriction').should == {'class' => 'OneHourRestrictionJob', 'args' => ['any args']}
17
+ Resque.push('restriction_normal', :class => 'OneHourRestrictionJob', :args => ['any args'])
18
+ Resque::Job.reserve('restriction_normal').should be_nil
19
+ Resque.pop('restriction_normal').should == {'class' => 'OneHourRestrictionJob', 'args' => ['any args']}
18
20
  Resque::Job.reserve('normal').should be_nil
19
21
  end
20
22
 
@@ -22,5 +24,16 @@ describe Resque::Job do
22
24
  Resque.push('normal', :class => 'OneHourRestrictionJob', :args => ['any args'])
23
25
  Resque::Job.reserve('normal').should == Resque::Job.new('normal', {'class' => 'OneHourRestrictionJob', 'args' => ['any args']})
24
26
  Resque::Job.reserve('normal').should be_nil
27
+ Resque::Job.reserve('restriction_normal').should be_nil
25
28
  end
29
+
30
+ it "should only push back queue_length times to restriction queue" do
31
+ Resque.redis.set(OneHourRestrictionJob.redis_key(:per_hour), -1)
32
+ 3.times { Resque.push('restriction_normal', :class => 'OneHourRestrictionJob', :args => ['any args']) }
33
+ Resque.size('restriction_normal').should == 3
34
+ OneHourRestrictionJob.should_receive(:repush).exactly(3).times.and_return(true)
35
+ Resque::Job.reserve('restriction_normal')
36
+ end
37
+
38
+
26
39
  end
@@ -82,7 +82,7 @@ describe Resque::Plugins::RestrictionJob do
82
82
  result = perform_job(OneHourRestrictionJob, "any args")
83
83
  result.should_not be_true
84
84
  Resque.redis.get(OneHourRestrictionJob.redis_key(:per_hour)).should == "0"
85
- Resque.redis.lrange("queue:restriction", 0, -1).should == [Resque.encode(:class => "OneHourRestrictionJob", :args => ["any args"])]
85
+ Resque.redis.lrange("queue:restriction_normal", 0, -1).should == [Resque.encode(:class => "OneHourRestrictionJob", :args => ["any args"])]
86
86
  end
87
87
 
88
88
  context "multiple restrict" do
@@ -107,5 +107,20 @@ describe Resque::Plugins::RestrictionJob do
107
107
  Resque.redis.get(MultipleRestrictionJob.redis_key(:per_300)).should == "1"
108
108
  end
109
109
  end
110
+
111
+ context "repush" do
112
+ it "should push restricted jobs onto restriction queue" do
113
+ Resque.redis.set(OneHourRestrictionJob.redis_key(:per_hour), -1)
114
+ Resque.should_receive(:push).once.with('restriction_normal', :class => 'OneHourRestrictionJob', :args => ['any args'])
115
+ OneHourRestrictionJob.repush('any args').should be_true
116
+ end
117
+
118
+ it "should not push unrestricted jobs onto restriction queue" do
119
+ Resque.redis.set(OneHourRestrictionJob.redis_key(:per_hour), 1)
120
+ Resque.should_not_receive(:push)
121
+ OneHourRestrictionJob.repush('any args').should be_false
122
+ end
123
+
124
+ end
110
125
  end
111
126
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 1
9
- version: 0.2.1
8
+ - 2
9
+ version: 0.2.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Richard Huang
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-07-10 00:00:00 +08:00
17
+ date: 2010-09-09 00:00:00 +08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency