que 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: que
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Hanks
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-07 00:00:00.000000000 Z
11
+ date: 2013-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -73,7 +73,21 @@ dependencies:
73
73
  - - '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
- type: :runtime
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activerecord
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
@@ -87,14 +101,28 @@ dependencies:
87
101
  - - '>='
88
102
  - !ruby/object:Gem::Version
89
103
  version: '0'
90
- type: :runtime
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: connection_pool
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
122
  - - '>='
95
123
  - !ruby/object:Gem::Version
96
124
  version: '0'
97
- description: Durable job queueing with PostgreSQL.
125
+ description: A job queue that uses PostgreSQL's advisory locks for speed and reliability.
98
126
  email:
99
127
  - christopher.m.hanks@gmail.com
100
128
  executables: []
@@ -107,17 +135,37 @@ files:
107
135
  - LICENSE.txt
108
136
  - README.md
109
137
  - Rakefile
138
+ - lib/generators/que/install_generator.rb
139
+ - lib/generators/que/templates/add_que.rb
110
140
  - lib/que.rb
141
+ - lib/que/adapters/active_record.rb
142
+ - lib/que/adapters/base.rb
143
+ - lib/que/adapters/connection_pool.rb
144
+ - lib/que/adapters/pg.rb
145
+ - lib/que/adapters/sequel.rb
111
146
  - lib/que/job.rb
147
+ - lib/que/railtie.rb
148
+ - lib/que/rake_tasks.rb
149
+ - lib/que/sql.rb
112
150
  - lib/que/version.rb
113
151
  - lib/que/worker.rb
114
152
  - que.gemspec
153
+ - spec/adapters/active_record_spec.rb
154
+ - spec/adapters/connection_pool_spec.rb
155
+ - spec/adapters/pg_spec.rb
156
+ - spec/adapters/sequel_spec.rb
157
+ - spec/connection_spec.rb
158
+ - spec/helper_spec.rb
159
+ - spec/pool_spec.rb
160
+ - spec/queue_spec.rb
115
161
  - spec/spec_helper.rb
116
- - spec/unit/error_spec.rb
117
- - spec/unit/queue_spec.rb
118
- - spec/unit/work_spec.rb
119
- - spec/unit/worker_spec.rb
120
- homepage: ''
162
+ - spec/support/helpers.rb
163
+ - spec/support/jobs.rb
164
+ - spec/support/shared_examples/adapter.rb
165
+ - spec/support/shared_examples/multithreaded_adapter.rb
166
+ - spec/work_spec.rb
167
+ - spec/worker_spec.rb
168
+ homepage: https://github.com/chanks/que
121
169
  licenses:
122
170
  - MIT
123
171
  metadata: {}
@@ -140,10 +188,20 @@ rubyforge_project:
140
188
  rubygems_version: 2.1.9
141
189
  signing_key:
142
190
  specification_version: 4
143
- summary: Durable, efficient job queueing with PostgreSQL.
191
+ summary: A PostgreSQL-based Job Queue
144
192
  test_files:
193
+ - spec/adapters/active_record_spec.rb
194
+ - spec/adapters/connection_pool_spec.rb
195
+ - spec/adapters/pg_spec.rb
196
+ - spec/adapters/sequel_spec.rb
197
+ - spec/connection_spec.rb
198
+ - spec/helper_spec.rb
199
+ - spec/pool_spec.rb
200
+ - spec/queue_spec.rb
145
201
  - spec/spec_helper.rb
