sucker_punch 0.5.1 → 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bfa065a0910c2a661bcf6e4b084d335e69d0eaf0
4
- data.tar.gz: b7adbddd6cfef43dd535daa1e53be3e95361d663
3
+ metadata.gz: d30899558c37fb7f4f048e63520446ab0713746e
4
+ data.tar.gz: d1d3aa2d0e641b78b30c17fc49f48ddab368cbb9
5
5
  SHA512:
6
- metadata.gz: 4f4e52fbf2fd0dadeaed1a6629f4b4d1a27bf46adbb9c96756b5001cdc8da32ea6a253f7851dabef5099874c6417373b40c2c6dbe9d848308d1d6c6c456cbc1d
7
- data.tar.gz: 1a2dde0085716b865decb16a9c5933fa696fcd6e98269549133e0ec7e7b33773f35b277f098301ef981d05a779aff499d64d64739a898208aba4994c0af6b798
6
+ metadata.gz: 2568a1953bedf82b39675ce6a4d55ec0d60266aaf5c6e5c7203b0ccd6cab8d4bdd9a5e393a4badd9e3bc6a4e75e7e320c8657ce548828c617da2b2b755d1e292
7
+ data.tar.gz: 4b9355da76ac828677c9081330e64c48b9c85618f466c4b3149afc47233e3b163b2b9a7871dbb9b781efe3abd3eb8d00e67d83d7bf3161997dfebffc0c620391
data/CHANGES.md CHANGED
@@ -1,3 +1,10 @@
1
+ 1.0.0.pre
2
+ --------
3
+
4
+ - Removed the need for a configuration initializer
5
+ - include `SuckerPunch::Job` instead of `SuckerPunch::Worker`
6
+ - Use standard Ruby job class instantiation to perform a job (ie. LogJob.new.async.perform)
7
+
1
8
  0.5.1
2
9
  --------
