matthewrudy-rudeq 0.1
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/README +62 -0
- data/Rakefile +22 -0
- data/lib/rude_q.rb +84 -0
- data/spec/database.yml +4 -0
- data/spec/process_queue.rb +3 -0
- data/spec/rude_q_spec.rb +225 -0
- data/spec/schema.rb +12 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +12 -0
- metadata +70 -0
data/README
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
== Author
|
|
2
|
+
Matthew Rudy Jacobs
|
|
3
|
+
|
|
4
|
+
== Contact
|
|
5
|
+
MatthewRudyJacobs@gmail.com
|
|
6
|
+
|
|
7
|
+
RudeQ
|
|
8
|
+
=============
|
|
9
|
+
A simple DB based queue,
|
|
10
|
+
designed for situations where a server based queue is unnecessary.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
INSTALL
|
|
14
|
+
============
|
|
15
|
+
This plugin requires Rails 2.* currently, and has only been tested on MySQL.
|
|
16
|
+
It definitely does not work on SQLite (as it requires :limit and :order options for a SQL UPDATE command)
|
|
17
|
+
|
|
18
|
+
On rails 2.1 you can install straight from github:
|
|
19
|
+
ruby script/plugin install git://github.com/matthewrudy/rudeq.git
|
|
20
|
+
|
|
21
|
+
Else just check it out into your plugins directory:
|
|
22
|
+
git clone git://github.com/matthewrudy/rudeq.git vendor/plugins/rudeq
|
|
23
|
+
|
|
24
|
+
USAGE
|
|
25
|
+
============
|
|
26
|
+
After you've installed it just run
|
|
27
|
+
rake queue:setup
|
|
28
|
+
|
|
29
|
+
matthew@iRudy:~/code/jbequeueing $ rake queue:setup
|
|
30
|
+
(in /Users/matthew/code/jbequeueing)
|
|
31
|
+
exists app/models/
|
|
32
|
+
exists spec/fixtures/
|
|
33
|
+
exists spec/models/
|
|
34
|
+
create app/models/rude_queue.rb
|
|
35
|
+
create spec/fixtures/rude_queues.yml
|
|
36
|
+
create spec/models/rude_queue_spec.rb
|
|
37
|
+
exists db/migrate
|
|
38
|
+
create db/migrate/029_create_rude_queues.rb
|
|
39
|
+
|
|
40
|
+
and you're done.
|
|
41
|
+
Fully tested, fully index... BOOM!
|
|
42
|
+
|
|
43
|
+
Now run migrations, start up a console, and;
|
|
44
|
+
|
|
45
|
+
RudeQueue.set(:queue_name, RandomObject)
|
|
46
|
+
RudeQueue.get(:queue_name)
|
|
47
|
+
|
|
48
|
+
And, to keep the queue running fast,
|
|
49
|
+
set up a cron job to run
|
|
50
|
+
|
|
51
|
+
rake queue:cleanup
|
|
52
|
+
|
|
53
|
+
the cleanup will remove any queued items which have been processed longer than an hour ago.
|
|
54
|
+
|
|
55
|
+
rake queue:cleanup CLEANUP_TIME=86,400
|
|
56
|
+
|
|
57
|
+
will clear processed queue items processed longer than 86,400 seconds ago (1 day)
|
|
58
|
+
|
|
59
|
+
Try Yourself!
|
|
60
|
+
|
|
61
|
+
Copyright (c) 2008 [Matthew Rudy Jacobs Email: MatthewRudyJacobs@gmail.com],
|
|
62
|
+
released under the MIT license
|
data/Rakefile
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'spec'
|
|
3
|
+
require 'spec/rake/spectask'
|
|
4
|
+
require 'rake/rdoctask'
|
|
5
|
+
|
|
6
|
+
desc 'Default: run the specs.'
|
|
7
|
+
task :default => :spec
|
|
8
|
+
|
|
9
|
+
desc 'Run specs for rude_q plugin'
|
|
10
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
|
11
|
+
t.spec_opts = ['--options', "\"spec/spec.opts\""]
|
|
12
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc 'Generate documentation for the rude_q plugin.'
|
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
18
|
+
rdoc.title = 'RudeQ'
|
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
|
20
|
+
rdoc.rdoc_files.include('README')
|
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
22
|
+
end
|
data/lib/rude_q.rb
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# RudeQ
|
|
2
|
+
require 'digest/sha1'
|
|
3
|
+
module RudeQ
|
|
4
|
+
|
|
5
|
+
def self.included(mod)
|
|
6
|
+
mod.extend(ClassMethods)
|
|
7
|
+
mod.serialize(:data)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module ClassMethods
|
|
11
|
+
# Cleanup old processed items
|
|
12
|
+
#
|
|
13
|
+
# RudeQueue.cleanup!
|
|
14
|
+
# RudeQueue.cleanup!(1.week)
|
|
15
|
+
def cleanup!(expiry=1.hour)
|
|
16
|
+
self.delete_all(["processed = ? AND updated_at < ?", true, expiry.to_i.ago])
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Add any serialize-able *data* to the queue *queue_name* (strings and symbols are treated the same)
|
|
20
|
+
#
|
|
21
|
+
# RudeQueue.set(:sausage_queue, Sausage.new(:sauce => "yummy"))
|
|
22
|
+
# RudeQueue.set("sausage_queue", Sausage.new(:other => true))
|
|
23
|
+
#
|
|
24
|
+
# RudeQueue.get("sausage_queue")
|
|
25
|
+
# -> *yummy sausage*
|
|
26
|
+
# RudeQueue.get(:sausage_queue)
|
|
27
|
+
# -> *other_sausage*
|
|
28
|
+
# RudeQueue.get(:sausage_queue)
|
|
29
|
+
# -> nil
|
|
30
|
+
def set(queue_name, data)
|
|
31
|
+
queue_name = sanitize_queue_name(queue_name)
|
|
32
|
+
self.create!(:queue_name => queue_name, :data => data)
|
|
33
|
+
return nil # in line with Starling
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Grab the first item from the queue *queue_name* (strings and symbols are treated the same)
|
|
37
|
+
# - it should always come out the same as it went in
|
|
38
|
+
# - they should always come out in the same order they went in
|
|
39
|
+
# - it will return a nil if there is no unprocessed entry in the queue
|
|
40
|
+
#
|
|
41
|
+
# RudeQueue.get(21)
|
|
42
|
+
# -> {:a => "hash"}
|
|
43
|
+
# RudeQueue.get(:a_symbol)
|
|
44
|
+
# -> 255
|
|
45
|
+
# RudeQueue.get("a string")
|
|
46
|
+
# -> nil
|
|
47
|
+
def get(queue_name)
|
|
48
|
+
qname = sanitize_queue_name(queue_name)
|
|
49
|
+
token = get_unique_token
|
|
50
|
+
|
|
51
|
+
self.update_all(["token = ?", token], ["queue_name = ? AND processed = ? AND token IS NULL", qname, false], :limit => 1, :order => "id ASC")
|
|
52
|
+
queued = self.find_by_queue_name_and_token_and_processed(qname, token, false)
|
|
53
|
+
if queued
|
|
54
|
+
queued.update_attribute(:processed, true)
|
|
55
|
+
return queued.data
|
|
56
|
+
else
|
|
57
|
+
return nil # in line with Starling
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def get_unique_token # :nodoc:
|
|
62
|
+
|
|
63
|
+
digest = Digest::SHA1.new
|
|
64
|
+
digest << Time.now.to_s
|
|
65
|
+
digest << Process.pid.to_s
|
|
66
|
+
digest << Socket.gethostname
|
|
67
|
+
digest << self.token_count!.to_s # multiple requests from the same pid in the same second get different token
|
|
68
|
+
|
|
69
|
+
return digest.hexdigest
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
protected
|
|
73
|
+
|
|
74
|
+
def token_count!
|
|
75
|
+
@token_count ||= 0
|
|
76
|
+
@token_count += 1
|
|
77
|
+
return @token_count
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def sanitize_queue_name(queue_name)
|
|
81
|
+
queue_name.to_s
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
data/spec/database.yml
ADDED
data/spec/rude_q_spec.rb
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ProcessQueue do
|
|
4
|
+
before(:each) do
|
|
5
|
+
ProcessQueue.delete_all
|
|
6
|
+
create_some_noise
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def create_some_noise
|
|
10
|
+
ProcessQueue.create!(:queue_name => "doNT use this in Specs", :data => {:not => "to be messed with"})
|
|
11
|
+
ProcessQueue.create!(:queue_name => "abcde", :data => {:same_as => "the specs but already processed"}, :processed => true)
|
|
12
|
+
ProcessQueue.create!(:queue_name => "abcde", :data => {:same_as => "the specs but with token"}, :token => " unlikely ")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "get and set" do
|
|
16
|
+
it "should work with strings" do
|
|
17
|
+
ProcessQueue.set('abcde', "Something to set")
|
|
18
|
+
ProcessQueue.get('abcde').should == "Something to set"
|
|
19
|
+
end
|
|
20
|
+
it "should work with symbols" do
|
|
21
|
+
ProcessQueue.set('abcde', :a_symbol)
|
|
22
|
+
ProcessQueue.get('abcde').should == :a_symbol
|
|
23
|
+
end
|
|
24
|
+
it "should work with arrays" do
|
|
25
|
+
array = [1, :b, "C"]
|
|
26
|
+
ProcessQueue.set('abcde', array)
|
|
27
|
+
ProcessQueue.get('abcde').should == array
|
|
28
|
+
end
|
|
29
|
+
it "should work with hashes" do
|
|
30
|
+
hash = {:symbol => "A string", "stringy" => 23, 74 => :cheese}
|
|
31
|
+
ProcessQueue.set('abcde', hash)
|
|
32
|
+
ProcessQueue.get('abcde').should == hash
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should :get in the same order they are :set" do
|
|
36
|
+
ProcessQueue.set('abcde', :first)
|
|
37
|
+
ProcessQueue.set('abcde', "second")
|
|
38
|
+
|
|
39
|
+
ProcessQueue.get('abcde').should == :first
|
|
40
|
+
|
|
41
|
+
ProcessQueue.set('abcde', 33.3333)
|
|
42
|
+
|
|
43
|
+
ProcessQueue.get('abcde').should == "second"
|
|
44
|
+
ProcessQueue.get('abcde').should == 33.3333
|
|
45
|
+
ProcessQueue.get('abcde').should be(nil)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should keep queues seperated" do
|
|
49
|
+
ProcessQueue.set('queue_1', :data_1)
|
|
50
|
+
ProcessQueue.set('queue_2', "DATA2")
|
|
51
|
+
|
|
52
|
+
ProcessQueue.get('queue_2').should == "DATA2"
|
|
53
|
+
ProcessQueue.get('queue_2').should be(nil)
|
|
54
|
+
ProcessQueue.get('queue_1').should == :data_1
|
|
55
|
+
ProcessQueue.get('queue_1').should be(nil)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should call to_s on inputs" do
|
|
59
|
+
qname = stub("fake input")
|
|
60
|
+
qname.should_receive(:to_s).exactly(:twice).and_return("fake queue name")
|
|
61
|
+
|
|
62
|
+
ProcessQueue.set(qname, ["Data"])
|
|
63
|
+
ProcessQueue.get(qname).should == ["Data"]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should work with queue name as strings or symbols" do
|
|
67
|
+
ProcessQueue.set(:bah, "something about bah")
|
|
68
|
+
ProcessQueue.get("bah").should == "something about bah"
|
|
69
|
+
|
|
70
|
+
ProcessQueue.set("girah", {:craziness => "embodied"})
|
|
71
|
+
ProcessQueue.get(:girah).should == {:craziness => "embodied"}
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe ".set" do
|
|
76
|
+
it "should delegate to :create!" do
|
|
77
|
+
ProcessQueue.should_receive(:create!).with(:queue_name => 'abcde', :data => :magical_planet)
|
|
78
|
+
ProcessQueue.set('abcde', :magical_planet)
|
|
79
|
+
end
|
|
80
|
+
it "should return nil" do
|
|
81
|
+
ProcessQueue.set('abcde', "something").should be(nil)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe ".get" do
|
|
86
|
+
it "should not return a processed item with the same token" do
|
|
87
|
+
@token = "tokEEEannn"
|
|
88
|
+
ProcessQueue.should_receive(:get_unique_token).exactly(3).times.and_return(@token)
|
|
89
|
+
@existing = ProcessQueue.create!(:queue_name => 'abcde', :data => :old_data, :token => @token, :processed => true)
|
|
90
|
+
|
|
91
|
+
ProcessQueue.get('abcde').should be(nil)
|
|
92
|
+
|
|
93
|
+
ProcessQueue.set('abcde', :new_data)
|
|
94
|
+
ProcessQueue.get('abcde').should == :new_data
|
|
95
|
+
ProcessQueue.get('abcde').should be(nil)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe ".get_unique_token" do
|
|
100
|
+
it "should create a unique token" do
|
|
101
|
+
lots_of_tokens = Array.new(50) do
|
|
102
|
+
ProcessQueue.get_unique_token
|
|
103
|
+
end
|
|
104
|
+
lots_of_tokens.uniq.should == lots_of_tokens
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should create a unique token even if time stands still" do
|
|
108
|
+
time_now = Time.now
|
|
109
|
+
Time.should_receive(:now).at_least(50).times.and_return(time_now)
|
|
110
|
+
lots_of_tokens = Array.new(50) do
|
|
111
|
+
ProcessQueue.get_unique_token
|
|
112
|
+
end
|
|
113
|
+
lots_of_tokens.uniq.should == lots_of_tokens
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
describe ".cleanup!" do
|
|
118
|
+
it "should use :delete_all" do
|
|
119
|
+
ProcessQueue.should_receive(:delete_all) # not :destroy_all
|
|
120
|
+
ProcessQueue.cleanup!
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should allow string inputs" do
|
|
124
|
+
ProcessQueue.cleanup!("3600")
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should allow integer inputs" do
|
|
128
|
+
ProcessQueue.cleanup!(3600)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "should not clear unprocessed items" do
|
|
132
|
+
ProcessQueue.set('abcde', :giraffe)
|
|
133
|
+
ProcessQueue.set('abcde', :monkey)
|
|
134
|
+
ProcessQueue.count.should >= 2
|
|
135
|
+
|
|
136
|
+
ProcessQueue.cleanup!
|
|
137
|
+
|
|
138
|
+
ProcessQueue.count.should >=2
|
|
139
|
+
ProcessQueue.get('abcde').should == :giraffe
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "should not clear old unprocessed items" do
|
|
143
|
+
ProcessQueue.set('abcde', :giraffe)
|
|
144
|
+
giraffe = ProcessQueue.find(:first, :conditions => {:data => :giraffe})
|
|
145
|
+
|
|
146
|
+
time_now = Time.now
|
|
147
|
+
Time.stub!(:now).and_return(time_now + 1.year)
|
|
148
|
+
|
|
149
|
+
giraffe.updated_at.should < 2.weeks.ago
|
|
150
|
+
|
|
151
|
+
ProcessQueue.cleanup!
|
|
152
|
+
|
|
153
|
+
giraffe.reload
|
|
154
|
+
ProcessQueue.get('abcde').should == :giraffe
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "should not clear processed items newer than the argument" do
|
|
158
|
+
ProcessQueue.set('abcde', :giraffe)
|
|
159
|
+
ProcessQueue.get('abcde').should == :giraffe
|
|
160
|
+
|
|
161
|
+
giraffe = ProcessQueue.find(:first, :conditions => {:data => :giraffe})
|
|
162
|
+
|
|
163
|
+
time_now = Time.now
|
|
164
|
+
Time.stub!(:now).and_return(time_now + 1.week - 5.minutes)
|
|
165
|
+
|
|
166
|
+
giraffe.updated_at.should > 1.week.ago
|
|
167
|
+
giraffe.processed.should be(true)
|
|
168
|
+
|
|
169
|
+
ProcessQueue.cleanup!(1.week)
|
|
170
|
+
|
|
171
|
+
giraffe.reload
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "should not clear processed items newer than one hour, by default" do
|
|
175
|
+
ProcessQueue.set('abcde', :giraffe)
|
|
176
|
+
ProcessQueue.get('abcde').should == :giraffe
|
|
177
|
+
|
|
178
|
+
giraffe = ProcessQueue.find(:first, :conditions => {:data => :giraffe})
|
|
179
|
+
|
|
180
|
+
time_now = Time.now
|
|
181
|
+
Time.stub!(:now).and_return(time_now + 59.minutes)
|
|
182
|
+
|
|
183
|
+
giraffe.updated_at.should > 1.hour.ago
|
|
184
|
+
giraffe.processed.should be(true)
|
|
185
|
+
|
|
186
|
+
ProcessQueue.cleanup!()
|
|
187
|
+
|
|
188
|
+
giraffe.reload
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "should clear processed items older than the argument" do
|
|
192
|
+
ProcessQueue.set('abcde', :giraffe)
|
|
193
|
+
ProcessQueue.get('abcde').should == :giraffe
|
|
194
|
+
|
|
195
|
+
giraffe = ProcessQueue.find(:first, :conditions => {:data => :giraffe})
|
|
196
|
+
|
|
197
|
+
time_now = Time.now
|
|
198
|
+
Time.stub!(:now).and_return(time_now + 1.week + 5.minutes)
|
|
199
|
+
|
|
200
|
+
giraffe.updated_at.should < 1.week.ago
|
|
201
|
+
giraffe.processed.should be(true)
|
|
202
|
+
|
|
203
|
+
ProcessQueue.cleanup!(1.week)
|
|
204
|
+
|
|
205
|
+
lambda { giraffe.reload }.should raise_error(ActiveRecord::RecordNotFound)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "should clear processed items older than one hour, by default" do
|
|
209
|
+
ProcessQueue.set('abcde', :giraffe)
|
|
210
|
+
ProcessQueue.get('abcde').should == :giraffe
|
|
211
|
+
|
|
212
|
+
giraffe = ProcessQueue.find(:first, :conditions => {:data => :giraffe})
|
|
213
|
+
|
|
214
|
+
time_now = Time.now()
|
|
215
|
+
Time.stub!(:now).and_return(time_now + 61.minutes)
|
|
216
|
+
|
|
217
|
+
giraffe.updated_at.should < 1.hour.ago
|
|
218
|
+
giraffe.processed.should be(true)
|
|
219
|
+
|
|
220
|
+
ProcessQueue.cleanup!
|
|
221
|
+
|
|
222
|
+
lambda { giraffe.reload }.should raise_error(ActiveRecord::RecordNotFound)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
data/spec/schema.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
ActiveRecord::Schema.define(:version => 1) do
|
|
2
|
+
create_table :process_queues, :force => true do |t|
|
|
3
|
+
t.string :queue_name
|
|
4
|
+
t.text :data
|
|
5
|
+
t.string :token, :default => nil
|
|
6
|
+
t.boolean :processed, :default => false, :null => false
|
|
7
|
+
|
|
8
|
+
t.timestamps
|
|
9
|
+
end
|
|
10
|
+
add_index :process_queues, :processed
|
|
11
|
+
add_index :process_queues, [:queue_name, :processed]
|
|
12
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'spec'
|
|
3
|
+
require 'active_record'
|
|
4
|
+
|
|
5
|
+
current_dir = File.dirname(__FILE__)
|
|
6
|
+
require "#{current_dir}/../lib/rude_q"
|
|
7
|
+
require "#{current_dir}/process_queue"
|
|
8
|
+
|
|
9
|
+
config = YAML::load(IO.read(current_dir + '/database.yml'))
|
|
10
|
+
ActiveRecord::Base.logger = Logger.new(current_dir + "/debug.log")
|
|
11
|
+
ActiveRecord::Base.establish_connection(config['rude_q_test'])
|
|
12
|
+
load(current_dir + "/schema.rb")
|
metadata
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: matthewrudy-rudeq
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: "0.1"
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Matthew Rudy Jacobs
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2008-06-21 00:00:00 -07:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: activerecord
|
|
17
|
+
version_requirement:
|
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
19
|
+
requirements:
|
|
20
|
+
- - ">="
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: "0"
|
|
23
|
+
version:
|
|
24
|
+
description: A simple DB queueing library built on top of ActiveRecord, and designed for use with MySQL.
|
|
25
|
+
email: MatthewRudyJacobs@gmail.com
|
|
26
|
+
executables: []
|
|
27
|
+
|
|
28
|
+
extensions: []
|
|
29
|
+
|
|
30
|
+
extra_rdoc_files:
|
|
31
|
+
- README
|
|
32
|
+
files:
|
|
33
|
+
- README
|
|
34
|
+
- Rakefile
|
|
35
|
+
- lib/rude_q.rb
|
|
36
|
+
- spec/database.yml
|
|
37
|
+
- spec/process_queue.rb
|
|
38
|
+
- spec/rude_q_spec.rb
|
|
39
|
+
- spec/schema.rb
|
|
40
|
+
- spec/spec.opts
|
|
41
|
+
- spec/spec_helper.rb
|
|
42
|
+
has_rdoc: true
|
|
43
|
+
homepage: http://github.com/matthewrudy/rudeq
|
|
44
|
+
post_install_message:
|
|
45
|
+
rdoc_options:
|
|
46
|
+
- --main
|
|
47
|
+
- README
|
|
48
|
+
require_paths:
|
|
49
|
+
- lib
|
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: "0"
|
|
55
|
+
version:
|
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: "0"
|
|
61
|
+
version:
|
|
62
|
+
requirements: []
|
|
63
|
+
|
|
64
|
+
rubyforge_project:
|
|
65
|
+
rubygems_version: 1.0.1
|
|
66
|
+
signing_key:
|
|
67
|
+
specification_version: 2
|
|
68
|
+
summary: ActiveRecord-based DB-queue
|
|
69
|
+
test_files:
|
|
70
|
+
- spec/rude_q_spec.rb
|