kthxbye 1.0.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.
Files changed (41) hide show
  1. data/.document +5 -0
  2. data/.gitignore +33 -0
  3. data/DESIGN.textile +81 -0
  4. data/Gemfile +21 -0
  5. data/Gemfile.lock +42 -0
  6. data/LICENSE +20 -0
  7. data/README.textile +91 -0
  8. data/Rakefile +53 -0
  9. data/VERSION +1 -0
  10. data/config.ru +7 -0
  11. data/lib/kthxbye.rb +151 -0
  12. data/lib/kthxbye/config.rb +35 -0
  13. data/lib/kthxbye/exceptions.rb +4 -0
  14. data/lib/kthxbye/failure.rb +62 -0
  15. data/lib/kthxbye/helper.rb +42 -0
  16. data/lib/kthxbye/job.rb +127 -0
  17. data/lib/kthxbye/version.rb +5 -0
  18. data/lib/kthxbye/web_interface.rb +117 -0
  19. data/lib/kthxbye/web_interface/public/application.js +16 -0
  20. data/lib/kthxbye/web_interface/public/awesome-buttons.css +108 -0
  21. data/lib/kthxbye/web_interface/public/jquery.js +154 -0
  22. data/lib/kthxbye/web_interface/public/style.css +128 -0
  23. data/lib/kthxbye/web_interface/views/error.haml +5 -0
  24. data/lib/kthxbye/web_interface/views/failed.haml +26 -0
  25. data/lib/kthxbye/web_interface/views/hash.haml +6 -0
  26. data/lib/kthxbye/web_interface/views/layout.haml +33 -0
  27. data/lib/kthxbye/web_interface/views/overview.haml +2 -0
  28. data/lib/kthxbye/web_interface/views/queues.haml +31 -0
  29. data/lib/kthxbye/web_interface/views/set.haml +4 -0
  30. data/lib/kthxbye/web_interface/views/stats.haml +32 -0
  31. data/lib/kthxbye/web_interface/views/view_backtrace.haml +8 -0
  32. data/lib/kthxbye/web_interface/views/workers.haml +24 -0
  33. data/lib/kthxbye/web_interface/views/working.haml +19 -0
  34. data/lib/kthxbye/worker.rb +221 -0
  35. data/test/helper.rb +18 -0
  36. data/test/redis-test.conf +115 -0
  37. data/test/test_failure.rb +51 -0
  38. data/test/test_helper.rb +86 -0
  39. data/test/test_kthxbye.rb +213 -0
  40. data/test/test_worker.rb +148 -0
  41. metadata +364 -0