3
10
 
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Build Status](https://travis-ci.org/brandonhilkert/sucker_punch.png?branch=master)](https://travis-ci.org/brandonhilkert/sucker_punch)
4
4
  [![Code Climate](https://codeclimate.com/github/brandonhilkert/sucker_punch.png)](https://codeclimate.com/github/brandonhilkert/sucker_punch)
5
5
 
6
- Sucker Punch is a single-process Ruby asynchronous processing library. It's [girl_friday](https://github.com/mperham/girl_friday) with syntax from [Sidekiq](https://github.com/mperham/sidekiq) and DSL sugar on top of [Celluloid](https://github.com/celluloid/celluloid/). With Celluloid's actor pattern, we can do asynchronous processing within a single process. This reduces costs of hosting on a service like Heroku along with the memory footprint of having to maintain additional workers if hosting on a dedicated server. All queues can run within a single Rails/Sinatra process.
6
+ Sucker Punch is a single-process Ruby asynchronous processing library. It's [girl_friday](https://github.com/mperham/girl_friday) and DSL sugar on top of [Celluloid](https://github.com/celluloid/celluloid/). With Celluloid's actor pattern, we can do asynchronous processing within a single process. This reduces costs of hosting on a service like Heroku along with the memory footprint of having to maintain additional jobs if hosting on a dedicated server. All queues can run within a single Rails/Sinatra process.
7
7
 
8
8
  Sucker Punch is perfect for asynchronous processes like emailing, data crunching, or social platform manipulation. No reason to hold up a user when you can do these things in the background within the same process as your web application...
9
9
 
@@ -21,25 +21,19 @@ Or install it yourself as:
21
21
 
22
22
  $ gem install sucker_punch
23
23
 
24
- ## Configuration
24
+ ## Usage
25
25
 
26
+ Each job should be a separate Ruby class and should:
26
27
 
27
- ```Ruby
28
- # config/initializers/sucker_punch.rb
28
+ * Add `include SuckerPunch::Job`
29
+ * Define the instance method `perform`, which should be the code the job will run when enqueued
29
30
 
30
- SuckerPunch.config do
31
- queue name: :log_queue, worker: LogWorker, workers: 10
32
- queue name: :awesome_queue, worker: AwesomeWorker, workers: 2
33
- end
34
- ```
35
-
36
- ## Usage
37
31
 
38
32
  ```Ruby
39
- # app/workers/log_worker.rb
33
+ # app/jobs/log_job.rb
40
34
 
41
- class LogWorker
42
- include SuckerPunch::Worker
35
+ class LogJob
36
+ include SuckerPunch::Job
43
37
 
44
38
  def perform(event)
45
39
  Log.new(event).track
@@ -47,16 +41,25 @@ class LogWorker
47
41
  end
48
42
  ```
49
43
 
50
- All workers should define an instance method `perform`, of which the job being queued will adhere to.
44
+ Synchronous:
45
+
46
+ ```Ruby
47
+ LogJob.new.perform("login")
48
+ ```
49
+
50
+ Asynchronous:
51
51
 
52
- Workers interacting with `ActiveRecord` should take special precaution not to exhaust connections in the pool. This can be done with `ActiveRecord::Base.connection_pool.with_connection`, which ensures the connection is returned back to the pool when completed.
52
+ ```Ruby
53
+ LogJob.new.async.perform("login") # => nil
54
+ ```
53
55
 
56
+ Jobs interacting with `ActiveRecord` should take special precaution not to exhaust connections in the pool. This can be done with `ActiveRecord::Base.connection_pool.with_connection`, which ensures the connection is returned back to the pool when completed.
54
57
 
55
58
  ```Ruby
56
- # app/workers/awesome_worker.rb
59
+ # app/jobs/awesome_job.rb
57
60
 
58
- class AwesomeWorker
59
- include SuckerPunch::Worker
61
+ class AwesomeJob
62
+ include SuckerPunch::Job
60
63
 
61
64
  def perform(user_id)
62
65
  ActiveRecord::Base.connection_pool.with_connection do
@@ -70,47 +73,19 @@ end
70
73
  We can create a job from within another job:
71
74
 
72
75
  ```Ruby
73
- class AwesomeWorker
74
- include SuckerPunch::Worker
76
+ class AwesomeJob
77
+ include SuckerPunch::Job
75
78
 
76
79
  def perform(user_id)
77
80
  ActiveRecord::Base.connection_pool.with_connection do
78
81
  user = User.find(user_id)
79
82
  user.update_attributes(is_awesome: true)
80
- SuckerPunch::Queue[:log_queue].async.perform("User #{user.id} became awesome!")
83
+ LogJob.new.async.perform("User #{user.id} became awesome!")
81
84
  end
82
85
  end
83
86
  end
84
87
  ```
85
88
 
86
- Queues:
87
-
88
- ```Ruby
89
- SuckerPunch::Queue[:log_queue] # Just a wrapper for the LogWorker class
90
- SuckerPunch::Queue.new(:log_queue)
91
- ```
92
-
93
- Synchronous:
94
-
95
- ```Ruby
96
- SuckerPunch::Queue[:log_queue].perform("login")
97
- ```
98
-
99
- Asynchronous:
100
-
101
- ```Ruby
102
- SuckerPunch::Queue[:log_queue].async.perform("login") # => nil
103
- ```
104
-
105
- ## Stats
106
-
107
- ```Ruby
108
- SuckerPunch::Queue[:log_queue].workers # => 10
109
- SuckerPunch::Queue[:log_queue].size # => 23 # # of jobs enqueued
110
- SuckerPunch::Queue[:log_queue].busy_size # => 7
111
- SuckerPunch::Queue[:log_queue].idle_size # => 3
112
- ```
113
-
114
89
  ## Logger
115
90
 
116
91
  ```Ruby
@@ -118,76 +93,24 @@ SuckerPunch.logger = Logger.new('sucker_punch')
118
93
  SuckerPunch.logger # => #<Logger:0x007fa1f28b83f0>
119
94
  ```
120
95
 
121
- If SuckerPunch is being within a Rails application, SuckerPunch's logger is set to Rails.logger.
122
-
123
- ## Testing (Only 0.3.1+)
124
-
125
- ```Ruby
126
- # spec/spec_helper.rb
127
- require 'sucker_punch/testing'
128
- ```
129
-
130
- Requiring this library completely stubs out the internals of Sucker Punch, but will provide the necessary tools to confirm your jobs are being enqueud.
131
-
132
- ```Ruby
133
- # spec/spec_helper.rb
134
- require 'sucker_punch/testing'
135
-
136
- RSpec.configure do |config|
137
- config.after do
138
- SuckerPunch.reset! # => Resets the queues and jobs in the queues before each test
139
- end
140
- end
141
-
142
- # config/initializer/sucker_punch.rb
143
- SuckerPunch.config do
144
- queue name: :email, worker: EmailWorker, workers: 2
145
- end
96
+ If Sucker Punch is being used within a Rails application, Sucker Punch's logger is set to Rails.logger by default.
146
97
 
147
- # app/workers/email_worker.rb
148
- class EmailWorker
149
- include SuckerPunch::Worker
98
+ ## Testing
150
99
 
151
- def perform(email, user_id)
152
- user = User.find(user_id)
153
- UserMailer.send(email.to_sym, user)
154
- end
155
- end
156
-
157
- # spec/models/user.rb
158
- class User < ActiveRecord::Base
159
- def send_welcome_email
160
- SuckerPunch::Queue.new(:email).async.perform(:welcome, self.id)
161
- end
162
- end
163
-
164
- # spec/models/user_spec.rb
165
- require 'spec_helper'
166
-
167
- describe User do
168
- describe "#send_welcome_email" do
169
- user = FactoryGirl.create(:user)
170
- expect{
171
- user.send_welcome_email
172
- }.to change{ SuckerPunch::Queue.new(:email).jobs.size }.by(1)
173
- end
174
- end
175
- ```
100
+ Requiring this library causes your jobs to run everything inline. So a call to the following will actually be SYNCHRONOUS:
176
101
 
177
102
  ```Ruby
178
103
  # spec/spec_helper.rb
179
104
  require 'sucker_punch/testing/inline'
180
105
  ```
181
106
 
182
- Requiring this library causes your workers to run everything inline. So a call to the following will actually be SYNCHRONOUS.
183
-
184
107
  ```Ruby
185
- SuckerPunch::Queue[:log_queue].async.perform("login")
108
+ Log.new.async.perform("login") # => Will be synchronous and block until job is finished
186
109
  ```
187
110
 
188
111
  ## Troubleshooting
189
112
 
190
- If you're running tests in transactions (using DatabaseCleaner or a native solution), Sucker Punch workers may have trouble finding database records that were created during test setup because the worker class is running in a separate thread and the Transaction operates on a different thread so it clears out the data before the worker can do its business. The best thing to do is cleanup data created for tests workers through a truncation strategy by tagging the rspec tests as workers and then specifying the strategy in `spec_helper` like below:
113
+ If you're running tests in transactions (using DatabaseCleaner or a native solution), Sucker Punch jobs may have trouble finding database records that were created during test setup because the job class is running in a separate thread and the Transaction operates on a different thread so it clears out the data before the jojob can do its business. The best thing to do is cleanup data created for tests jobs through a truncation strategy by tagging the rspec tests as jobs and then specifying the strategy in `spec_helper` like below:
191
114
 
192
115
  ```Ruby
193
116
  # spec/spec_helper.rb
@@ -196,8 +119,8 @@ RSpec.configure do |config|
196
119
  DatabaseCleaner.strategy = :transaction
197
120
  end
198
121
 
199
- # Clean up all worker specs with truncation
200
- config.before(:each, :worker => true) do
122
+ # Clean up all jobs specs with truncation
123
+ config.before(:each, :job => true) do
201
124
  DatabaseCleaner.strategy = :truncation
202
125
  end
203
126
 
@@ -209,49 +132,23 @@ RSpec.configure do |config|
209
132
  DatabaseCleaner.clean
210
133
  end
211
134
 
212
- # spec/workers/email_worker_spec.rb
135
+ # spec/jobs/email_job_spec.rb
213
136
  require 'spec_helper'
214
137
 
215
- # Tag the spec as a worker spec so data is persisted long enough for the test
216
- describe EmailWorker, worker: true do
138
+ # Tag the spec as a job spec so data is persisted long enough for the test
139
+ describe EmailJob, job: true do
217
140
  describe "#perform" do
218
141
  let(:user) { FactoryGirl.create(:user) }
219
142
 
220
143
  it "delivers an email" do
221
144
  expect {
222
- EmailWorker.new.perform(user.id)
145
+ EmailJob.new.perform(user.id)
223
146
  }.to change{ ActionMailer::Base.deliveries.size }.by(1)
224
147
  end
225
148
  end
226
149
  end
227
150
  ```
228
151
 
229
- When using Passenger or Unicorn, you should configure the queues within a block that runs after the child process is forked.
230
-
231
- ```Ruby
232
- # config/unicorn.rb
233
- #
234
- # The following is only need if in your unicorn config
235
- # you set:
236
- # preload_app true
237
- after_fork do |server, worker|
238
- SuckerPunch.config do
239
- queue name: :log_queue, worker: LogWorker, workers: 10
240
- end
241
- end
242
- ```
243
- ```Ruby
244
- # config/initializers/sucker_punch.rb
245
- #
246
- if defined?(PhusionPassenger)
247
- PhusionPassenger.on_event(:starting_worker_process) do |forked|
248
- SuckerPunch.config do
249
- queue name: :log_queue, worker: LogWorker, workers: 10
250
- end
251
- end
252
- end
253
- ```
254
-
255
152
  ## Gem Name
256
153
 
257
154
  ...is awesome. But I can't take credit for it. Thanks to [@jmazzi](https://twitter.com/jmazzi) for his superior naming skills. If you're looking for a name for something, he is the one to go to.
@@ -1,26 +1,11 @@
1
1
  require 'celluloid'
2
- require 'sucker_punch/exceptions'
2
+ require 'sucker_punch/core_ext'
3
+ require 'sucker_punch/job'
3
4
  require 'sucker_punch/queue'
4
- require 'sucker_punch/worker'
5
+ require 'sucker_punch/queues'
5
6
  require 'sucker_punch/version'
6
7
 
7
8
  module SuckerPunch
8
- def self.config(&block)
9
- instance_eval &block
10
- end
11
-
12
- def self.queue(options = {})
13
- raise MissingQueueName unless options[:name]
14
- raise MissingWorkerName unless options[:worker]
15
-
16
- klass = options.fetch(:worker)
17
- registry_name = options.fetch(:name)
18
- workers = options.fetch(:workers, nil)
19
-
20
- q = Queue.new(registry_name)
21
- q.register(klass, workers)
22
- end
23
-
24
9
  def self.logger
25
10
  Celluloid.logger
26
11
  end
@@ -0,0 +1,9 @@
1
+ class String
2
+ def underscore
3
+ self.gsub(/::/, '/').
4
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
6
+ tr("-", "_").
7
+ downcase
8
+ end
9
+ end if !defined?(::ActiveSupport) && !"".respond_to?(:underscore)
@@ -0,0 +1,21 @@
1
+ module SuckerPunch
2
+ module Job
3
+ def self.included(base)
4
+ base.send(:include, ::Celluloid)
5
+ base.extend(ClassMethods)
6
+
7
+ base.class_eval do
8
+ def self.new
9
+ define_celluloid_pool(self)
10
+ end
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def define_celluloid_pool(klass)
16
+ SuckerPunch::Queue.new(klass).register
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -1,36 +1,54 @@
1
+ require 'thread'
2
+
1
3
  module SuckerPunch
2
4
  class Queue
3
- attr_reader :name
5
+ attr_reader :klass
6
+ attr_accessor :pool
7
+
8
+ def self.find(klass)
9
+ queue = self.new(klass)
10
+ Celluloid::Actor[queue.name]
11
+ end
12
+
13
+ def initialize(klass)
14
+ @klass = klass
15
+ @pool = nil
16
+ @mutex = Mutex.new
17
+ end
4
18
 
5
- def initialize(name)
6
- @name = name
19
+ def register
20
+ @mutex.synchronize {
21
+ unless registered?
22
+ initialize_celluloid_pool
23
+ register_celluloid_pool
24
+ register_queue_with_master_list
25
+ end
26
+ }
27
+ self.class.find(klass)
7
28
  end
8
29
 
9
- def self.[](name)
10
- Celluloid::Actor[name]
30
+ def registered?
31
+ SuckerPunch::Queues.all.include?(name)
11
32
  end
12
33
 
13
- def register(klass, size)
14
- opts = {}
15
- opts[:size] = size if size
16
- Celluloid::Actor[name] = klass.send(:pool, opts)
34
+ def name
35
+ klass.to_s.underscore.to_sym
17
36
  end
18
37
 
19
- # Equivalent to size of the Celluloid Pool
20
- # However, in context of a "queue" workers
21
- # makes more sense here
22
- def workers
23
- Celluloid::Actor[name].size
38
+ private
39
+
40
+ def initialize_celluloid_pool
41
+ self.pool = klass.send(:pool)
24
42
  end
25
43
 
26
- # Equivalent to number of messages queued
27
- # in the Celluloid mailbox
28
- def size
29
- Celluloid::Actor[name].mailbox.size
44
+ def register_celluloid_pool
45
+ Celluloid::Actor[name] = pool
30
46
  end
31
47
 
32
- def method_missing(method_name, *args, &block)
33
- Celluloid::Actor[name].send(method_name, *args, &block)
48
+ def register_queue_with_master_list
49
+ SuckerPunch::Queues.register(name)
34
50
  end
35
51
  end
36
52
  end
53
+
54
+
@@ -0,0 +1,14 @@
1
+ module SuckerPunch
2
+ class Queues
3
+ @queues = Set.new
4
+
5
+ def self.all
6
+ @queues.to_a
7
+ end
8
+
9
+ def self.register(name)
10
+ @queues.add(name)
11
+ end
12
+ end
13
+ end
14
+
@@ -5,4 +5,3 @@ module Celluloid
5
5
  end
6
6
  end
7
7
  end
8
-
@@ -1,3 +1,3 @@
1
1
  module SuckerPunch
2
- VERSION = "0.5.1"
2
+ VERSION = "1.0.0.beta"
3
3
  end
@@ -4,3 +4,10 @@ rescue LoadError
4
4
  end
5
5
 
6
6
  require 'sucker_punch'
7
+
8
+ RSpec.configure do |config|
9
+ config.after(:each) do
10
+ # Clean up the master queue list
11
+ SuckerPunch::Queues.instance_variable_set(:@queues, Set.new)
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+
3
+ describe "Core extensions" do
4
+ describe String do
5
+ before :each do
6
+ class FakeQueue; end
7
+ end
8
+
9
+ it "underscores a class name" do
10
+ expect(FakeQueue.to_s.underscore).to eq("fake_queue")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe SuckerPunch::Job do
4
+ before :each do
5
+ class ::FakeJob
6
+ include SuckerPunch::Job
7
+
8
+ def perform(name)
9
+ "response #{name}"
10
+ end
11
+ end
12
+ end
13
+
14
+ it "includes Celluloid into requesting class when included" do
15
+ FakeJob.should respond_to(:pool)
16
+ end
17
+
18
+ describe "#perform" do
19
+ context "when pool hasn't been created" do
20
+ it "creates pool and registers queue" do
21
+ expect(Celluloid::Actor[:fake_job]).to eq(nil)
22
+ expect(SuckerPunch::Queues.all).to eq([])
23
+
24
+ # Don't use #async here b/c of a race condition
25
+ # The expectation will run before the asynchronous
26
+ # job is executed
27
+ FakeJob.new.perform("test")
28
+
29
+ expect(Celluloid::Actor[:fake_job]).to be
30
+ expect(SuckerPunch::Queues.all).to eq([:fake_job])
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,53 +1,53 @@
1
1
  require 'spec_helper'
2
2
 
3
- class FakeWorker
4
- include Celluloid
5
- end
6
-
7
3
  describe SuckerPunch::Queue do
8
- describe ".[]" do
9
- it "delegates to Celluloid" do
10
- Celluloid::Actor[:fake] = FakeWorker.pool
11
- Celluloid::Actor.should_receive(:[]).with(:fake)
12
- SuckerPunch::Queue[:fake]
4
+ before :each do
5
+ class ::FakeJob
6
+ include SuckerPunch::Job
7
+
8
+ def perform(name)
9
+ "response #{name}"
10
+ end
13
11
  end
14
12
  end
15
13
 
16
- describe "#register" do
17
- before(:each) do
18
- SuckerPunch::Queue.new(:crazy_queue).register(FakeWorker, 2)
14
+ describe "#find" do
15
+ it "returns the Celluloid Actor from the registry" do
16
+ SuckerPunch::Queue.new(FakeJob).register
17
+ queue = SuckerPunch::Queue.find(FakeJob)
18
+ queue.class == Celluloid::PoolManager
19
19
  end
20
+ end
20
21
 
21
- it "turns the class into an actor" do
22
- Celluloid::Actor[:crazy_queue].should be_a(Celluloid)
23
- Celluloid::Actor[:crazy_queue].should be_a(FakeWorker)
24
- Celluloid::Actor[:crazy_queue].methods.should include(:async)
22
+ describe "#register" do
23
+ let(:job) { FakeJob }
24
+ let(:queue) { SuckerPunch::Queue.new(job) }
25
+
26
+ it "initializes a celluloid pool" do
27
+ queue.register
28
+ expect(queue.pool.class).to eq(Celluloid::PoolManager)
25
29
  end
26
30
 
27
- it "sets worker size" do
28
- Celluloid::Actor[:crazy_queue].size.should == 2
31
+ it "registers the pool with Celluloid" do
32
+ pool = queue.register
33
+ expect(Celluloid::Actor[:fake_job]).to eq(pool)
29
34
  end
30
- end
31
35
 
32
- describe "#workers" do
33
- it "returns number of workers" do
34
- SuckerPunch::Queue.new(:crazy_queue).register(FakeWorker, 2)
35
- SuckerPunch::Queue.new(:crazy_queue).workers.should == 2
36
+ it "registers with master list of queues" do
37
+ queue.register
38
+ queues = SuckerPunch::Queues.all
39
+ expect(queues.size).to be(1)
36
40
  end
37
41
  end
38
42
 
39
- describe "delegation" do
40
- let(:queue) { SuckerPunch::Queue.new(:crazy_queue) }
43
+ describe "#registered?" do
44
+ it "returns true if queue has already been registered" do
45
+ queue = SuckerPunch::Queue.new(FakeJob)
41
46
 
42
- before(:each) do
43
- SuckerPunch::Queue.new(:crazy_queue).register(FakeWorker, 2)
44
- end
45
-
46
- it "sends messages to Actor" do
47
- queue.workers.should == 2
48
- queue.idle_size.should == 2
49
- queue.busy_size.should == 0
50
- queue.size.should == 0
47
+ expect{
48
+ queue.register
49
+ }.to change{ queue.registered? }.from(false).to(true)
51
50
  end
52
51
  end
53
52
  end
53
+
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe SuckerPunch::Queues do
4
+ describe "queue registration and querying" do
5
+ it "adds a queue to the master queue list" do
6
+ SuckerPunch::Queues.register(:fake)
7
+ expect(SuckerPunch::Queues.all).to eq([:fake])
8
+ end
9
+ end
10
+
11
+ describe ".registered?" do
12
+ it "returns true if queue has already been registered" do
13
+ SuckerPunch::Queues.register(:fake)
14
+ expect{ SuckerPunch::Queues.registered?(:fake) }.to be_true
15
+ end
16
+ end
17
+ end
@@ -1,20 +1,18 @@
1
1
  require 'spec_helper'
2
2
  require_relative '../../../lib/sucker_punch/testing/inline'
3
3
 
4
- class PatchedWorker
5
- include SuckerPunch::Worker
6
-
7
- def perform
8
- "do stuff"
9
- end
10
- end
11
- SuckerPunch::Queue.new(:patched_queue).register(PatchedWorker, 2)
12
-
13
4
  describe "SuckerPunch Inline Testing" do
14
- let(:queue) { SuckerPunch::Queue.new(:patched_queue) }
5
+ before :each do
6
+ class PatchedJob
7
+ def perform
8
+ "do stuff"
9
+ end
10
+ include SuckerPunch::Job
11
+ end
12
+ end
15
13
 
16
14
  it "processes jobs inline" do
17
- job = queue.async.perform
15
+ job = PatchedJob.new.async.perform
18
16
  expect(job).to eq "do stuff"
19
17
  end
20
18
  end
@@ -1,44 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- class FakeWorker
4
- include Celluloid
5
- end
6
-
7
3
  describe SuckerPunch do
8
- context "config" do
9
-
10
- context "properly configured" do
11
- it "registers the queue" do
12
- SuckerPunch::Queue.any_instance.should_receive(:register).with(FakeWorker, 3)
13
-
14
- SuckerPunch.config do
15
- queue name: :crazy_queue, worker: FakeWorker, workers: 3
16
- end
17
- end
18
- end
19
-
20
- context "with no queue name" do
21
- it "raises an exception" do
22
- expect {
23
- SuckerPunch.config do
24
- queue worker: FakeWorker
25
- end
26
- }.to raise_error(SuckerPunch::MissingQueueName)
27
- end
28
- end
29
-
30
- context "with no worker name" do
31
- it "raises an exception" do
32
- expect {
33
- SuckerPunch.config do
34
- queue name: :fake
35
- end
36
- }.to raise_error(SuckerPunch::MissingWorkerName)
37
- end
38
- end
39
-
40
- end
41
-
42
4
  describe 'logger' do
43
5
  it "delegates get to Celluloid's logger" do
44
6
  SuckerPunch.logger.should == Celluloid.logger
@@ -19,6 +19,7 @@ Gem::Specification.new do |gem|
19
19
 
20
20
  gem.add_development_dependency "rspec"
21
21
  gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "pry"
22
23
 
23
24
  gem.add_dependency "celluloid", "~> 0.14.1"
24
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sucker_punch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 1.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Hilkert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-14 00:00:00.000000000 Z
11
+ date: 2013-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: celluloid
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -67,18 +81,19 @@ files:
67
81
  - README.md
68
82
  - Rakefile
69
83
  - lib/sucker_punch.rb
70
- - lib/sucker_punch/exceptions.rb
84
+ - lib/sucker_punch/core_ext.rb
85
+ - lib/sucker_punch/job.rb
71
86
  - lib/sucker_punch/queue.rb
87
+ - lib/sucker_punch/queues.rb
72
88
  - lib/sucker_punch/railtie.rb
73
- - lib/sucker_punch/testing.rb
74
89
  - lib/sucker_punch/testing/inline.rb
75
90
  - lib/sucker_punch/version.rb
76
- - lib/sucker_punch/worker.rb
77
91
  - spec/spec_helper.rb
92
+ - spec/sucker_punch/core_ext_spec.rb
93
+ - spec/sucker_punch/job_spec.rb
78
94
  - spec/sucker_punch/queue_spec.rb
95
+ - spec/sucker_punch/queues_spec.rb
79
96
  - spec/sucker_punch/testing/inline_spec.rb
80
- - spec/sucker_punch/testing_spec.rb
81
- - spec/sucker_punch/worker_spec.rb
82
97
  - spec/sucker_punch_spec.rb
83
98
  - sucker_punch.gemspec
84
99
  homepage: https://github.com/brandonhilkert/sucker_punch
@@ -95,9 +110,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
95
110
  version: '0'
96
111
  required_rubygems_version: !ruby/object:Gem::Requirement
97
112
  requirements:
98
- - - '>='
113
+ - - '>'
99
114
  - !ruby/object:Gem::Version
100
- version: '0'
115
+ version: 1.3.1
101
116
  requirements: []
102
117
  rubyforge_project:
103
118
  rubygems_version: 2.0.2
@@ -107,8 +122,9 @@ summary: Sucker Punch is a Ruby asynchronous processing using Celluloid, heavily
107
122
  by Sidekiq and girl_friday.
108
123
  test_files:
109
124
  - spec/spec_helper.rb
125
+ - spec/sucker_punch/core_ext_spec.rb
126
+ - spec/sucker_punch/job_spec.rb
110
127
  - spec/sucker_punch/queue_spec.rb
128
+ - spec/sucker_punch/queues_spec.rb
111
129
  - spec/sucker_punch/testing/inline_spec.rb
112
- - spec/sucker_punch/testing_spec.rb
113
- - spec/sucker_punch/worker_spec.rb
114
130
  - spec/sucker_punch_spec.rb
@@ -1,5 +0,0 @@
1
- module SuckerPunch
2
- class Error < StandardError; end
3
- class MissingQueueName < Error; end
4
- class MissingWorkerName < Error; end
5
- end
@@ -1,44 +0,0 @@
1
- module SuckerPunch
2
- class << self
3
- attr_accessor :queues
4
-
5
- def reset!
6
- self.queues = {}
7
- end
8
- end
9
-
10
- SuckerPunch.reset!
11
-
12
- class Queue
13
- attr_reader :name
14
-
15
- def initialize(name)
16
- @name = name
17
- SuckerPunch.queues[name] ||= []
18
- end
19
-
20
- def self.[](name)
21
- new(name)
22
- end
23
-
24
- def register(klass, size)
25
- nil
26
- end
27
-
28
- def workers
29
- raise "Not implemented"
30
- end
31
-
32
- def jobs
33
- SuckerPunch.queues[@name]
34
- end
35
-
36
- def async
37
- self
38
- end
39
-
40
- def method_missing(name, *args, &block)
41
- SuckerPunch.queues[@name] << { method: name, args: Array(args) }
42
- end
43
- end
44
- end
@@ -1,7 +0,0 @@
1
- module SuckerPunch
2
- module Worker
3
- def self.included(base)
4
- base.send :include, ::Celluloid
5
- end
6
- end
7
- end
@@ -1,88 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class TestingWorker
4
- include Celluloid
5
-
6
- def perform(input)
7
- input = "after"
8
- end
9
- end
10
-
11
- SuckerPunch.config do
12
- queue name: :queue, worker: TestingWorker
13
- end
14
-
15
- describe "SuckerPunch Testing" do
16
- before :each do
17
- require_relative '../../lib/sucker_punch/testing'
18
- SuckerPunch.reset!
19
- end
20
-
21
- describe ".reset!" do
22
- it "resets the queues to be empty" do
23
- 4.times { SuckerPunch::Queue.new(:queue).async.perform("before") }
24
- SuckerPunch.reset!
25
- queue = SuckerPunch::Queue.new(:queue)
26
- expect(queue.jobs.count).to eq 0
27
- end
28
- end
29
-
30
- describe Queue do
31
- it "returns previous instance when queried again" do
32
- queue = SuckerPunch::Queue.new(:queue)
33
- queue.async.perform("before")
34
- expect(SuckerPunch::Queue.new(:queue).jobs.count).to eq 1
35
- end
36
-
37
- describe ".[]" do
38
- it "returns the queue instance" do
39
- queue = SuckerPunch::Queue.new(:queue)
40
- queue.async.perform("before")
41
- expect(SuckerPunch::Queue[:queue].jobs.count).to eq 1
42
- end
43
- end
44
-
45
- describe "#register" do
46
- it "returns nil" do
47
- queue = SuckerPunch::Queue.new(:queue)
48
- expect(queue.register(TestingWorker, 3)).to eq nil
49
- end
50
- end
51
-
52
- describe "#workers" do
53
- it "raises an exception if called" do
54
- queue = SuckerPunch::Queue.new(:queue)
55
- expect{ queue.workers }.to raise_error "Not implemented"
56
- end
57
- end
58
-
59
- describe "#jobs" do
60
- it "returns an array of the jobs in the queue" do
61
- queue = SuckerPunch::Queue.new(:queue)
62
- queue.async.perform("before")
63
- expect(queue.jobs).to eq [{ method: :perform, args: ["before"] }]
64
- end
65
-
66
- it "returns the number of jobs in the queue" do
67
- queue = SuckerPunch::Queue.new(:queue)
68
- 4.times { queue.async.perform("before") }
69
- expect(queue.jobs.count).to eq 4
70
- end
71
- end
72
-
73
- describe "#async" do
74
- it "returns self" do
75
- queue = SuckerPunch::Queue.new(:queue)
76
- expect(queue.async).to eq queue
77
- end
78
- end
79
-
80
- describe "enqueueing a job" do
81
- it "adds the job to the queue" do
82
- queue = SuckerPunch::Queue.new(:queue)
83
- queue.async.perform("before")
84
- expect(queue.jobs).to eq [{ method: :perform, args: ["before"] }]
85
- end
86
- end
87
- end
88
- end
@@ -1,15 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class FakeWorker
4
- include SuckerPunch::Worker
5
-
6
- def perform
7
- puts "do stuff"
8
- end
9
- end
10
-
11
- describe SuckerPunch::Worker do
12
- it "should include Celluloid into requesting class when included" do
13
- FakeWorker.should respond_to(:pool)
14
- end
15
- end