sucker_punch 0.5.1 → 1.0.0.beta

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.
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