matthewrudy-rudeq 2.0 → 2.1.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.
- data/MIT-LICENSE +20 -0
- data/generators/rude_q/USAGE +24 -0
- data/generators/rude_q/rude_q_generator.rb +27 -0
- data/generators/rude_q/templates/rude_q_migration.rb +18 -0
- data/generators/rude_q/templates/rude_q_model.rb +3 -0
- data/generators/rude_q/templates/rude_q_model_spec.rb +71 -0
- data/lib/rude_q.rb +36 -8
- data/lib/rude_q/scope.rb +24 -0
- data/lib/rude_q/worker.rb +66 -0
- data/spec/{process_queue.rb → models/rude_queue.rb} +3 -2
- data/spec/models/something.rb +3 -0
- data/spec/rude_q_spec.rb +122 -110
- data/spec/schema.rb +11 -4
- data/spec/spec_helper.rb +5 -3
- data/spec/worker_spec.rb +49 -0
- data/tasks/rude_q_tasks.rake +25 -0
- metadata +18 -5
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2008 [Matthew Rudy Jacobs]
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Description:
|
|
2
|
+
The rude_q generator creates a fully functioning RudeQ.
|
|
3
|
+
|
|
4
|
+
The generator takes a model name as its argument. The model name may be
|
|
5
|
+
given in CamelCase or under_score and should not be suffixed with 'Model'.
|
|
6
|
+
|
|
7
|
+
The generator creates a model class in app/models, an RSpec spec in
|
|
8
|
+
spec/models, database fixtures in spec/fixtures/plural_name.yml, and a migration
|
|
9
|
+
in db/migrate.
|
|
10
|
+
|
|
11
|
+
All the generated files are fully functioning, and no extra work should be necessary.
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
./script/generate rude_q ProcessQueue
|
|
15
|
+
|
|
16
|
+
This will create a ProcessQueue model:
|
|
17
|
+
Model: app/models/process_queue.rb
|
|
18
|
+
Spec: spec/models/process_queue_spec.rb
|
|
19
|
+
Fixtures: spec/fixtures/process_queues.yml
|
|
20
|
+
Migration: db/migrate/XXX_add_process_queues.rb
|
|
21
|
+
|
|
22
|
+
Run migrations, and you can use it immediately;
|
|
23
|
+
ProcessQueue.set(queue_name, value)
|
|
24
|
+
ProcessQueue.get(queue_name)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class RudeQGenerator < Rails::Generator::NamedBase
|
|
2
|
+
def manifest
|
|
3
|
+
|
|
4
|
+
record do |m|
|
|
5
|
+
# Check for class naming collisions.
|
|
6
|
+
m.class_collisions class_path, class_name
|
|
7
|
+
|
|
8
|
+
# Model, spec, and fixture directories.
|
|
9
|
+
m.directory File.join('app/models', class_path)
|
|
10
|
+
m.directory File.join('spec/fixtures', class_path)
|
|
11
|
+
m.directory File.join('spec/models', class_path)
|
|
12
|
+
|
|
13
|
+
# Model class, spec and fixtures.
|
|
14
|
+
m.template 'rude_q_model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
|
15
|
+
m.template 'model:fixtures.yml', File.join('spec/fixtures', class_path, "#{table_name}.yml")
|
|
16
|
+
m.template 'rude_q_model_spec.rb', File.join('spec/models', class_path, "#{file_name}_spec.rb")
|
|
17
|
+
|
|
18
|
+
unless options[:skip_migration]
|
|
19
|
+
m.migration_template 'rude_q_migration.rb', 'db/migrate', :assigns => {
|
|
20
|
+
:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
|
|
21
|
+
}, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class <%= migration_name %> < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :<%= table_name %> do |t|
|
|
4
|
+
t.string :queue_name
|
|
5
|
+
t.text :data
|
|
6
|
+
t.boolean :processed, :default => false, :null => false
|
|
7
|
+
<% unless options[:skip_timestamps] %>
|
|
8
|
+
t.timestamps
|
|
9
|
+
<% end -%>
|
|
10
|
+
end
|
|
11
|
+
add_index :<%= table_name %>, :processed
|
|
12
|
+
add_index :<%= table_name %>, [:queue_name, :processed]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.down
|
|
16
|
+
drop_table :<%= table_name %>
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe <%= class_name %> do
|
|
4
|
+
before(:each) do
|
|
5
|
+
@<%= file_name %> = <%= class_name %>.new
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "should be valid" do
|
|
9
|
+
@<%= file_name %>.should be_valid
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe "get and set" do
|
|
13
|
+
it "should work with strings" do
|
|
14
|
+
<%= class_name %>.set('abcde', "Something to set")
|
|
15
|
+
<%= class_name %>.get('abcde').should == "Something to set"
|
|
16
|
+
end
|
|
17
|
+
it "should work with symbols" do
|
|
18
|
+
<%= class_name %>.set('abcde', :a_symbol)
|
|
19
|
+
<%= class_name %>.get('abcde').should == :a_symbol
|
|
20
|
+
end
|
|
21
|
+
it "should work with arrays" do
|
|
22
|
+
array = [1, :b, "C"]
|
|
23
|
+
<%= class_name %>.set('abcde', array)
|
|
24
|
+
<%= class_name %>.get('abcde').should == array
|
|
25
|
+
end
|
|
26
|
+
it "should work with hashes" do
|
|
27
|
+
hash = {:symbol => "A string", "stringy" => 23, 74 => :cheese}
|
|
28
|
+
<%= class_name %>.set('abcde', hash)
|
|
29
|
+
<%= class_name %>.get('abcde').should == hash
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should :get in the same order they are :set" do
|
|
33
|
+
<%= class_name %>.set('abcde', :first)
|
|
34
|
+
<%= class_name %>.set('abcde', "second")
|
|
35
|
+
|
|
36
|
+
<%= class_name %>.get('abcde').should == :first
|
|
37
|
+
|
|
38
|
+
<%= class_name %>.set('abcde', 33.3333)
|
|
39
|
+
|
|
40
|
+
<%= class_name %>.get('abcde').should == "second"
|
|
41
|
+
<%= class_name %>.get('abcde').should == 33.3333
|
|
42
|
+
<%= class_name %>.get('abcde').should be(nil)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should keep queues seperated" do
|
|
46
|
+
<%= class_name %>.set('queue_1', :data_1)
|
|
47
|
+
<%= class_name %>.set('queue_2', "DATA2")
|
|
48
|
+
|
|
49
|
+
<%= class_name %>.get('queue_2').should == "DATA2"
|
|
50
|
+
<%= class_name %>.get('queue_2').should be(nil)
|
|
51
|
+
<%= class_name %>.get('queue_1').should == :data_1
|
|
52
|
+
<%= class_name %>.get('queue_1').should be(nil)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should work with queue name as strings or symbols" do
|
|
56
|
+
<%= class_name %>.set(:bah, "something about bah")
|
|
57
|
+
<%= class_name %>.get("bah").should == "something about bah"
|
|
58
|
+
|
|
59
|
+
<%= class_name %>.set("girah", {:craziness => "embodied"})
|
|
60
|
+
<%= class_name %>.get(:girah).should == {:craziness => "embodied"}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should work with queue name as strings or integers" do
|
|
64
|
+
<%= class_name %>.set(23, "something about bah")
|
|
65
|
+
<%= class_name %>.get("23").should == "something about bah"
|
|
66
|
+
|
|
67
|
+
<%= class_name %>.set("34", {:craziness => "embodied"})
|
|
68
|
+
<%= class_name %>.get(34).should == {:craziness => "embodied"}
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
data/lib/rude_q.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# RudeQ
|
|
2
|
-
require 'digest/sha1'
|
|
3
2
|
|
|
4
3
|
# simply doing;
|
|
5
4
|
# class RudeQueue < ActiveRecord::Base
|
|
@@ -12,9 +11,18 @@ module RudeQ
|
|
|
12
11
|
|
|
13
12
|
def self.included(mod) # :nodoc:
|
|
14
13
|
mod.extend(ClassMethods)
|
|
15
|
-
mod.
|
|
14
|
+
mod.send(:include, InstanceMethods)
|
|
16
15
|
end
|
|
17
|
-
|
|
16
|
+
|
|
17
|
+
module InstanceMethods
|
|
18
|
+
def data # :nodoc:
|
|
19
|
+
YAML.load(self[:data])
|
|
20
|
+
end
|
|
21
|
+
def data=(value) # :nodoc:
|
|
22
|
+
self[:data] = YAML.dump(value)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
18
26
|
module ClassMethods
|
|
19
27
|
# Cleanup old processed items
|
|
20
28
|
#
|
|
@@ -25,7 +33,6 @@ module RudeQ
|
|
|
25
33
|
end
|
|
26
34
|
|
|
27
35
|
# Add any serialize-able +data+ to the queue +queue_name+ (strings and symbols are treated the same)
|
|
28
|
-
#
|
|
29
36
|
# RudeQueue.set(:sausage_queue, Sausage.new(:sauce => "yummy"))
|
|
30
37
|
# RudeQueue.set("sausage_queue", Sausage.new(:other => true))
|
|
31
38
|
#
|
|
@@ -37,6 +44,7 @@ module RudeQ
|
|
|
37
44
|
# -> nil
|
|
38
45
|
def set(queue_name, data)
|
|
39
46
|
queue_name = sanitize_queue_name(queue_name)
|
|
47
|
+
|
|
40
48
|
self.create!(:queue_name => queue_name, :data => data)
|
|
41
49
|
return nil # in line with Starling
|
|
42
50
|
end
|
|
@@ -86,9 +94,20 @@ module RudeQ
|
|
|
86
94
|
end
|
|
87
95
|
|
|
88
96
|
# A snapshot count of unprocessed items for the given +queue_name+
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
97
|
+
#
|
|
98
|
+
# >> RudeQueue.backlog
|
|
99
|
+
# -> 265
|
|
100
|
+
# >> RudeQueue.backlog(:one_queue)
|
|
101
|
+
# -> 212
|
|
102
|
+
# >> RudeQueue.backlog(:another_queue)
|
|
103
|
+
# -> 53
|
|
104
|
+
#
|
|
105
|
+
def backlog(queue_name=nil)
|
|
106
|
+
conditions = {:processed => false}
|
|
107
|
+
if queue_name
|
|
108
|
+
conditions[:queue_name] = sanitize_queue_name(queue_name)
|
|
109
|
+
end
|
|
110
|
+
self.count(:conditions => conditions)
|
|
92
111
|
end
|
|
93
112
|
|
|
94
113
|
def fetch_with_lock(qname, &block) # :nodoc:
|
|
@@ -126,6 +145,12 @@ module RudeQ
|
|
|
126
145
|
@queue_options ||= {:processed => :set_flag, :lock => :pessimistic}
|
|
127
146
|
end
|
|
128
147
|
|
|
148
|
+
def data # :nodoc:
|
|
149
|
+
YAML.load(self[:data])
|
|
150
|
+
end
|
|
151
|
+
def data=(value) # :nodoc:
|
|
152
|
+
self[:data] = YAML.dump(value)
|
|
153
|
+
end
|
|
129
154
|
private
|
|
130
155
|
|
|
131
156
|
def sanitize_queue_name(queue_name) # :nodoc:
|
|
@@ -161,9 +186,12 @@ module RudeQ
|
|
|
161
186
|
# which misses the point
|
|
162
187
|
#
|
|
163
188
|
# also, it doesn't work on SQLite as it requires "UPDATE ... LIMIT 1 ORDER id ASC"
|
|
189
|
+
# and as of RudeQueue2, you'll need to manually add the "token" column
|
|
164
190
|
module TokenLock
|
|
165
191
|
class << self
|
|
166
192
|
|
|
193
|
+
require 'digest/sha1'
|
|
194
|
+
|
|
167
195
|
def fetch_with_lock(klass, qname) # :nodoc:
|
|
168
196
|
token = get_unique_token
|
|
169
197
|
klass.update_all(["token = ?", token], ["queue_name = ? AND processed = ? AND token IS NULL", qname, false], :limit => 1, :order => "id ASC")
|
|
@@ -188,5 +216,5 @@ module RudeQ
|
|
|
188
216
|
end
|
|
189
217
|
end
|
|
190
218
|
end
|
|
191
|
-
|
|
192
219
|
end
|
|
220
|
+
|
data/lib/rude_q/scope.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + "/../rude_q"
|
|
2
|
+
|
|
3
|
+
module RudeQ
|
|
4
|
+
class Scope
|
|
5
|
+
|
|
6
|
+
def initialize(queue_name)
|
|
7
|
+
@queue_name = queue_name
|
|
8
|
+
end
|
|
9
|
+
attr_reader :queue_name
|
|
10
|
+
|
|
11
|
+
def set(data)
|
|
12
|
+
RudeQueue.set(self.queue_name, data)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get()
|
|
16
|
+
RudeQueue.get(self.queue_name)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def backlog()
|
|
20
|
+
RudeQueue.backlog(self.queue_name)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# example worker class: lib/my_worker.rb
|
|
2
|
+
# class MyWorker < RudeQ::Worker
|
|
3
|
+
# def queue_name
|
|
4
|
+
# :my_queue
|
|
5
|
+
# end
|
|
6
|
+
#
|
|
7
|
+
# def do_work(data)
|
|
8
|
+
# MyMailer.send(data)
|
|
9
|
+
# end
|
|
10
|
+
# end
|
|
11
|
+
#
|
|
12
|
+
# example rake file: lib/tasks/worker.rake
|
|
13
|
+
# namespace :worker do
|
|
14
|
+
# desc "fire off a worker"
|
|
15
|
+
# task :do => :environment do
|
|
16
|
+
# worker = MyWorker.new
|
|
17
|
+
# worker.do!
|
|
18
|
+
# end
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# then add a cron job to run "cd /path/to/wherever && rake worker:do RAILS_ENV=production"
|
|
22
|
+
module RudeQ
|
|
23
|
+
class Worker
|
|
24
|
+
|
|
25
|
+
def queue_name
|
|
26
|
+
raise NotImplementedError
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def do_work(data)
|
|
30
|
+
raise NotImplementedError
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def do!
|
|
34
|
+
logger.info("starting up")
|
|
35
|
+
if work = self.queue.get
|
|
36
|
+
logger.info("found some work")
|
|
37
|
+
do_work(work)
|
|
38
|
+
else
|
|
39
|
+
logger.info("couldn't find any work")
|
|
40
|
+
end
|
|
41
|
+
logger.info("finished for now")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def logger
|
|
45
|
+
unless @logger
|
|
46
|
+
@logger = Logger.new(RAILS_ROOT + "/log/#{self.class.to_s.underscore}_#{RAILS_ENV}.log")
|
|
47
|
+
class << @logger
|
|
48
|
+
def format_message(severity, timestamp, progname, msg)
|
|
49
|
+
"#{timestamp.strftime('%Y%m%d-%H:%M:%S')} (#{$$}) #{msg}\n"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
return @logger
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
class << self
|
|
57
|
+
def queue
|
|
58
|
+
RudeQ::Scope.new(self.new.queue_name)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def queue
|
|
63
|
+
@queue ||= self.class.queue
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/spec/rude_q_spec.rb
CHANGED
|
@@ -1,111 +1,117 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
2
|
|
|
3
|
-
describe RudeQ::ClassMethods do #
|
|
3
|
+
describe RudeQ::ClassMethods do # RudeQueue extends ClassMethods
|
|
4
4
|
before(:each) do
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
RudeQueue.delete_all
|
|
6
|
+
RudeQueue.raise_on_processed = false
|
|
7
7
|
create_some_noise
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def create_some_noise
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
RudeQueue.create!(:queue_name => "doNT use this in Specs", :data => {:not => "to be messed with"})
|
|
12
|
+
RudeQueue.create!(:queue_name => "abcde", :data => {:same_as => "the specs but already processed"}, :processed => true)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
describe "get and set" do
|
|
16
16
|
it "should work with strings" do
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
RudeQueue.set('abcde', "Something to set")
|
|
18
|
+
RudeQueue.get('abcde').should == "Something to set"
|
|
19
19
|
end
|
|
20
20
|
it "should work with symbols" do
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
RudeQueue.set('abcde', :a_symbol)
|
|
22
|
+
RudeQueue.get('abcde').should == :a_symbol
|
|
23
23
|
end
|
|
24
24
|
it "should work with arrays" do
|
|
25
25
|
array = [1, :b, "C"]
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
RudeQueue.set('abcde', array)
|
|
27
|
+
RudeQueue.get('abcde').should == array
|
|
28
28
|
end
|
|
29
29
|
it "should work with hashes" do
|
|
30
30
|
hash = {:symbol => "A string", "stringy" => 23, 74 => :cheese}
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
RudeQueue.set('abcde', hash)
|
|
32
|
+
RudeQueue.get('abcde').should == hash
|
|
33
33
|
end
|
|
34
34
|
it "should work with integers" do
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
RudeQueue.set('abcde', 7816327370)
|
|
36
|
+
RudeQueue.get('abcde').should == 7816327370
|
|
37
37
|
end
|
|
38
|
-
it "
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
it "should work with ActiveRecords" do
|
|
39
|
+
record = Something.create!(:name => "MatthewRudy")
|
|
40
|
+
|
|
41
|
+
RudeQueue.set('abcde', record)
|
|
42
|
+
RudeQueue.get('abcde').should == record
|
|
43
|
+
end
|
|
44
|
+
it "should resolve booleans correctly" do
|
|
45
|
+
RudeQueue.set('abcde', true)
|
|
46
|
+
RudeQueue.get('abcde').should == true
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
|
|
48
|
+
RudeQueue.set('abcde', false)
|
|
49
|
+
RudeQueue.get('abcde').should == false
|
|
44
50
|
end
|
|
45
51
|
|
|
46
52
|
it "should :get in the same order they are :set" do
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
RudeQueue.set('abcde', :first)
|
|
54
|
+
RudeQueue.set('abcde', "second")
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
RudeQueue.get('abcde').should == :first
|
|
51
57
|
|
|
52
|
-
|
|
58
|
+
RudeQueue.set('abcde', 33.3333)
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
RudeQueue.get('abcde').should == "second"
|
|
61
|
+
RudeQueue.get('abcde').should == 33.3333
|
|
62
|
+
RudeQueue.get('abcde').should be(nil)
|
|
57
63
|
end
|
|
58
64
|
|
|
59
65
|
it "should keep queues seperated" do
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
RudeQueue.set('queue_1', :data_1)
|
|
67
|
+
RudeQueue.set('queue_2', "DATA2")
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
RudeQueue.get('queue_2').should == "DATA2"
|
|
70
|
+
RudeQueue.get('queue_2').should be(nil)
|
|
71
|
+
RudeQueue.get('queue_1').should == :data_1
|
|
72
|
+
RudeQueue.get('queue_1').should be(nil)
|
|
67
73
|
end
|
|
68
74
|
|
|
69
75
|
it "should call to_s on inputs" do
|
|
70
76
|
qname = stub("fake input")
|
|
71
77
|
qname.should_receive(:to_s).exactly(:twice).and_return("fake queue name")
|
|
72
78
|
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
RudeQueue.set(qname, ["Data"])
|
|
80
|
+
RudeQueue.get(qname).should == ["Data"]
|
|
75
81
|
end
|
|
76
82
|
|
|
77
83
|
it "should work with queue name as strings or symbols" do
|
|
78
|
-
|
|
79
|
-
|
|
84
|
+
RudeQueue.set(:bah, "something about bah")
|
|
85
|
+
RudeQueue.get("bah").should == "something about bah"
|
|
80
86
|
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
RudeQueue.set("girah", {:craziness => "embodied"})
|
|
88
|
+
RudeQueue.get(:girah).should == {:craziness => "embodied"}
|
|
83
89
|
end
|
|
84
90
|
end
|
|
85
91
|
|
|
86
92
|
describe ".set" do
|
|
87
93
|
it "should delegate to :create!" do
|
|
88
|
-
|
|
89
|
-
|
|
94
|
+
RudeQueue.should_receive(:create!).with(:queue_name => 'abcde', :data => :magical_planet)
|
|
95
|
+
RudeQueue.set('abcde', :magical_planet)
|
|
90
96
|
end
|
|
91
97
|
it "should return nil" do
|
|
92
|
-
|
|
98
|
+
RudeQueue.set('abcde', "something").should be(nil)
|
|
93
99
|
end
|
|
94
100
|
end
|
|
95
101
|
|
|
96
102
|
describe ".get" do
|
|
97
103
|
it "should revert a record if something goes wrong before it finishes" do
|
|
98
|
-
|
|
99
|
-
|
|
104
|
+
RudeQueue.raise_on_processed = true
|
|
105
|
+
RudeQueue.set('abcde', :this_will_remain_unprocessed)
|
|
100
106
|
|
|
101
107
|
# confirm the object is in the db
|
|
102
|
-
record =
|
|
108
|
+
record = RudeQueue.find(:first, :order => "id DESC")
|
|
103
109
|
record.queue_name.should == 'abcde'
|
|
104
110
|
record.data.should == :this_will_remain_unprocessed
|
|
105
111
|
record.processed?.should == false
|
|
106
112
|
record.token.should == nil
|
|
107
113
|
|
|
108
|
-
lambda {
|
|
114
|
+
lambda {RudeQueue.get('abcde')}.should raise_error(RuntimeError)
|
|
109
115
|
|
|
110
116
|
record.reload
|
|
111
117
|
record.queue_name.should == 'abcde'
|
|
@@ -119,11 +125,11 @@ describe RudeQ::ClassMethods do # ProcessQueue extends ClassMethods
|
|
|
119
125
|
describe "with data" do
|
|
120
126
|
|
|
121
127
|
before(:each) do
|
|
122
|
-
|
|
128
|
+
RudeQueue.set(:fetch_queue, "some data")
|
|
123
129
|
end
|
|
124
130
|
|
|
125
131
|
it "should return the value of the block" do
|
|
126
|
-
rtn =
|
|
132
|
+
rtn = RudeQueue.fetch(:fetch_queue) do |data|
|
|
127
133
|
data.should == "some data"
|
|
128
134
|
:the_return
|
|
129
135
|
end
|
|
@@ -132,7 +138,7 @@ describe RudeQ::ClassMethods do # ProcessQueue extends ClassMethods
|
|
|
132
138
|
|
|
133
139
|
it "should execute the block with the data" do
|
|
134
140
|
self.should_receive(:something)
|
|
135
|
-
|
|
141
|
+
RudeQueue.fetch(:fetch_queue) do |data|
|
|
136
142
|
self.something
|
|
137
143
|
data.should == "some data"
|
|
138
144
|
end
|
|
@@ -144,13 +150,13 @@ describe RudeQ::ClassMethods do # ProcessQueue extends ClassMethods
|
|
|
144
150
|
|
|
145
151
|
it "should not execute the block" do
|
|
146
152
|
self.should_not_receive(:something)
|
|
147
|
-
|
|
153
|
+
RudeQueue.fetch(:fetch_queue) do |data|
|
|
148
154
|
raise(Exception, "this should never get here")
|
|
149
155
|
end
|
|
150
156
|
end
|
|
151
157
|
|
|
152
158
|
it "should return nil" do
|
|
153
|
-
rtn =
|
|
159
|
+
rtn = RudeQueue.fetch(:fetch_queue) do |data|
|
|
154
160
|
raise(Exception, "again this shouldnt happen")
|
|
155
161
|
end
|
|
156
162
|
rtn.should be_nil
|
|
@@ -163,33 +169,33 @@ describe RudeQ::ClassMethods do # ProcessQueue extends ClassMethods
|
|
|
163
169
|
describe :processed do
|
|
164
170
|
describe "set to :destroy" do
|
|
165
171
|
before(:each) do
|
|
166
|
-
@old_processed =
|
|
167
|
-
|
|
172
|
+
@old_processed = RudeQueue.queue_options[:processed]
|
|
173
|
+
RudeQueue.queue_options[:processed] = :destroy
|
|
168
174
|
end
|
|
169
175
|
after(:each) do
|
|
170
|
-
|
|
176
|
+
RudeQueue.queue_options[:processed] = @old_processed
|
|
171
177
|
end
|
|
172
178
|
it "should delete processed items" do
|
|
173
|
-
count =
|
|
179
|
+
count = RudeQueue.count
|
|
174
180
|
|
|
175
|
-
|
|
176
|
-
|
|
181
|
+
RudeQueue.set(:abcde, "some value")
|
|
182
|
+
RudeQueue.count.should == (count + 1)
|
|
177
183
|
|
|
178
|
-
|
|
179
|
-
|
|
184
|
+
RudeQueue.get(:abcde).should == "some value"
|
|
185
|
+
RudeQueue.count.should == count
|
|
180
186
|
end
|
|
181
187
|
end
|
|
182
188
|
describe "set to something crazy" do
|
|
183
189
|
before(:each) do
|
|
184
|
-
@old_processed =
|
|
185
|
-
|
|
190
|
+
@old_processed = RudeQueue.queue_options[:processed]
|
|
191
|
+
RudeQueue.queue_options[:processed] = :something_crazy
|
|
186
192
|
end
|
|
187
193
|
after(:each) do
|
|
188
|
-
|
|
194
|
+
RudeQueue.queue_options[:processed] = @old_processed
|
|
189
195
|
end
|
|
190
196
|
it "should raise an exception" do
|
|
191
|
-
|
|
192
|
-
lambda {
|
|
197
|
+
RudeQueue.set(:abcde, "some value")
|
|
198
|
+
lambda {RudeQueue.get(:abcde)}.should raise_error(ArgumentError)
|
|
193
199
|
end
|
|
194
200
|
end
|
|
195
201
|
end
|
|
@@ -197,66 +203,72 @@ describe RudeQ::ClassMethods do # ProcessQueue extends ClassMethods
|
|
|
197
203
|
|
|
198
204
|
describe ".backlog" do
|
|
199
205
|
it "should count the unprocessed items for the provided queue_name" do
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
206
|
+
RudeQueue.delete_all
|
|
207
|
+
|
|
208
|
+
RudeQueue.backlog(:abcde).should == 0
|
|
209
|
+
RudeQueue.backlog().should == 0
|
|
210
|
+
|
|
211
|
+
RudeQueue.set(:abcde, "a value")
|
|
212
|
+
RudeQueue.backlog(:abcde).should == 1
|
|
213
|
+
RudeQueue.backlog().should == 1
|
|
214
|
+
|
|
215
|
+
RudeQueue.set(:something_else, "another value")
|
|
216
|
+
3.times { RudeQueue.set(:abcde, :add_three_more)}
|
|
209
217
|
|
|
210
|
-
|
|
211
|
-
|
|
218
|
+
RudeQueue.backlog(:abcde).should == 4
|
|
219
|
+
RudeQueue.backlog().should == 5
|
|
220
|
+
|
|
221
|
+
RudeQueue.get(:abcde).should == "a value"
|
|
222
|
+
RudeQueue.backlog(:abcde).should == 3
|
|
223
|
+
RudeQueue.backlog().should == 4
|
|
212
224
|
end
|
|
213
225
|
end
|
|
214
226
|
|
|
215
227
|
describe ".cleanup!" do
|
|
216
228
|
it "should use :delete_all" do
|
|
217
|
-
|
|
218
|
-
|
|
229
|
+
RudeQueue.should_receive(:delete_all) # not :destroy_all
|
|
230
|
+
RudeQueue.cleanup!
|
|
219
231
|
end
|
|
220
232
|
|
|
221
233
|
it "should allow string inputs" do
|
|
222
|
-
|
|
234
|
+
RudeQueue.cleanup!("3600")
|
|
223
235
|
end
|
|
224
236
|
|
|
225
237
|
it "should allow integer inputs" do
|
|
226
|
-
|
|
238
|
+
RudeQueue.cleanup!(3600)
|
|
227
239
|
end
|
|
228
240
|
|
|
229
241
|
it "should not clear unprocessed items" do
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
242
|
+
RudeQueue.set('abcde', :giraffe)
|
|
243
|
+
RudeQueue.set('abcde', :monkey)
|
|
244
|
+
RudeQueue.count.should >= 2
|
|
233
245
|
|
|
234
|
-
|
|
246
|
+
RudeQueue.cleanup!
|
|
235
247
|
|
|
236
|
-
|
|
237
|
-
|
|
248
|
+
RudeQueue.count.should >=2
|
|
249
|
+
RudeQueue.get('abcde').should == :giraffe
|
|
238
250
|
end
|
|
239
251
|
|
|
240
252
|
it "should not clear old unprocessed items" do
|
|
241
|
-
|
|
242
|
-
giraffe =
|
|
253
|
+
RudeQueue.set('abcde', :giraffe)
|
|
254
|
+
giraffe = RudeQueue.find(:first, :conditions => {:data => :giraffe})
|
|
243
255
|
|
|
244
256
|
time_now = Time.now
|
|
245
257
|
Time.stub!(:now).and_return(time_now + 1.year)
|
|
246
258
|
|
|
247
259
|
giraffe.updated_at.should < 2.weeks.ago
|
|
248
260
|
|
|
249
|
-
|
|
261
|
+
RudeQueue.cleanup!
|
|
250
262
|
|
|
251
263
|
giraffe.reload
|
|
252
|
-
|
|
264
|
+
RudeQueue.get('abcde').should == :giraffe
|
|
253
265
|
end
|
|
254
266
|
|
|
255
267
|
it "should not clear processed items newer than the argument" do
|
|
256
|
-
|
|
257
|
-
|
|
268
|
+
RudeQueue.set('abcde', :giraffe)
|
|
269
|
+
RudeQueue.get('abcde').should == :giraffe
|
|
258
270
|
|
|
259
|
-
giraffe =
|
|
271
|
+
giraffe = RudeQueue.find(:first, :conditions => {:data => :giraffe})
|
|
260
272
|
|
|
261
273
|
time_now = Time.now
|
|
262
274
|
Time.stub!(:now).and_return(time_now + 1.week - 5.minutes)
|
|
@@ -264,16 +276,16 @@ describe RudeQ::ClassMethods do # ProcessQueue extends ClassMethods
|
|
|
264
276
|
giraffe.updated_at.should > 1.week.ago
|
|
265
277
|
giraffe.processed.should be(true)
|
|
266
278
|
|
|
267
|
-
|
|
279
|
+
RudeQueue.cleanup!(1.week)
|
|
268
280
|
|
|
269
281
|
giraffe.reload
|
|
270
282
|
end
|
|
271
283
|
|
|
272
284
|
it "should not clear processed items newer than one hour, by default" do
|
|
273
|
-
|
|
274
|
-
|
|
285
|
+
RudeQueue.set('abcde', :giraffe)
|
|
286
|
+
RudeQueue.get('abcde').should == :giraffe
|
|
275
287
|
|
|
276
|
-
giraffe =
|
|
288
|
+
giraffe = RudeQueue.find(:first, :conditions => {:data => :giraffe})
|
|
277
289
|
|
|
278
290
|
time_now = Time.now
|
|
279
291
|
Time.stub!(:now).and_return(time_now + 59.minutes)
|
|
@@ -281,16 +293,16 @@ describe RudeQ::ClassMethods do # ProcessQueue extends ClassMethods
|
|
|
281
293
|
giraffe.updated_at.should > 1.hour.ago
|
|
282
294
|
giraffe.processed.should be(true)
|
|
283
295
|
|
|
284
|
-
|
|
296
|
+
RudeQueue.cleanup!()
|
|
285
297
|
|
|
286
298
|
giraffe.reload
|
|
287
299
|
end
|
|
288
300
|
|
|
289
301
|
it "should clear processed items older than the argument" do
|
|
290
|
-
|
|
291
|
-
|
|
302
|
+
RudeQueue.set('abcde', :giraffe)
|
|
303
|
+
RudeQueue.get('abcde').should == :giraffe
|
|
292
304
|
|
|
293
|
-
giraffe =
|
|
305
|
+
giraffe = RudeQueue.find(:first, :conditions => {:data => :giraffe})
|
|
294
306
|
|
|
295
307
|
time_now = Time.now
|
|
296
308
|
Time.stub!(:now).and_return(time_now + 1.week + 5.minutes)
|
|
@@ -298,16 +310,16 @@ describe RudeQ::ClassMethods do # ProcessQueue extends ClassMethods
|
|
|
298
310
|
giraffe.updated_at.should < 1.week.ago
|
|
299
311
|
giraffe.processed.should be(true)
|
|
300
312
|
|
|
301
|
-
|
|
313
|
+
RudeQueue.cleanup!(1.week)
|
|
302
314
|
|
|
303
315
|
lambda { giraffe.reload }.should raise_error(ActiveRecord::RecordNotFound)
|
|
304
316
|
end
|
|
305
317
|
|
|
306
318
|
it "should clear processed items older than one hour, by default" do
|
|
307
|
-
|
|
308
|
-
|
|
319
|
+
RudeQueue.set('abcde', :giraffe)
|
|
320
|
+
RudeQueue.get('abcde').should == :giraffe
|
|
309
321
|
|
|
310
|
-
giraffe =
|
|
322
|
+
giraffe = RudeQueue.find(:first, :conditions => {:data => :giraffe})
|
|
311
323
|
|
|
312
324
|
time_now = Time.now()
|
|
313
325
|
Time.stub!(:now).and_return(time_now + 61.minutes)
|
|
@@ -315,7 +327,7 @@ describe RudeQ::ClassMethods do # ProcessQueue extends ClassMethods
|
|
|
315
327
|
giraffe.updated_at.should < 1.hour.ago
|
|
316
328
|
giraffe.processed.should be(true)
|
|
317
329
|
|
|
318
|
-
|
|
330
|
+
RudeQueue.cleanup!
|
|
319
331
|
|
|
320
332
|
lambda { giraffe.reload }.should raise_error(ActiveRecord::RecordNotFound)
|
|
321
333
|
end
|
|
@@ -348,13 +360,13 @@ describe RudeQ::TokenLock do
|
|
|
348
360
|
# RudeQ::TokenLock.should respond_to(:get_unique_token) # ensure our stub is safe
|
|
349
361
|
# RudeQ::TokenLock.should_receive(:get_unique_token).exactly(3).times.and_return(@token)
|
|
350
362
|
#
|
|
351
|
-
# @existing =
|
|
363
|
+
# @existing = RudeQueue.create!(:queue_name => 'abcde', :data => :old_data, :token => @token, :processed => true)
|
|
352
364
|
#
|
|
353
|
-
#
|
|
365
|
+
# RudeQueue.get('abcde').should be(nil)
|
|
354
366
|
#
|
|
355
|
-
#
|
|
356
|
-
#
|
|
357
|
-
#
|
|
367
|
+
# RudeQueue.set('abcde', :new_data)
|
|
368
|
+
# RudeQueue.get('abcde').should == :new_data
|
|
369
|
+
# RudeQueue.get('abcde').should be(nil)
|
|
358
370
|
# end
|
|
359
371
|
|
|
360
372
|
end
|
data/spec/schema.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
ActiveRecord::Schema.define(:version => 1) do
|
|
2
|
-
create_table :
|
|
2
|
+
create_table :rude_queues, :force => true do |t|
|
|
3
3
|
t.string :queue_name
|
|
4
4
|
t.text :data
|
|
5
5
|
t.string :token, :default => nil
|
|
@@ -7,6 +7,13 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
|
7
7
|
|
|
8
8
|
t.timestamps
|
|
9
9
|
end
|
|
10
|
-
add_index :
|
|
11
|
-
add_index :
|
|
12
|
-
|
|
10
|
+
add_index :rude_queues, :processed
|
|
11
|
+
add_index :rude_queues, [:queue_name, :processed]
|
|
12
|
+
|
|
13
|
+
create_table :somethings, :force => true do |t|
|
|
14
|
+
t.string :name
|
|
15
|
+
t.integer :count
|
|
16
|
+
|
|
17
|
+
t.timestamps
|
|
18
|
+
end
|
|
19
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -4,9 +4,11 @@ require 'active_record'
|
|
|
4
4
|
|
|
5
5
|
current_dir = File.dirname(__FILE__)
|
|
6
6
|
require "#{current_dir}/../lib/rude_q"
|
|
7
|
-
require "#{current_dir}/
|
|
8
|
-
|
|
7
|
+
require "#{current_dir}/../lib/rude_q/worker"
|
|
8
|
+
require "#{current_dir}/../lib/rude_q/scope"
|
|
9
|
+
require "#{current_dir}/models/rude_queue"
|
|
10
|
+
require "#{current_dir}/models/something"
|
|
9
11
|
config = YAML::load(IO.read(current_dir + '/database.yml'))
|
|
10
12
|
ActiveRecord::Base.logger = Logger.new(current_dir + "/debug.log")
|
|
11
13
|
ActiveRecord::Base.establish_connection(config['rude_q_test'])
|
|
12
|
-
load(current_dir + "/schema.rb")
|
|
14
|
+
load(current_dir + "/schema.rb")
|
data/spec/worker_spec.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
class ExampleWorker < RudeQ::Worker
|
|
4
|
+
def queue_name
|
|
5
|
+
:some_queue
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# for the test, we'll just append each bit of data to a variable
|
|
9
|
+
attr_accessor :processed_data
|
|
10
|
+
|
|
11
|
+
def do_work(data)
|
|
12
|
+
self.processed_data ||= []
|
|
13
|
+
self.processed_data << data
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe RudeQ::Worker do
|
|
18
|
+
before(:each) do
|
|
19
|
+
@it = ExampleWorker.new
|
|
20
|
+
RudeQueue.delete_all
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "queue" do
|
|
24
|
+
it "should expose RudeQueue.get scoped for the worker's queue" do
|
|
25
|
+
RudeQueue.set(:some_queue, ["some data for the worker"])
|
|
26
|
+
@it.queue.get.should == ["some data for the worker"]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should expose RudeQueue.set scoped for the worker's queue" do
|
|
30
|
+
@it.queue.set(:some_other_data_for_the_worker)
|
|
31
|
+
RudeQueue.get(:some_queue).should == :some_other_data_for_the_worker
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should expose RudeQueue.backlog scoped for the worker's queue" do
|
|
35
|
+
RudeQueue.set(:who_knows, 1)
|
|
36
|
+
RudeQueue.set(:my_mum, 23)
|
|
37
|
+
|
|
38
|
+
RudeQueue.backlog.should == 2
|
|
39
|
+
RudeQueue.backlog(:some_queue).should == 0
|
|
40
|
+
@it.queue.backlog.should == 0
|
|
41
|
+
|
|
42
|
+
RudeQueue.set(:some_queue, "purple")
|
|
43
|
+
|
|
44
|
+
RudeQueue.backlog.should == 3
|
|
45
|
+
RudeQueue.backlog(:some_queue).should == 1
|
|
46
|
+
@it.queue.backlog.should == 1
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
namespace :queue do
|
|
2
|
+
desc "Generates your RudeQueue model"
|
|
3
|
+
task :setup => :environment do
|
|
4
|
+
require 'rails_generator'
|
|
5
|
+
require 'rails_generator/scripts/generate'
|
|
6
|
+
Rails::Generator::Scripts::Generate.new.run(["rude_q", ENV["QUEUE"] || "RudeQueue"])
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
desc "Removes all the old queue items"
|
|
10
|
+
task :cleanup => :environment do
|
|
11
|
+
queue_model = (ENV["QUEUE"] || "RudeQueue").constantize
|
|
12
|
+
args = [ENV["CLEANUP_TIME"]].compact
|
|
13
|
+
queue_model.cleanup!(*args) # no arg if no CLEANUP_TIME specified
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
#namespace :spec do
|
|
18
|
+
# namespace :plugins do
|
|
19
|
+
# desc "Runs the examples for RudeQ"
|
|
20
|
+
# Spec::Rake::SpecTask.new(:rude_q) do |t|
|
|
21
|
+
# t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
|
|
22
|
+
# t.spec_files = FileList['vendor/plugins/rude_q/spec/**/*_spec.rb']
|
|
23
|
+
# end
|
|
24
|
+
# end
|
|
25
|
+
#end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: matthewrudy-rudeq
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matthew Rudy Jacobs
|
|
@@ -9,11 +9,12 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-
|
|
12
|
+
date: 2009-06-09 00:00:00 -07:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: activerecord
|
|
17
|
+
type: :runtime
|
|
17
18
|
version_requirement:
|
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
|
19
20
|
requirements:
|
|
@@ -32,13 +33,24 @@ extra_rdoc_files:
|
|
|
32
33
|
files:
|
|
33
34
|
- README
|
|
34
35
|
- Rakefile
|
|
36
|
+
- MIT-LICENSE
|
|
37
|
+
- lib/rude_q/worker.rb
|
|
38
|
+
- lib/rude_q/scope.rb
|
|
35
39
|
- lib/rude_q.rb
|
|
40
|
+
- generators/rude_q/templates/rude_q_model.rb
|
|
41
|
+
- generators/rude_q/templates/rude_q_model_spec.rb
|
|
42
|
+
- generators/rude_q/templates/rude_q_migration.rb
|
|
43
|
+
- generators/rude_q/rude_q_generator.rb
|
|
44
|
+
- generators/rude_q/USAGE
|
|
45
|
+
- spec/spec.opts
|
|
46
|
+
- spec/worker_spec.rb
|
|
47
|
+
- spec/spec_helper.rb
|
|
36
48
|
- spec/database.yml
|
|
37
|
-
- spec/process_queue.rb
|
|
38
49
|
- spec/rude_q_spec.rb
|
|
50
|
+
- spec/models/rude_queue.rb
|
|
51
|
+
- spec/models/something.rb
|
|
39
52
|
- spec/schema.rb
|
|
40
|
-
-
|
|
41
|
-
- spec/spec_helper.rb
|
|
53
|
+
- tasks/rude_q_tasks.rake
|
|
42
54
|
has_rdoc: true
|
|
43
55
|
homepage: http://github.com/matthewrudy/rudeq
|
|
44
56
|
post_install_message:
|
|
@@ -68,3 +80,4 @@ specification_version: 2
|
|
|
68
80
|
summary: ActiveRecord-based DB-queue
|
|
69
81
|
test_files:
|
|
70
82
|
- spec/rude_q_spec.rb
|
|
83
|
+
- spec/worker_spec.rb
|