@@ -0,0 +1,213 @@
1
+ require 'test_helper'
2
+
3
+ class TestKthxbye < Test::Unit::TestCase
4
+ context "See Kthxbye Configuration" do
5
+
6
+ should "configure an app with given params" do
7
+ k = Kthxbye::Config.setup(:redis_server => "localhost", :redis_port => 8080, :verbose => true)
8
+
9
+ assert_equal 'localhost', Kthxbye::Config.options[:redis_server]
10
+ assert_equal 8080, Kthxbye::Config.options[:redis_port]
11
+ assert_equal true, Kthxbye::Config.options[:verbose]
12
+ end
13
+
14
+ should "configure an app with default params" do
15
+ Kthxbye::Config.setup
16
+
17
+ assert_equal '127.0.0.1', Kthxbye::Config.options[:redis_server]
18
+ assert_equal 9876, Kthxbye::Config.options[:redis_port]
19
+ assert_equal false, Kthxbye::Config.options[:verbose]
20
+ end
21
+
22
+ end
23
+
24
+ context "See Kthxbye" do
25
+ setup do
26
+ Kthxbye::Config.setup
27
+ Kthxbye.redis.flushall
28
+ end
29
+
30
+ should "register unregister and delete queues" do
31
+ assert_equal 0, Kthxbye.queues.size
32
+
33
+ assert Kthxbye.register_queue "dogs"
34
+ assert Kthxbye.register_queue "cats"
35
+
36
+ assert_equal 2, Kthxbye.queues.size
37
+ assert_equal ["cats", "dogs"], Kthxbye.queues
38
+
39
+ assert Kthxbye.unregister_queue("dogs")
40
+ assert_equal ["cats"], Kthxbye.queues
41
+
42
+ assert Kthxbye.delete_queue("cats")
43
+ assert_equal [], Kthxbye.queues
44
+ end
45
+
46
+ should "store a couple of jobs and return good ids" do
47
+ assert id = Kthxbye.enqueue("test", SimpleJob, {:hello => "world"}, "test params")
48
+ assert id2 = Kthxbye.enqueue("test", GoodJob, "I am a sentence to print")
49
+ assert_equal 1, id
50
+ assert_equal 2, id2
51
+ end
52
+
53
+ should "enqueue a job and show a queue size of one" do
54
+ assert_equal 0, Kthxbye.size("test")
55
+ Kthxbye.enqueue("test", SimpleJob, {:hello => "world"}, "test params")
56
+ assert_equal 1, Kthxbye.size("test")
57
+ end
58
+
59
+ should "peek at the datastore for a specific job" do
60
+ id = Kthxbye.enqueue("test", SimpleJob, {:hello => "world"}, "test params")
61
+ assert_equal [{'hello' => "world"}, "test params"], Kthxbye.data_peek("test", id)['payload']
62
+ end
63
+
64
+ should "peek at all the data stores" do
65
+ Kthxbye.enqueue("test", SimpleJob, "first", "job")
66
+ Kthxbye.enqueue("test", SimpleJob, "second", "job")
67
+
68
+ assert_equal ({'1' => {'klass' => 'SimpleJob', 'payload' => ["first", "job"]},
69
+ '2' => {'klass' => 'SimpleJob', 'payload' => ["second", "job"]}}), Kthxbye.data_peek("test")
70
+ end
71
+
72
+ should "peek at the resultstore for a specific job" do
73
+ id = Kthxbye.enqueue("test", GoodJob, "Jim")
74
+ worker = Kthxbye::Worker.new("test", 0)
75
+ worker.run
76
+
77
+ assert_equal "Good job, Jim", Kthxbye.result_peek("test", id)
78
+ end
79
+
80
+ should "peek at all the result stores" do
81
+ Kthxbye.enqueue("test", GoodJob, "Jim")
82
+ Kthxbye.enqueue("test", GoodJob, "Dwight")
83
+ worker = Kthxbye::Worker.new("test", 0)
84
+ worker.run
85
+
86
+ assert_equal ({'1' => "Good job, Jim", '2' => "Good job, Dwight"}), Kthxbye.result_peek("test")
87
+ end
88
+
89
+ should "show its queues correctly" do
90
+ Kthxbye.enqueue("these-jobs", SimpleJob, {:hello => "world"}, "test params")
91
+ Kthxbye.enqueue("those-jobs", SimpleJob, {:hello => "world"}, "test params")
92
+
93
+ assert_equal ["these-jobs", "those-jobs"], Kthxbye.queues
94
+
95
+ Kthxbye.delete_queue("these-jobs")
96
+ assert_equal ["those-jobs"], Kthxbye.queues
97
+ end
98
+
99
+ should "grab a job off the queue" do
100
+ Kthxbye.enqueue("these-jobs", SimpleJob, {:hello => "world"}, "test params")
101
+
102
+ assert job = Kthxbye.salvage("these-jobs")
103
+ assert_equal Kthxbye::Job, job.class
104
+ assert_equal 1, job.id
105
+ assert_equal "these-jobs", job.queue
106
+ assert_equal "SimpleJob", job.data['klass']
107
+ end
108
+
109
+ should "return a job" do
110
+ id = Kthxbye.enqueue( "test", SimpleJob, 1, 2 )
111
+ assert job = Kthxbye::Job.find( id, "test" )
112
+ assert_equal Kthxbye::Job, job.class
113
+ assert_equal [1, 2], job.data['payload']
114
+ end
115
+
116
+ should "perform a job" do
117
+ id = Kthxbye.enqueue( "test", GoodJob, "Lukas" )
118
+ job = Kthxbye::Job.find(id, "test")
119
+
120
+ assert result = job.perform
121
+ assert "Good job, Lukas!", result
122
+ end
123
+
124
+ should "retry a job if attempts setting is > 1" do
125
+ Kthxbye::Config.options[:attempts] = 2
126
+ id = Kthxbye.enqueue( "test", BadJob )
127
+ job = Kthxbye::Job.find(id, "test")
128
+
129
+ job.perform
130
+ assert_equal 2, job.instance_variable_get(:@failed_attempts)
131
+
132
+ end
133
+
134
+ should "delete a job" do
135
+ id = Kthxbye.enqueue("test", SimpleJob, 1, 2 )
136
+ assert_equal :active, Kthxbye::Job.destroy(id, "test")
137
+ assert_equal nil, Kthxbye::Job.find(id, "test")
138
+ end
139
+
140
+ should "return all keys" do
141
+ Kthxbye.enqueue("test", SimpleJob, 1, 2 )
142
+ Kthxbye.register_queue("money")
143
+
144
+ assert_equal ["data-store:test", "queue:test", "queues", "uniq_id"], Kthxbye.keys.sort
145
+ end
146
+
147
+ should "register and unregister workers" do
148
+ assert_equal [], Kthxbye.workers
149
+
150
+ worker = Kthxbye::Worker.new("bill")
151
+ worker.register_worker
152
+
153
+ assert_equal [worker], Kthxbye.workers
154
+
155
+ worker2 = Kthxbye::Worker.new("holiday")
156
+ worker2.register_worker
157
+
158
+ assert_equal [worker, worker2], Kthxbye.workers.sort
159
+
160
+ worker2.unregister_worker
161
+ assert_equal [worker], Kthxbye.workers
162
+
163
+ worker.unregister_worker
164
+ assert_equal [], Kthxbye.workers
165
+ end
166
+
167
+ should "show all active workers" do
168
+ worker = Kthxbye::Worker.new( "test" )
169
+ id = Kthxbye.enqueue( "test", SimpleJob, 1, 2 )
170
+ worker.register_worker
171
+ worker.working( Kthxbye::Job.find( id, "test" ) )
172
+
173
+ assert_equal [[worker, {'job_id' => id, 'started' => Time.now.to_s }]], Kthxbye.working
174
+ end
175
+
176
+ should "return the correct status of a job" do
177
+ worker1 = Kthxbye::Worker.new( "good", 0 )
178
+ worker2 = Kthxbye::Worker.new( "bad", 0 )
179
+
180
+ good_job = Kthxbye.enqueue( "good", GoodJob, "Dave" )
181
+ bad_job = Kthxbye.enqueue( "bad", BadJob )
182
+ job = Kthxbye::Job.find(good_job, "good")
183
+
184
+ assert_equal :active, job.status
185
+ job.dequeue
186
+ assert_equal :inactive, job.status
187
+ job.rerun
188
+
189
+ worker1.run
190
+ assert_equal :succeeded, job.status
191
+
192
+ job = Kthxbye::Job.find(bad_job, "bad")
193
+ worker2.run
194
+
195
+ assert_equal :failed, job.status
196
+ end
197
+
198
+ should "display nice inspect" do
199
+ i = Kthxbye.inspect
200
+
201
+ assert_equal Kthxbye::Version, i[:version]
202
+ assert_equal 0, i[:keys]
203
+ assert_equal 0, i[:workers]
204
+ assert_equal 0, i[:queues]
205
+ assert_equal 0, i[:working]
206
+ assert_equal 0, i[:pending]
207
+ end
208
+
209
+
210
+
211
+ end
212
+ end
213
+
@@ -0,0 +1,148 @@
1
+
2
+ class TestWorker < Test::Unit::TestCase
3
+ context "See Kthxbye::Worker" do
4
+ setup do
5
+ Kthxbye::Config.setup(:verbose => false, :redis_port => 9876)
6
+ Kthxbye.redis.flushall
7
+
8
+ @id = Kthxbye.enqueue( "test", SimpleJob, 1, 2 )
9
+ @worker = Kthxbye::Worker.new("test", 0)
10
+ end
11
+
12
+ should "register and show a worker" do
13
+ @worker.run do
14
+ assert_equal [@worker], Kthxbye.workers
15
+ end
16
+ end
17
+
18
+ should "find a registered worker and its queues" do
19
+ @worker.run do
20
+ found = Kthxbye::Worker.find(@worker.id)
21
+ assert_equal @worker, found
22
+ end
23
+ end
24
+
25
+ should "startup a worker and register it as working" do
26
+ @worker.run do
27
+ assert_equal [[@worker.to_s, {'job_id' => @id, 'started' => Time.now.to_s}]], Kthxbye.working
28
+ end
29
+ end
30
+
31
+ should "pull jobs from given queue and run them" do
32
+ @worker.run
33
+
34
+ assert_equal 0, Kthxbye.size("test")
35
+ end
36
+
37
+ should "store a job's results and retrieve them" do
38
+ id = Kthxbye.enqueue("new", GoodJob, "Lukas")
39
+ worker = Kthxbye::Worker.new("new", 0)
40
+ worker.run
41
+
42
+ assert_equal 1, Kthxbye.job_results("new").size
43
+ assert_equal "Good job, Lukas", Kthxbye.job_results("new", id)
44
+ end
45
+
46
+ should "capture and report failed jobs" do
47
+ id = Kthxbye.enqueue( "bad", BadJob )
48
+ id2 = Kthxbye.enqueue( "bad", BadJobWithSyntaxError )
49
+
50
+ assert_equal 0, Kthxbye::Failure.count
51
+
52
+ worker = Kthxbye::Worker.new("bad", 0 )
53
+ worker.run
54
+
55
+ assert_equal 2, Kthxbye::Failure.count
56
+ assert_equal "Bad job!", Kthxbye::Failure.find(id)["error"]
57
+ assert_equal "Extra Bad job!", Kthxbye::Failure.find(id2)["error"]
58
+
59
+ assert_equal ["Bad job!", "Extra Bad job!"], Kthxbye::Failure.all.map{|x| x['error']}
60
+
61
+ assert_equal 1, Kthxbye::Failure.count_type(RuntimeError)
62
+ end
63
+
64
+ should "report queues available to workers when added via csv (alphabetical)" do
65
+ worker = Kthxbye::Worker.new("good,bad,ugly")
66
+ assert_equal ["good", "bad", "ugly"].sort, worker.queues
67
+ end
68
+
69
+ should "report queues available to workers when using * (alphabetical)" do
70
+ Kthxbye.register_queue("hello")
71
+ Kthxbye.register_queue("world")
72
+
73
+ worker = Kthxbye::Worker.new("*")
74
+ assert_equal ["hello", "test", "world"].sort, worker.queues
75
+ end
76
+
77
+ should "report queues available to worker when passed an array (alphabetical)" do
78
+ worker = Kthxbye::Worker.new(["one", "two", "three"])
79
+ assert_equal ["one", "two", "three"].sort, worker.queues
80
+ end
81
+
82
+ should "work jobs from multiple queues" do
83
+ Kthxbye.enqueue("other", GoodJob, "Boieee")
84
+ Kthxbye.enqueue("more", GoodJob, "Lukas")
85
+
86
+ worker = Kthxbye::Worker.new("*", 0)
87
+
88
+ worker.run
89
+
90
+ assert_equal 0, Kthxbye.size("test")
91
+ assert_equal 0, Kthxbye.size("other")
92
+ assert_equal 0, Kthxbye.size("more")
93
+ end
94
+
95
+ should "return job active once working it" do
96
+ job = Kthxbye::Job.find(@id, "test")
97
+
98
+ @worker.working(job)
99
+
100
+ assert @worker.working?
101
+ assert_equal @worker.current_job, job
102
+
103
+ assert job.active?
104
+ end
105
+
106
+ should "know when it is working" do
107
+ @worker.run do
108
+ assert @worker.working?
109
+ assert Kthxbye::Job.find(@id, @worker.current_queue ).active?
110
+ end
111
+ end
112
+
113
+ should "know which is the current queue" do
114
+ worker = Kthxbye::Worker.new("*", 0)
115
+ worker.run do
116
+ assert_equal "test", worker.current_queue
117
+ end
118
+ end
119
+
120
+ should "know which is the current job id" do
121
+ worker = Kthxbye::Worker.new("*", 0)
122
+ worker.run do
123
+ assert_equal Kthxbye::Job.find(@id, worker.current_queue), worker.current_job
124
+ end
125
+ end
126
+
127
+ should "find the current job" do
128
+ @worker.run do
129
+ assert_equal ({'job_id' => @id, 'started' => Time.now.to_s}), Kthxbye::Worker.working_on(@worker.id)
130
+ end
131
+ end
132
+
133
+ should "requeue a job and report error if worker is killed mid-process" do
134
+ @worker.working( Kthxbye::Job.find( @id, "test" ) )
135
+ @worker.unregister_worker
136
+
137
+ assert_equal 1, Kthxbye::Failure.all.size
138
+ assert_equal "Kthxbye::ActiveWorkerKilled", Kthxbye::Failure.find(@id)['type']
139
+ assert_not_nil job = Kthxbye::Job.find( @id, "test" )
140
+ assert_equal 1, job.failed_attempts
141
+ end
142
+
143
+ should "show a pretty inspect" do
144
+ assert_equal "#<Worker: #{@worker.id}>", @worker.inspect
145
+ end
146
+
147
+ end
148
+ end
metadata ADDED
@@ -0,0 +1,364 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kthxbye
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Luke van der Hoeven
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-09-23 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ name: redis
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ requirement: *id001
34
+ type: :runtime
35
+ - !ruby/object:Gem::Dependency
36
+ prerelease: false
37
+ name: yajl-ruby
38
+ version_requirements: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ requirement: *id002
48
+ type: :runtime
49
+ - !ruby/object:Gem::Dependency
50
+ prerelease: false
51
+ name: json
52
+ version_requirements: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ requirement: *id003
62
+ type: :runtime
63
+ - !ruby/object:Gem::Dependency
64
+ prerelease: false
65
+ name: mail
66
+ version_requirements: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ requirement: *id004
76
+ type: :runtime
77
+ - !ruby/object:Gem::Dependency
78
+ prerelease: false
79
+ name: i18n
80
+ version_requirements: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ requirement: *id005
90
+ type: :runtime
91
+ - !ruby/object:Gem::Dependency
92
+ prerelease: false
93
+ name: sinatra
94
+ version_requirements: &id006 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ requirement: *id006
104
+ type: :runtime
105
+ - !ruby/object:Gem::Dependency
106
+ prerelease: false
107
+ name: shoulda
108
+ version_requirements: &id007 !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ requirement: *id007
118
+ type: :development
119
+ - !ruby/object:Gem::Dependency
120
+ prerelease: false
121
+ name: bundler
122
+ version_requirements: &id008 !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ~>
126
+ - !ruby/object:Gem::Version
127
+ hash: 23
128
+ segments:
129
+ - 1
130
+ - 0
131
+ - 0
132
+ version: 1.0.0
133
+ requirement: *id008
134
+ type: :development
135
+ - !ruby/object:Gem::Dependency
136
+ prerelease: false
137
+ name: jeweler
138
+ version_requirements: &id009 !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ~>
142
+ - !ruby/object:Gem::Version
143
+ hash: 270495430
144
+ segments:
145
+ - 1
146
+ - 5
147
+ - 0
148
+ - pre3
149
+ version: 1.5.0.pre3
150
+ requirement: *id009
151
+ type: :development
152
+ - !ruby/object:Gem::Dependency
153
+ prerelease: false
154
+ name: rcov
155
+ version_requirements: &id010 !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ hash: 3
161
+ segments:
162
+ - 0
163
+ version: "0"
164
+ requirement: *id010
165
+ type: :development
166
+ - !ruby/object:Gem::Dependency
167
+ prerelease: false
168
+ name: shoulda
169
+ version_requirements: &id011 !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ hash: 3
175
+ segments:
176
+ - 0
177
+ version: "0"
178
+ requirement: *id011
179
+ type: :development
180
+ - !ruby/object:Gem::Dependency
181
+ prerelease: false
182
+ name: bundler
183
+ version_requirements: &id012 !ruby/object:Gem::Requirement
184
+ none: false
185
+ requirements:
186
+ - - ~>
187
+ - !ruby/object:Gem::Version
188
+ hash: 23
189
+ segments:
190
+ - 1
191
+ - 0
192
+ - 0
193
+ version: 1.0.0
194
+ requirement: *id012
195
+ type: :development
196
+ - !ruby/object:Gem::Dependency
197
+ prerelease: false
198
+ name: jeweler
199
+ version_requirements: &id013 !ruby/object:Gem::Requirement
200
+ none: false
201
+ requirements:
202
+ - - ~>
203
+ - !ruby/object:Gem::Version
204
+ hash: 270495430
205
+ segments:
206
+ - 1
207
+ - 5
208
+ - 0
209
+ - pre3
210
+ version: 1.5.0.pre3
211
+ requirement: *id013
212
+ type: :development
213
+ - !ruby/object:Gem::Dependency
214
+ prerelease: false
215
+ name: rcov
216
+ version_requirements: &id014 !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - ">="
220
+ - !ruby/object:Gem::Version
221
+ hash: 3
222
+ segments:
223
+ - 0
224
+ version: "0"
225
+ requirement: *id014
226
+ type: :development
227
+ - !ruby/object:Gem::Dependency
228
+ prerelease: false
229
+ name: redis
230
+ version_requirements: &id015 !ruby/object:Gem::Requirement
231
+ none: false
232
+ requirements:
233
+ - - ~>
234
+ - !ruby/object:Gem::Version
235
+ hash: 5
236
+ segments:
237
+ - 2
238
+ - 0
239
+ - 5
240
+ version: 2.0.5
241
+ requirement: *id015
242
+ type: :runtime
243
+ - !ruby/object:Gem::Dependency
244
+ prerelease: false
245
+ name: yajl-ruby
246
+ version_requirements: &id016 !ruby/object:Gem::Requirement
247
+ none: false
248
+ requirements:
249
+ - - ">="
250
+ - !ruby/object:Gem::Version
251
+ hash: 13
252
+ segments:
253
+ - 0
254
+ - 7
255
+ - 7
256
+ version: 0.7.7
257
+ requirement: *id016
258
+ type: :runtime
259
+ - !ruby/object:Gem::Dependency
260
+ prerelease: false
261
+ name: json
262
+ version_requirements: &id017 !ruby/object:Gem::Requirement
263
+ none: false
264
+ requirements:
265
+ - - ~>
266
+ - !ruby/object:Gem::Version
267
+ hash: 11
268
+ segments:
269
+ - 1
270
+ - 4
271
+ - 6
272
+ version: 1.4.6
273
+ requirement: *id017
274
+ type: :runtime
275
+ description: "Kthxbye is the answer to a fairly unique-yet-common problem: Background job processing when we care about the result."
276
+ email: hungerandthirst@gmail.com
277
+ executables: []
278
+
279
+ extensions: []
280
+
281
+ extra_rdoc_files:
282
+ - LICENSE
283
+ - README.textile
284
+ files:
285
+ - .document
286
+ - .gitignore
287
+ - DESIGN.textile
288
+ - Gemfile
289
+ - Gemfile.lock
290
+ - LICENSE
291
+ - README.textile
292
+ - Rakefile
293
+ - VERSION
294
+ - config.ru
295
+ - lib/kthxbye.rb
296
+ - lib/kthxbye/config.rb
297
+ - lib/kthxbye/exceptions.rb
298
+ - lib/kthxbye/failure.rb
299
+ - lib/kthxbye/helper.rb
300
+ - lib/kthxbye/job.rb
301
+ - lib/kthxbye/version.rb
302
+ - lib/kthxbye/web_interface.rb
303
+ - lib/kthxbye/web_interface/public/application.js
304
+ - lib/kthxbye/web_interface/public/awesome-buttons.css
305
+ - lib/kthxbye/web_interface/public/jquery.js
306
+ - lib/kthxbye/web_interface/public/style.css
307
+ - lib/kthxbye/web_interface/views/error.haml
308
+ - lib/kthxbye/web_interface/views/failed.haml
309
+ - lib/kthxbye/web_interface/views/hash.haml
310
+ - lib/kthxbye/web_interface/views/layout.haml
311
+ - lib/kthxbye/web_interface/views/overview.haml
312
+ - lib/kthxbye/web_interface/views/queues.haml
313
+ - lib/kthxbye/web_interface/views/set.haml
314
+ - lib/kthxbye/web_interface/views/stats.haml
315
+ - lib/kthxbye/web_interface/views/view_backtrace.haml
316
+ - lib/kthxbye/web_interface/views/workers.haml
317
+ - lib/kthxbye/web_interface/views/working.haml
318
+ - lib/kthxbye/worker.rb
319
+ - test/helper.rb
320
+ - test/redis-test.conf
321
+ - test/test_failure.rb
322
+ - test/test_helper.rb
323
+ - test/test_kthxbye.rb
324
+ - test/test_worker.rb
325
+ has_rdoc: true
326
+ homepage: http://github.com/plukevdh/kthxbye
327
+ licenses: []
328
+
329
+ post_install_message:
330
+ rdoc_options: []
331
+
332
+ require_paths:
333
+ - lib
334
+ required_ruby_version: !ruby/object:Gem::Requirement
335
+ none: false
336
+ requirements:
337
+ - - ">="
338
+ - !ruby/object:Gem::Version
339
+ hash: 3
340
+ segments:
341
+ - 0
342
+ version: "0"
343
+ required_rubygems_version: !ruby/object:Gem::Requirement
344
+ none: false
345
+ requirements:
346
+ - - ">="
347
+ - !ruby/object:Gem::Version
348
+ hash: 3
349
+ segments:
350
+ - 0
351
+ version: "0"
352
+ requirements: []
353
+
354
+ rubyforge_project:
355
+ rubygems_version: 1.3.7
356
+ signing_key:
357
+ specification_version: 3
358
+ summary: Async processing + results notification
359
+ test_files:
360
+ - test/helper.rb
361
+ - test/test_failure.rb
362
+ - test/test_helper.rb
363
+ - test/test_kthxbye.rb
364
+ - test/test_worker.rb