146
- - spec/unit/error_spec.rb
147
- - spec/unit/queue_spec.rb
148
- - spec/unit/work_spec.rb
149
- - spec/unit/worker_spec.rb
202
+ - spec/support/helpers.rb
203
+ - spec/support/jobs.rb
204
+ - spec/support/shared_examples/adapter.rb
205
+ - spec/support/shared_examples/multithreaded_adapter.rb
206
+ - spec/work_spec.rb
207
+ - spec/worker_spec.rb
@@ -1,45 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Que::Job error handling" do
4
- class ErrorJob < Que::Job
5
- def perform(*args)
6
- raise "Boo!"
7
- end
8
- end
9
-
10
- it "should increment the error_count, persist the error message and reschedule the job" do
11
- ErrorJob.queue
12
-
13
- proc { Que::Job.work }.should raise_error RuntimeError, "Boo!"
14
- Que::Job.count.should be 1
15
-
16
- job = Que::Job.first
17
- data = JSON.load(job.data)
18
- data['error_count'].should be 1
19
- data['error_message'].should =~ /Boo!/
20
- job.run_at.should be_within(1).of Time.now + 4
21
- end
22
-
23
- it "should reschedule jobs with exponentially increasing times" do
24
- ErrorJob.queue
25
- Que::Job.dataset.update :data => JSON.dump(:error_count => 5)
26
-
27
- proc { Que::Job.work }.should raise_error RuntimeError, "Boo!"
28
- Que::Job.count.should be 1
29
-
30
- job = Que::Job.first
31
- data = JSON.load(job.data)
32
- data['error_count'].should be 6
33
- data['error_message'].should =~ /Boo!/
34
- job.run_at.should be_within(1).of Time.now + 1299
35
- end
36
-
37
- it "should handle errors from jobs that cannot be deserialized" do
38
- DB[:jobs].insert :type => 'NonexistentJob', :priority => 1
39
- proc { Que::Job.work }.should raise_error NameError, /uninitialized constant NonexistentJob/
40
-
41
- job = DB[:jobs].first
42
- JSON.load(job[:data])['error_count'].should be 1
43
- job[:run_at].should be_within(1).of Time.now + 4
44
- end
45
- end
@@ -1,67 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Que::Job.queue" do
4
- it "should create a job in the DB" do
5
- Que::Job.queue :param1 => 4, :param2 => 'ferret', :param3 => false
6
- Que::Job.count.should == 1
7
-
8
- job = Que::Job.first
9
- job.type.should == 'Que::Job'
10
- job.run_at.should be_within(1).of Time.now
11
- job.priority.should be 5 # Defaults to lowest priority.
12
- JSON.load(job.args).should == [{'param1' => 4, 'param2' => 'ferret', 'param3' => false}]
13
- end
14
-
15
- it "should accept a :run_at argument" do
16
- time = Time.at(Time.now.to_i)
17
- Que::Job.queue :user_id => 4, :test_number => 8, :run_at => time
18
-
19
- Que::Job.count.should == 1
20
- job = Que::Job.first
21
- job.type.should == 'Que::Job'
22
- job.run_at.should == time
23
- job.priority.should == 5
24
- JSON.load(job.args).should == [{'user_id' => 4, 'test_number' => 8}]
25
- end
26
-
27
- it "should accept a :priority argument" do
28
- Que::Job.queue :user_id => 4, :test_number => 8, :priority => 1
29
-
30
- Que::Job.count.should == 1
31
- job = Que::Job.first
32
- job.type.should == 'Que::Job'
33
- job.run_at.should be_within(1).of Time.now
34
- job.priority.should be 1
35
- JSON.load(job.args).should == [{'user_id' => 4, 'test_number' => 8}]
36
- end
37
-
38
- it "should respect a default_priority for the class" do
39
- class TestPriorityJob < Que::Job
40
- @default_priority = 2
41
- end
42
-
43
- TestPriorityJob.queue :user_id => 4, :test_number => 8
44
-
45
- Que::Job.count.should == 1
46
- job = Que::Job.first
47
- job.type.should == 'TestPriorityJob'
48
- job.run_at.should be_within(1).of Time.now
49
- job.priority.should be 2
50
- JSON.load(job.args).should == [{'user_id' => 4, 'test_number' => 8}]
51
- end
52
-
53
- it "should let a :priority option override a default_priority for the class" do
54
- class OtherTestPriorityJob < Que::Job
55
- @default_priority = 2
56
- end
57
-
58
- OtherTestPriorityJob.queue :user_id => 4, :test_number => 8, :priority => 4
59
-
60
- Que::Job.count.should == 1
61
- job = Que::Job.first
62
- job.type.should == 'OtherTestPriorityJob'
63
- job.run_at.should be_within(1).of Time.now
64
- job.priority.should be 4
65
- JSON.load(job.args).should == [{'user_id' => 4, 'test_number' => 8}]
66
- end
67
- end
@@ -1,168 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Que::Job.work" do
4
- it "should automatically delete jobs from the database's queue" do
5
- Que::Job.count.should be 0
6
- Que::Job.queue
7
- Que::Job.count.should be 1
8
- Que::Job.work
9
- Que::Job.count.should be 0
10
- end
11
-
12
- it "should pass a job's arguments to its perform method" do
13
- class JobWorkTest < Que::Job
14
- def perform(*args)
15
- $passed_args = args
16
- end
17
- end
18
-
19
- JobWorkTest.queue 5, 'ferret', :lazy => true
20
-
21
- Que::Job.work
22
- $passed_args.should == [5, 'ferret', {'lazy' => true}]
23
- end
24
-
25
- it "should prefer a job with higher priority" do
26
- Que::Job.queue
27
- Que::Job.queue :priority => 1
28
-
29
- Que::Job.select_order_map(:priority).should == [1, 5]
30
- Que::Job.work
31
- Que::Job.select_order_map(:priority).should == [5]
32
- end
33
-
34
- it "should prefer a job that was scheduled to run longer ago" do
35
- now = Time.at(Time.now.to_i) # Prevent rounding errors by rounding to the nearest second.
36
- recently = now - 60
37
- long_ago = now - 61
38
-
39
- Que::Job.queue :run_at => recently
40
- Que::Job.queue :run_at => long_ago
41
-
42
- Que::Job.select_order_map(:run_at).should == [long_ago, recently]
43
- Que::Job.work
44
- Que::Job.select_order_map(:run_at).should == [recently]
45
- end
46
-
47
- it "should only work a job whose run_at has already passed" do
48
- now = Time.at(Time.now.to_i) # Prevent rounding errors by rounding to the nearest second.
49
- past = now - 60
50
- soon = now + 60
51
-
52
- Que::Job.queue :run_at => past
53
- Que::Job.queue :run_at => soon
54
-
55
- Que::Job.select_order_map(:run_at).should == [past, soon]
56
- Que::Job.work
57
- Que::Job.select_order_map(:run_at).should == [soon]
58
- Que::Job.work
59
- Que::Job.select_order_map(:run_at).should == [soon]
60
- end
61
-
62
- it "should prefer a job that was scheduled earlier, and therefore has a lower job_id" do
63
- time = Time.now - 60
64
- Que::Job.queue :run_at => time
65
- Que::Job.queue :run_at => time
66
-
67
- a, b = Que::Job.select_order_map(:job_id)
68
- Que::Job.work
69
- Que::Job.select_order_map(:job_id).should == [b]
70
- end
71
-
72
- it "should lock the job it selects" do
73
- $q1, $q2 = Queue.new, Queue.new
74
-
75
- class LockJob < Que::Job
76
- def perform(*args)
77
- $q1.push nil
78
- $q2.pop
79
- end
80
- end
81
-
82
- job = LockJob.queue
83
- @thread = Thread.new { Que::Job.work }
84
-
85
- # Wait until job is being worked.
86
- $q1.pop
87
-
88
- # Job should be advisory-locked...
89
- DB.select{pg_try_advisory_lock(job.job_id)}.single_value.should be false
90
-
91
- # ...and Job.work should ignore advisory-locked jobs.
92
- Que::Job.work.should be nil
93
-
94
- # Let LockJob finish.
95
- $q2.push nil
96
-
97
- # Make sure there aren't any errors.
98
- @thread.join
99
- end
100
-
101
- it "that raises a Que::Job::Retry should abort the job, leaving it to be retried" do
102
- class RetryJob < Que::Job
103
- def perform(*args)
104
- raise Que::Job::Retry
105
- end
106
- end
107
-
108
- job = RetryJob.queue
109
- Que::Job.count.should be 1
110
- Que::Job.work
111
- Que::Job.count.should be 1
112
-
113
- same_job = Que::Job.first
114
- same_job.job_id.should == job.job_id
115
- same_job.run_at.should == job.run_at
116
- same_job.data['error_count'].should be nil
117
- end
118
-
119
- it "should handle subclasses of other jobs" do
120
- $class_job_array = []
121
-
122
- class ClassJob < Que::Job
123
- def perform(*args)
124
- $class_job_array << 2
125
- end
126
- end
127
-
128
- class SubclassJob < ClassJob
129
- def perform(*args)
130
- $class_job_array << 1
131
- super
132
- end
133
- end
134
-
135
- SubclassJob.queue
136
- Que::Job.get(:type).should == 'SubclassJob'
137
- Que::Job.work
138
- $class_job_array.should == [1, 2]
139
- end
140
-
141
- describe "should support a logger" do
142
- before do
143
- @logger = Object.new
144
- def @logger.method_missing(m, message)
145
- @messages ||= []
146
- @messages << message
147
- end
148
- Que.logger = @logger
149
- end
150
-
151
- after do
152
- Que.logger = nil
153
- end
154
-
155
- def messages
156
- @logger.instance_variable_get(:@messages)
157
- end
158
-
159
- it "should write messages to the logger" do
160
- Que::Job.queue
161
- Que::Job.work
162
-
163
- messages.should be_an_instance_of Array
164
- messages.length.should == 1
165
- messages[0].should =~ /\AWorked job in/
166
- end
167
- end
168
- end
@@ -1,31 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Que::Worker do
4
- class ExceptionJob < Que::Job
5
- def perform(*args)
6
- raise "Blah!"
7
- end
8
- end
9
-
10
- it "should not be taken out by an error, and keep looking for jobs" do
11
- ExceptionJob.queue
12
- Que::Job.queue
13
-
14
- Que::Worker.state = :async
15
- Que::Worker.wake!
16
- @worker = Que::Worker.workers.first
17
-
18
- {} until @worker.thread[:state] == :sleeping
19
-
20
- # Job was worked, ExceptionJob remains.
21
- Que::Job.select_map(:type).should == ['ExceptionJob']
22
- end
23
-
24
- it "#async? and #up? should return whether Worker is async and whether there are workers running, respectively" do
25
- Que::Worker.should_not be_async
26
- Que::Worker.should_not be_up
27
- Que::Worker.state = :async
28
- Que::Worker.should be_async
29
- Que::Worker.should be_up
30
- end
31
- end