qe 0.2.0 → 0.2.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.
@@ -1,53 +1,53 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- qe (0.2.0)
4
+ qe (0.2.1)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
8
8
  specs:
9
- activemodel (3.2.9)
10
- activesupport (= 3.2.9)
9
+ activemodel (3.2.11)
10
+ activesupport (= 3.2.11)
11
11
  builder (~> 3.0.0)
12
- activerecord (3.2.9)
13
- activemodel (= 3.2.9)
14
- activesupport (= 3.2.9)
12
+ activerecord (3.2.11)
13
+ activemodel (= 3.2.11)
14
+ activesupport (= 3.2.11)
15
15
  arel (~> 3.0.2)
16
16
  tzinfo (~> 0.3.29)
17
- activesupport (3.2.9)
17
+ activesupport (3.2.11)
18
18
  i18n (~> 0.6)
19
19
  multi_json (~> 1.0)
20
20
  arel (3.0.2)
21
21
  awesome_print (1.1.0)
22
- backburner (0.3.0)
23
- beaneater (~> 0.2.0)
22
+ backburner (0.3.2)
23
+ beaneater (~> 0.3.0)
24
24
  dante (~> 0.1.5)
25
- beaneater (0.2.0)
25
+ beaneater (0.3.0)
26
26
  builder (3.0.4)
27
- celluloid (0.12.3)
27
+ celluloid (0.12.4)
28
28
  facter (>= 1.6.12)
29
29
  timers (>= 1.0.0)
30
30
  coderay (1.0.8)
31
- connection_pool (0.9.2)
31
+ connection_pool (1.0.0)
32
32
  dante (0.1.5)
33
- delayed_job (3.0.4)
33
+ delayed_job (3.0.5)
34
34
  activesupport (~> 3.0)
35
35
  delayed_job_active_record (0.3.3)
36
36
  activerecord (>= 2.1.0, < 4)
37
37
  delayed_job (~> 3.0)
38
38
  diff-lcs (1.1.3)
39
- facter (1.6.14)
39
+ facter (1.6.17)
40
40
  i18n (0.6.1)
41
41
  method_source (0.8.1)
42
- multi_json (1.3.7)
43
- pry (0.9.10)
42
+ multi_json (1.5.0)
43
+ pry (0.9.11.4)
44
44
  coderay (~> 1.0.5)
45
45
  method_source (~> 0.8)
46
- slop (~> 3.3.1)
46
+ slop (~> 3.4)
47
47
  qu (0.2.0)
48
48
  multi_json
49
- rack (1.4.1)
50
- rack-protection (1.2.0)
49
+ rack (1.5.1)
50
+ rack-protection (1.3.2)
51
51
  rack
52
52
  redis (3.0.2)
53
53
  redis-namespace (1.2.1)
@@ -57,28 +57,34 @@ GEM
57
57
  redis-namespace (~> 1.0)
58
58
  sinatra (>= 0.9.2)
59
59
  vegas (~> 0.1.2)
60
+ resque-scheduler (2.0.0)
61
+ redis (>= 2.0.1)
62
+ resque (>= 1.20.0)
63
+ rufus-scheduler
60
64
  rspec (2.12.0)
61
65
  rspec-core (~> 2.12.0)
62
66
  rspec-expectations (~> 2.12.0)
63
67
  rspec-mocks (~> 2.12.0)
64
- rspec-core (2.12.0)
65
- rspec-expectations (2.12.0)
68
+ rspec-core (2.12.2)
69
+ rspec-expectations (2.12.1)
66
70
  diff-lcs (~> 1.1.3)
67
- rspec-mocks (2.12.0)
68
- sidekiq (2.5.3)
71
+ rspec-mocks (2.12.2)
72
+ rufus-scheduler (2.0.17)
73
+ tzinfo (>= 0.3.23)
74
+ sidekiq (2.6.5)
69
75
  celluloid (~> 0.12.0)
70
- connection_pool (~> 0.9.2)
76
+ connection_pool (~> 1.0)
71
77
  multi_json (~> 1)
72
78
  redis (~> 3)
73
79
  redis-namespace
74
- sinatra (1.3.3)
75
- rack (~> 1.3, >= 1.3.6)
76
- rack-protection (~> 1.2)
80
+ sinatra (1.3.4)
81
+ rack (~> 1.4)
82
+ rack-protection (~> 1.3)
77
83
  tilt (~> 1.3, >= 1.3.3)
78
- slop (3.3.3)
79
- sqlite3 (1.3.6)
84
+ slop (3.4.3)
85
+ sqlite3 (1.3.7)
80
86
  tilt (1.3.3)
81
- timers (1.0.1)
87
+ timers (1.1.0)
82
88
  tzinfo (0.3.35)
83
89
  vegas (0.1.11)
84
90
  rack (>= 1.0.0)
@@ -95,6 +101,7 @@ DEPENDENCIES
95
101
  qe!
96
102
  qu
97
103
  resque
104
+ resque-scheduler
98
105
  rspec
99
106
  sidekiq
100
107
  sqlite3
data/README.md CHANGED
@@ -75,6 +75,17 @@ MailerWorker.enqueue({
75
75
  })
76
76
  ```
77
77
 
78
+ You can specify when this job must be processed by setting the <tt>:run_at</tt> option.
79
+
80
+ ``` ruby
81
+ MailerWorker.enqueue({
82
+ :mail => :follow_up,
83
+ :email => "john@example.org",
84
+ :name => "John Doe",
85
+ :run_at => 5.days.from_now
86
+ })
87
+ ```
88
+
78
89
  ### Defining actions
79
90
 
80
91
  Sometimes you want to create several actions in a single worker, just because is easier. Instead of manually dispatch the action on your perform method, you can
@@ -109,6 +120,23 @@ NotificationWorker.enqueue(:message => "wat?")
109
120
 
110
121
  The action must be a existing public method. If not defined, `Qe::Action::MissingActionError` exception is raised.
111
122
 
123
+ ### Working with I18n
124
+
125
+ When you're working in internationalized app, you need to perform some jobs with the correct locale set (sending an e-mail, maybe?). Instead of doing it manually, you can just use the `Qe::Locale` extension.
126
+
127
+ This extension will set the `:locale` option when you enqueue some job and set it to `I18n.locale` when you perform it. Just include it after the `Qe::Worker` module.
128
+
129
+ ``` ruby
130
+ class MailerWorker
131
+ include Qe::Worker
132
+ include Qe::Locale
133
+
134
+ def perform
135
+ Mailer.public_send(options[:mail], options).deliver
136
+ end
137
+ end
138
+ ```
139
+
112
140
  ### Development support
113
141
 
114
142
  Qe comes with development support. Instead of starting up workers on development environment, you can use the `Qe::Immediate` adapter, which executes your worker right away!
@@ -130,7 +158,7 @@ require "qe/testing"
130
158
  Qe.adapter = Qe::Testing
131
159
  ```
132
160
 
133
- If you"re using RSpec, you can require the `qe/testing/rspec.rb` file
161
+ If you are using RSpec, you can require the `qe/testing/rspec.rb` file
134
162
  instead. This will reset `Qe.jobs` before every spec and will add a
135
163
  `enqueue` matcher.
136
164
 
@@ -1,3 +1,4 @@
1
- QUEUES="mail,default"
2
- QUEUE="mail,default"
1
+ QUEUE="later,mail,default"
2
+ QUEUES="later,mail,default"
3
3
  BEANSTALK_URL="beanstalk://localhost/"
4
+ GROUP=delayed_job
@@ -1,14 +1,35 @@
1
1
  source :rubygems
2
2
 
3
- gem "sidekiq"
4
- gem "backburner"
5
- gem "beanstalkd_view"
6
3
  gem "rake"
7
4
  gem "thin"
8
- gem "resque"
9
- gem "activerecord"
10
- gem "delayed_job_active_record"
11
- gem "sqlite3"
12
5
  gem "daemons"
13
- gem "qu-redis"
14
- gem "slim"
6
+ gem "pry"
7
+ gem "pry-remote"
8
+ gem "awesome_print"
9
+
10
+ group :sidekiq do
11
+ gem "activesupport", :require => "active_support/all"
12
+ gem "sidekiq"
13
+ gem "slim"
14
+ end
15
+
16
+ group :resque do
17
+ gem "resque"
18
+ gem "resque-scheduler"
19
+ end
20
+
21
+ group :beanstalk do
22
+ gem "backburner"
23
+ gem "beanstalkd_view"
24
+ end
25
+
26
+ group :delayed_job do
27
+ gem "activerecord"
28
+ gem "delayed_job_active_record"
29
+ gem "delayed_job_web"
30
+ gem "sqlite3"
31
+ end
32
+
33
+ group :qu do
34
+ gem "qu-redis"
35
+ end
@@ -1,25 +1,27 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- activemodel (3.2.8)
5
- activesupport (= 3.2.8)
4
+ activemodel (3.2.9)
5
+ activesupport (= 3.2.9)
6
6
  builder (~> 3.0.0)
7
- activerecord (3.2.8)
8
- activemodel (= 3.2.8)
9
- activesupport (= 3.2.8)
7
+ activerecord (3.2.9)
8
+ activemodel (= 3.2.9)
9
+ activesupport (= 3.2.9)
10
10
  arel (~> 3.0.2)
11
11
  tzinfo (~> 0.3.29)
12
- activesupport (3.2.8)
12
+ activesupport (3.2.9)
13
13
  i18n (~> 0.6)
14
14
  multi_json (~> 1.0)
15
15
  arel (3.0.2)
16
- backburner (0.2.0)
17
- beaneater (~> 0.1.2)
16
+ awesome_print (1.1.0)
17
+ backburner (0.3.0)
18
+ beaneater (~> 0.2.0)
18
19
  dante (~> 0.1.5)
19
20
  backports (2.6.5)
20
- beaneater (0.1.2)
21
- beanstalkd_view (1.1.0)
22
- beaneater (~> 0.1.0)
21
+ beaneater (0.2.2)
22
+ beanstalk-client (1.1.1)
23
+ beanstalkd_view (1.0.2)
24
+ beanstalk-client (>= 1.1.1)
23
25
  json
24
26
  sinatra (>= 1.3.0)
25
27
  sinatra-assetpack (>= 0.0.11)
@@ -29,20 +31,36 @@ GEM
29
31
  celluloid (0.12.3)
30
32
  facter (>= 1.6.12)
31
33
  timers (>= 1.0.0)
34
+ coderay (1.0.8)
32
35
  connection_pool (0.9.2)
33
36
  daemons (1.1.9)
34
37
  dante (0.1.5)
35
- delayed_job (3.0.3)
38
+ delayed_job (3.0.4)
36
39
  activesupport (~> 3.0)
37
40
  delayed_job_active_record (0.3.3)
38
41
  activerecord (>= 2.1.0, < 4)
39
42
  delayed_job (~> 3.0)
43
+ delayed_job_web (1.1.2)
44
+ activerecord (> 3.0.0)
45
+ delayed_job (> 2.0.3)
46
+ haml (~> 3.1.3)
47
+ rdoc
48
+ sinatra (>= 0.9.2)
40
49
  eventmachine (1.0.0)
41
- facter (1.6.14)
50
+ facter (1.6.16)
51
+ haml (3.1.7)
42
52
  i18n (0.6.1)
43
53
  jsmin (1.0.1)
44
54
  json (1.7.5)
45
- multi_json (1.3.7)
55
+ method_source (0.8.1)
56
+ multi_json (1.4.0)
57
+ pry (0.9.10)
58
+ coderay (~> 1.0.5)
59
+ method_source (~> 0.8)
60
+ slop (~> 3.3.1)
61
+ pry-remote (0.1.6)
62
+ pry (~> 0.9)
63
+ slop (~> 3.0)
46
64
  qu (0.2.0)
47
65
  multi_json
48
66
  qu-redis (0.2.0)
@@ -54,7 +72,9 @@ GEM
54
72
  rack
55
73
  rack-test (0.6.2)
56
74
  rack (>= 1.0)
57
- rake (0.9.2.2)
75
+ rake (10.0.2)
76
+ rdoc (3.12)
77
+ json (~> 1.4)
58
78
  redis (3.0.2)
59
79
  redis-namespace (1.2.1)
60
80
  redis (~> 3.0.0)
@@ -63,13 +83,19 @@ GEM
63
83
  redis-namespace (~> 1.0)
64
84
  sinatra (>= 0.9.2)
65
85
  vegas (~> 0.1.2)
66
- sidekiq (2.5.2)
86
+ resque-scheduler (2.0.0)
87
+ redis (>= 2.0.1)
88
+ resque (>= 1.20.0)
89
+ rufus-scheduler
90
+ rufus-scheduler (2.0.17)
91
+ tzinfo (>= 0.3.23)
92
+ sidekiq (2.5.4)
67
93
  celluloid (~> 0.12.0)
68
94
  connection_pool (~> 0.9.2)
69
95
  multi_json (~> 1)
70
96
  redis (~> 3)
71
97
  redis-namespace
72
- simple_uuid (0.2.0)
98
+ simple_uuid (0.3.0)
73
99
  sinatra (1.3.3)
74
100
  rack (~> 1.3, >= 1.3.6)
75
101
  rack-protection (~> 1.2)
@@ -86,9 +112,10 @@ GEM
86
112
  rack-test
87
113
  sinatra (~> 1.3.0)
88
114
  tilt (~> 1.3)
89
- slim (1.3.3)
115
+ slim (1.3.4)
90
116
  temple (~> 0.5.5)
91
117
  tilt (~> 1.3.3)
118
+ slop (3.3.3)
92
119
  sqlite3 (1.3.6)
93
120
  temple (0.5.5)
94
121
  thin (1.5.0)
@@ -106,13 +133,19 @@ PLATFORMS
106
133
 
107
134
  DEPENDENCIES
108
135
  activerecord
136
+ activesupport
137
+ awesome_print
109
138
  backburner
110
139
  beanstalkd_view
111
140
  daemons
112
141
  delayed_job_active_record
142
+ delayed_job_web
143
+ pry
144
+ pry-remote
113
145
  qu-redis
114
146
  rake
115
147
  resque
148
+ resque-scheduler
116
149
  sidekiq
117
150
  slim
118
151
  sqlite3
@@ -1,20 +1,25 @@
1
- redis: redis-server redis.conf
1
+ # redis: redis-server redis.conf
2
2
  # beanstalkd: beanstalkd
3
3
 
4
4
  # Uncomment the following lines to enable Sidekiq
5
- sidekiq: bundle exec sidekiq -r ./workers.rb -q default -q mail
6
- sidekiq_web: bundle exec thin -R sidekiq.ru -p 9292 -V start
5
+ # sidekiq: bundle exec sidekiq -r ./workers.rb -q default -q mail -q later
6
+ # sidekiq_web: bundle exec thin -R sidekiq.ru -p 9292 -V start
7
7
 
8
8
  # Uncomment the following lines to enable Beanstalk/Backburner
9
9
  # backburner: bundle exec rake backburner:work
10
10
  # beanstalkd_view: bundle exec thin -R beanstalkd.ru -p 9292 -V start
11
11
 
12
12
  # Uncomment the following line to enable DelayedJob
13
- # delayed_job: bundle exec rake jobs:work
13
+ delayed_job: bundle exec rake delayed_job
14
+ delayed_job_web: bundle exec thin -R delayed_job.ru -p 9292 -V start
14
15
 
15
16
  # Uncomment the following line to enable Qu
16
17
  # qu: bundle exec rake qu:work
17
18
 
18
19
  # Uncomment the following lines to enable Resque
19
20
  # resque: bundle exec rake resque:work
21
+ # resque_scheduler: bundle exec rake resque:scheduler
20
22
  # resque_web: bundle exec thin -R resque.ru -p 9292 -V start
23
+
24
+ # Add jobs every 3 seconds
25
+ add_jobs: ruby add_jobs.rb
@@ -1,9 +1,7 @@
1
1
  # Running examples
2
2
 
3
- 1. First, start processes with `$ foreman start`
4
- 2. Then execute `$ ruby sample.rb`
3
+ 1. Change the bundler group name on the `.env` file.
4
+ 2. Start processes with `$ foreman start`
5
5
  3. Go back to the Foreman's terminal and watch the output
6
6
 
7
- Tweak the `Procfile` to enable different libraries and web panels.
8
-
9
- You'll need to install Redis and/or Beanstalkd.
7
+ Tweak the `Procfile` and `.env` files to enable different libraries and web panels.
@@ -1,14 +1,15 @@
1
- require "backburner/tasks"
2
- require "resque/tasks"
3
- require "delayed/tasks"
4
- require "qu/tasks"
1
+ require "./workers"
5
2
 
6
3
  task :environment do #=> required by Backburner
7
- require "./workers"
8
4
 
9
- Backburner.configure do |config|
10
- config.logger = Logger.new(STDOUT)
11
- end
12
5
  end
13
6
 
14
7
  task "resque:setup" => :environment
8
+
9
+ desc "Setup delayed job consumer"
10
+ task :delayed_job do
11
+ ENV["QUEUES"] = "later,mail,default"
12
+ ENV.delete("QUEUE")
13
+ Rake::Task["jobs:work"].reenable
14
+ Rake::Task["jobs:work"].invoke
15
+ end
@@ -1,10 +1,9 @@
1
1
  require "./workers"
2
2
 
3
3
  loop do
4
- puts "=> Enqueuing jobs [#{Time.now}]"
5
-
6
4
  MailerWorker.enqueue(:name => "John Doe", :email => "john@example.org")
7
5
  ClockWorker.enqueue
6
+ LaterWorker.enqueue :run_at => Time.now + 5, :time => Time.now
8
7
 
9
8
  sleep 3
10
9
  end
@@ -1,5 +1,5 @@
1
1
  require "bundler"
2
- Bundler.setup(:default)
3
- Bundler.require(:default)
2
+ Bundler.setup(:default, :beanstalk)
3
+ Bundler.require(:default, :beanstalk)
4
4
 
5
5
  run BeanstalkdView::Server
@@ -0,0 +1,10 @@
1
+ require "bundler"
2
+ Bundler.setup(:default, :delayed_job)
3
+ Bundler.require(:default, :delayed_job)
4
+
5
+ ActiveRecord::Base.establish_connection(
6
+ :adapter => "sqlite3", :database => "jobs.sqlite3"
7
+ )
8
+
9
+ require "delayed_job_web"
10
+ run DelayedJobWeb
@@ -1,6 +1,6 @@
1
1
  require "bundler"
2
- Bundler.setup(:default)
3
- Bundler.require(:default)
2
+ Bundler.setup(:default, :resque)
3
+ Bundler.require(:default, :resque)
4
4
 
5
5
  require "resque/server"
6
6
  run Resque::Server
@@ -1,6 +1,6 @@
1
1
  require "bundler"
2
- Bundler.setup(:default)
3
- Bundler.require(:default)
2
+ Bundler.setup(:default, :sidekiq)
3
+ Bundler.require(:default, :sidekiq)
4
4
 
5
5
  Sidekiq.configure_client do |config|
6
6
  config.redis = { :size => 1 }
@@ -1,26 +1,53 @@
1
1
  require "bundler"
2
- Bundler.setup(:default)
2
+ Bundler.setup(:default, ENV.fetch("GROUP"))
3
3
  Bundler.require
4
4
 
5
+ require "time"
6
+
5
7
  $:.unshift File.expand_path("../../lib", __FILE__)
6
- require "qe"
7
8
 
8
- $stdout.sync = true
9
+ case ENV.fetch("GROUP")
10
+ when "sidekiq"
11
+ require "qe/sidekiq"
12
+ when "beanstalk"
13
+ require "qe/beanstalk"
14
+ require "backburner/tasks"
9
15
 
10
- Qe.adapter = Qe::Sidekiq
11
- # Qe.adapter = Qe::Beanstalk
12
- # Qe.adapter = Qe::Resque
13
- # Qe.adapter = Qe::DelayedJob
14
- # Qe.adapter = Qe::Qu
15
- # Qe.adapter = Qe::Testing
16
+ Backburner.configure do |config|
17
+ config.logger = Logger.new($stdout)
18
+ end
19
+ when "resque"
20
+ require "qe/resque"
21
+ require "resque/tasks"
22
+ require "resque_scheduler/tasks"
23
+ when "delayed_job"
24
+ require "delayed_job"
25
+ require "delayed_job_active_record"
26
+ require "qe/delayed_job"
27
+ require "active_record"
28
+ require "delayed/tasks"
29
+ when "qu"
30
+ require "qe/qu"
31
+ require "qu/tasks"
32
+ end
16
33
 
17
- ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "jobs.sqlite3")
34
+ $stdout.sync = true
35
+
36
+ if defined?(Qe::DelayedJob)
37
+ ActiveRecord::Base.establish_connection(
38
+ :adapter => "sqlite3", :database => "jobs.sqlite3"
39
+ )
40
+ end
18
41
 
19
42
  class ClockWorker
20
43
  include Qe::Worker
21
44
 
22
45
  def perform
46
+ puts
47
+ puts "---"
23
48
  puts "=> Time: #{Time.now}"
49
+ puts "---"
50
+ puts
24
51
  end
25
52
  end
26
53
 
@@ -29,6 +56,8 @@ class MailerWorker
29
56
  queue :mail
30
57
 
31
58
  def before
59
+ puts
60
+ puts "---"
32
61
  puts "=> Running before"
33
62
  end
34
63
 
@@ -39,5 +68,20 @@ class MailerWorker
39
68
 
40
69
  def after
41
70
  puts "=> Running after"
71
+ puts "---"
72
+ puts
73
+ end
74
+ end
75
+
76
+ class LaterWorker
77
+ include Qe::Worker
78
+
79
+ def perform
80
+ puts
81
+ puts "---"
82
+ puts "=> Job scheduled on #{options.inspect}"
83
+ puts "=> But executed on #{Time.now}"
84
+ puts "---"
85
+ puts
42
86
  end
43
87
  end
data/lib/qe.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require "qe/action"
2
+ require "qe/locale"
2
3
  require "qe/immediate"
3
4
  require "qe/version"
5
+ require "qe/worker/class_methods"
6
+ require "qe/worker/instance_methods"
4
7
  require "qe/worker"
5
8
 
6
9
  # In this wild world where a new asynchronous job processing
@@ -50,6 +53,16 @@ require "qe/worker"
50
53
  # :name => "John Doe"
51
54
  # })
52
55
  #
56
+ # You can specify when this job must be processed by setting the <tt>:run_at</tt>
57
+ # option.
58
+ #
59
+ # MailerWorker.enqueue({
60
+ # :mail => :follow_up,
61
+ # :email => "john@example.org",
62
+ # :name => "John Doe",
63
+ # :run_at => 5.days.from_now
64
+ # })
65
+ #
53
66
  # == Testing support
54
67
  #
55
68
  # Qe comes with testing support. Just require the <tt>qe/testing.rb</tt> file
@@ -77,4 +90,12 @@ module Qe
77
90
  class << self
78
91
  attr_accessor :adapter
79
92
  end
93
+
94
+ # Error that is raised when trying to use a feature
95
+ # that isn't supported by some adapter.
96
+ UnsupportedFeatureError = Class.new(StandardError)
97
+
98
+ # Error that is raised when trying to include a
99
+ # module before Qe::Worker is included.
100
+ OutOfOrderError = Class.new(StandardError)
80
101
  end
@@ -15,6 +15,12 @@ module Qe
15
15
  Worker.queue worker.queue
16
16
  Backburner.enqueue Worker, worker.name, options
17
17
  end
18
+
19
+ def self.schedule(worker, run_at, options = {})
20
+ delay = run_at - Time.now
21
+ Worker.queue worker.queue
22
+ Backburner::Worker.enqueue Worker, [worker.name, options], :delay => delay
23
+ end
18
24
  end
19
25
 
20
26
  self.adapter = Beanstalk
@@ -10,7 +10,14 @@ module Qe
10
10
  end
11
11
 
12
12
  def self.enqueue(worker, options = {})
13
- Delayed::Job.enqueue Worker.new(worker.name, options), :queue => worker.queue
13
+ Delayed::Job.enqueue Worker.new(worker.name, options),
14
+ :queue => worker.queue
15
+ end
16
+
17
+ def self.schedule(worker, run_at, options = {})
18
+ Delayed::Job.enqueue Worker.new(worker.name, options),
19
+ :queue => worker.queue,
20
+ :run_at => run_at
14
21
  end
15
22
  end
16
23
 
@@ -0,0 +1,29 @@
1
+ module Qe
2
+ module Locale
3
+ def self.included(base)
4
+ unless base.included_modules.include?(Qe::Worker)
5
+ raise OutOfOrderError, "must be included after Qe::Worker"
6
+ end
7
+
8
+ class << base
9
+ # Intercept <tt>Worker.enqueue</tt> method, adding
10
+ # the current locale to the options.
11
+ enqueue = instance_method(:enqueue)
12
+ define_method :enqueue do |options = {}|
13
+ options[:locale] = I18n.locale
14
+ enqueue.bind(self).call(options)
15
+ end
16
+ end
17
+
18
+ base.class_eval do
19
+ # Intercept <tt>Worker#before</tt> method, adding
20
+ # the setting the current locale.
21
+ before = instance_method(:before)
22
+ define_method :before do
23
+ I18n.locale = options.delete(:locale)
24
+ before.bind(self).call
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -4,8 +4,6 @@ require "qu"
4
4
  module Qe
5
5
  class Qu
6
6
  class Worker
7
- include ::Sidekiq::Worker
8
-
9
7
  def self.perform(*args)
10
8
  Qe::Worker.perform(*args)
11
9
  end
@@ -15,6 +13,10 @@ module Qe
15
13
  Worker.instance_variable_set("@queue", worker.queue)
16
14
  ::Qu.enqueue Worker, worker.name, options
17
15
  end
16
+
17
+ def self.schedule(*)
18
+ raise UnsupportedFeatureError, "scheduling isn't supported on Qu"
19
+ end
18
20
  end
19
21
 
20
22
  self.adapter = Qu
@@ -1,5 +1,6 @@
1
1
  require "qe"
2
2
  require "resque"
3
+ require "resque_scheduler"
3
4
 
4
5
  module Qe
5
6
  class Resque
@@ -13,6 +14,12 @@ module Qe
13
14
  Worker.instance_variable_set "@queue", worker.queue
14
15
  ::Resque.enqueue Worker, worker.name, options
15
16
  end
17
+
18
+ def self.schedule(worker, run_at, options = {})
19
+ Worker.instance_variable_set "@queue", worker.queue
20
+
21
+ ::Resque.enqueue_at(run_at, Worker, worker.name, options)
22
+ end
16
23
  end
17
24
 
18
25
  self.adapter = Resque
@@ -15,6 +15,11 @@ module Qe
15
15
  Worker.sidekiq_options :queue => worker.queue
16
16
  Worker.perform_async(worker.name, options)
17
17
  end
18
+
19
+ def self.schedule(worker, run_at, options = {})
20
+ Worker.sidekiq_options :queue => worker.queue
21
+ Worker.perform_at(run_at, worker.name, options)
22
+ end
18
23
  end
19
24
 
20
25
  self.adapter = Sidekiq
@@ -1,3 +1,3 @@
1
1
  module Qe
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -7,45 +7,6 @@ module Qe
7
7
  end
8
8
  end
9
9
 
10
- module InstanceMethods
11
- def initialize(options)
12
- @options = options
13
- end
14
-
15
- # Return options that were provided when
16
- # adding job to the queue.
17
- def options
18
- @options
19
- end
20
-
21
- # Set before hook.
22
- def before
23
- end
24
-
25
- # Set after hook.
26
- def after
27
- end
28
-
29
- # Set the error hook.
30
- def error(error)
31
- raise error
32
- end
33
- end
34
-
35
- module ClassMethods
36
- # Enqueue job on given worker class.
37
- def enqueue(options = {})
38
- Qe.adapter.enqueue(self, options)
39
- end
40
-
41
- # Set the queue name when receiving on argument.
42
- # Return queue name otherwise.
43
- def queue(*args)
44
- @queue = args.first unless args.empty?
45
- (@queue || :default).to_s
46
- end
47
- end
48
-
49
10
  # Find a worker by its name.
50
11
  # If worker constant is not found, raises a +NameError+
51
12
  # exception.
@@ -0,0 +1,23 @@
1
+ module Qe
2
+ module Worker
3
+ module ClassMethods
4
+ # Enqueue job on given worker class.
5
+ def enqueue(options = {})
6
+ run_at = options.delete(:run_at)
7
+
8
+ if run_at
9
+ Qe.adapter.schedule(self, run_at, options)
10
+ else
11
+ Qe.adapter.enqueue(self, options)
12
+ end
13
+ end
14
+
15
+ # Set the queue name when receiving on argument.
16
+ # Return queue name otherwise.
17
+ def queue(*args)
18
+ @queue = args.first unless args.empty?
19
+ (@queue || :default).to_s
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ module Qe
2
+ module Worker
3
+ module InstanceMethods
4
+ def initialize(options)
5
+ @options = options
6
+ end
7
+
8
+ # Return options that were provided when
9
+ # adding job to the queue.
10
+ def options
11
+ @options
12
+ end
13
+
14
+ # Set before hook.
15
+ def before
16
+ end
17
+
18
+ # Set after hook.
19
+ def after
20
+ end
21
+
22
+ # Set the error hook.
23
+ def error(error)
24
+ raise error
25
+ end
26
+ end
27
+ end
28
+ end
data/qe.gemspec CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency "delayed_job_active_record"
23
23
  s.add_development_dependency "backburner"
24
24
  s.add_development_dependency "resque"
25
+ s.add_development_dependency "resque-scheduler"
25
26
 
26
27
  s.add_development_dependency "activerecord"
27
28
  s.add_development_dependency "awesome_print"
@@ -42,4 +42,33 @@ describe Qe::Beanstalk do
42
42
  Qe::Beanstalk.enqueue(worker, :a => 1)
43
43
  end
44
44
  end
45
+
46
+ context "scheduling" do
47
+ let(:worker) {
48
+ mock("worker", :queue => "some_queue", :name => "SomeWorker")
49
+ }
50
+
51
+ let(:date) { Time.parse("2012-12-05 02:00:00") }
52
+
53
+ before do
54
+ Time.stub :now => date - 3600
55
+ Backburner::Worker.stub :enqueue
56
+ end
57
+
58
+ it "sets queue name" do
59
+ Qe::Beanstalk::Worker
60
+ .should_receive(:queue)
61
+ .with("some_queue")
62
+
63
+ Qe::Beanstalk.schedule(worker, date, :a => 1)
64
+ end
65
+
66
+ it "schedules job" do
67
+ ::Backburner::Worker
68
+ .should_receive(:enqueue)
69
+ .with(Qe::Beanstalk::Worker, ["SomeWorker", :a => 1], :delay => 3600)
70
+
71
+ Qe::Beanstalk.schedule(worker, date, :a => 1)
72
+ end
73
+ end
45
74
  end
@@ -56,4 +56,43 @@ describe Qe::DelayedJob do
56
56
  Qe::DelayedJob.enqueue(worker, :a => 1)
57
57
  end
58
58
  end
59
+
60
+ context "scheduling" do
61
+ let(:worker) {
62
+ mock("worker", :queue => "some_queue", :name => "SomeWorker")
63
+ }
64
+
65
+ let(:date) { Time.now }
66
+
67
+ before do
68
+ Delayed::Job.stub :enqueue
69
+ end
70
+
71
+ it "sets queue name" do
72
+ Delayed::Job
73
+ .should_receive(:enqueue)
74
+ .with(anything, hash_including(:queue => "some_queue"))
75
+
76
+ Qe::DelayedJob.schedule(worker, date, :a => 1)
77
+ end
78
+
79
+ it "instantiates worker" do
80
+ Qe::DelayedJob::Worker
81
+ .should_receive(:new)
82
+ .with("SomeWorker", :a => 1)
83
+
84
+ Qe::DelayedJob.schedule(worker, date, :a => 1)
85
+ end
86
+
87
+ it "schedules job" do
88
+ job = mock("job")
89
+ Qe::DelayedJob::Worker.stub :new => job
90
+
91
+ Delayed::Job
92
+ .should_receive(:enqueue)
93
+ .with(job, hash_including(:run_at => date))
94
+
95
+ Qe::DelayedJob.schedule(worker, date, :a => 1)
96
+ end
97
+ end
59
98
  end
@@ -1,8 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Qe::EnqueueMatcher do
4
- HelloWorker = Class.new { include Qe::Worker }
5
-
6
4
  it "sets adapter" do
7
5
  expect(Qe.adapter).to eql(Qe::Testing)
8
6
  end
@@ -1,11 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Qe::Immediate do
4
- HelloWorker = Class.new do
5
- include Qe::Worker
6
- def perform; end
7
- end
8
-
9
4
  let(:job) { mock("job").as_null_object }
10
5
 
11
6
  it "sets options" do
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+
3
+ describe Qe::Locale do
4
+ let(:i18n) { mock("I18n", :locale => :en) }
5
+
6
+ before do
7
+ stub_const("I18n", i18n)
8
+ end
9
+
10
+ context "when including extension" do
11
+ context "before Qe::Locale" do
12
+ it "raises exception" do
13
+ expect {
14
+ mod = Module.new do
15
+ include Qe::Locale
16
+ end
17
+ }.to raise_error(Qe::OutOfOrderError)
18
+ end
19
+ end
20
+
21
+ context "after Qe::Locale" do
22
+ it "does nothing" do
23
+ expect {
24
+ mod = Module.new do
25
+ include Qe::Worker
26
+ include Qe::Locale
27
+ end
28
+ }.not_to raise_error
29
+ end
30
+ end
31
+ end
32
+
33
+ context "when enqueuing" do
34
+ before do
35
+ Qe.adapter = Qe::Testing
36
+ end
37
+
38
+ it "sets locale" do
39
+ expect {
40
+ LocalizedWorker.enqueue
41
+ }.to enqueue(LocalizedWorker).with(:locale => :en)
42
+ end
43
+ end
44
+
45
+ context "when performing" do
46
+ before do
47
+ Qe.adapter = Qe::Immediate
48
+ end
49
+
50
+ it "sets locale" do
51
+ i18n
52
+ .should_receive(:locale=)
53
+ .with(:en)
54
+
55
+ LocalizedWorker.enqueue
56
+ end
57
+ end
58
+ end
@@ -39,4 +39,12 @@ describe Qe::Qu do
39
39
  Qe::Qu.enqueue(worker, :a => 1)
40
40
  end
41
41
  end
42
+
43
+ context "scheduling" do
44
+ it "raises exception" do
45
+ expect {
46
+ Qe::Qu.schedule(stub, Time.now, :a => 1)
47
+ }.to raise_error(Qe::UnsupportedFeatureError)
48
+ end
49
+ end
42
50
  end
@@ -39,4 +39,29 @@ describe Qe::Resque do
39
39
  Qe::Resque.enqueue(worker, :a => 1)
40
40
  end
41
41
  end
42
+
43
+ context "scheduling" do
44
+ let(:date) { Time.now }
45
+
46
+ let(:worker) {
47
+ mock("worker", :queue => "some_queue", :name => "SomeWorker")
48
+ }
49
+
50
+ before do
51
+ Resque.stub :enqueue_at => nil, :remove_delayed => nil
52
+ end
53
+
54
+ it "sets queue name" do
55
+ Qe::Resque.schedule(worker, date)
56
+ expect(Qe::Resque::Worker.instance_variable_get("@queue")).to eql("some_queue")
57
+ end
58
+
59
+ it "schedules job" do
60
+ ::Resque
61
+ .should_receive(:enqueue_at)
62
+ .with(date, Qe::Resque::Worker, "SomeWorker", :a => 1)
63
+
64
+ Qe::Resque.schedule(worker, date, :a => 1)
65
+ end
66
+ end
42
67
  end
@@ -46,4 +46,32 @@ describe Qe::Sidekiq do
46
46
  Qe::Sidekiq.enqueue(worker, :a => 1)
47
47
  end
48
48
  end
49
+
50
+ context "scheduling" do
51
+ let(:worker) {
52
+ mock("worker", :queue => "some_queue", :name => "SomeWorker")
53
+ }
54
+
55
+ before do
56
+ Qe::Sidekiq::Worker.stub :perform_at
57
+ end
58
+
59
+ it "sets queue name" do
60
+ Qe::Sidekiq::Worker
61
+ .should_receive(:sidekiq_options)
62
+ .with(:queue => "some_queue")
63
+
64
+ Qe::Sidekiq.enqueue(worker)
65
+ end
66
+
67
+ it "schedules job" do
68
+ date = Time.now
69
+
70
+ Qe::Sidekiq::Worker
71
+ .should_receive(:perform_at)
72
+ .with(date, "SomeWorker", :a => 1)
73
+
74
+ Qe::Sidekiq.schedule(worker, date, :a => 1)
75
+ end
76
+ end
49
77
  end
@@ -1,12 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Qe::Worker do
4
- HelloWorker = Class.new do
5
- include Qe::Worker
6
-
7
- def perform; end
8
- end
9
-
10
4
  it "sets queue name" do
11
5
  HelloWorker.queue "hello"
12
6
  expect(HelloWorker.queue).to eql("hello")
@@ -28,6 +22,18 @@ describe Qe::Worker do
28
22
  HelloWorker.enqueue(:a => 1)
29
23
  end
30
24
 
25
+ it "delegates scheduling to adapter" do
26
+ adapter = mock("adapter")
27
+ date = Time.now
28
+ adapter
29
+ .should_receive(:schedule)
30
+ .with(HelloWorker, date, :a => 1)
31
+
32
+ Qe.adapter = adapter
33
+
34
+ HelloWorker.enqueue(:a => 1, :run_at => date)
35
+ end
36
+
31
37
  it "finds worker by its name" do
32
38
  worker = mock("worker")
33
39
  stub_const "Some::Weird::Worker", worker
@@ -73,8 +79,13 @@ describe Qe::Worker do
73
79
  end
74
80
 
75
81
  it "passes error object to error handler" do
76
- HelloWorker.any_instance.should_receive(:error).with(kind_of(StandardError))
77
- HelloWorker.any_instance.stub(:perform).and_raise("ZOMG!")
82
+ HelloWorker.any_instance
83
+ .should_receive(:error)
84
+ .with(kind_of(StandardError))
85
+
86
+ HelloWorker.any_instance
87
+ .stub(:perform)
88
+ .and_raise("ZOMG!")
78
89
 
79
90
  Qe::Worker.perform("HelloWorker", {})
80
91
  end
@@ -10,3 +10,6 @@ require "qe/sidekiq"
10
10
  require "qe/qu"
11
11
  require "qe/delayed_job"
12
12
  require "delayed_job_active_record"
13
+
14
+ require "support/hello_worker"
15
+ require "support/localized_worker"
@@ -0,0 +1,4 @@
1
+ class HelloWorker
2
+ include Qe::Worker
3
+ def perform; end
4
+ end
@@ -0,0 +1,5 @@
1
+ class LocalizedWorker
2
+ include Qe::Worker
3
+ include Qe::Locale
4
+ def perform; end
5
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-17 00:00:00.000000000 Z
12
+ date: 2013-02-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sidekiq
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: resque-scheduler
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
94
110
  - !ruby/object:Gem::Dependency
95
111
  name: activerecord
96
112
  requirement: !ruby/object:Gem::Requirement
@@ -191,11 +207,12 @@ files:
191
207
  - examples/Procfile
192
208
  - examples/README.md
193
209
  - examples/Rakefile
210
+ - examples/add_jobs.rb
194
211
  - examples/beanstalkd.ru
212
+ - examples/delayed_job.ru
195
213
  - examples/migrate.rb
196
214
  - examples/redis.conf
197
215
  - examples/resque.ru
198
- - examples/sample.rb
199
216
  - examples/sidekiq.ru
200
217
  - examples/workers.rb
201
218
  - lib/qe.rb
@@ -203,6 +220,7 @@ files:
203
220
  - lib/qe/beanstalk.rb
204
221
  - lib/qe/delayed_job.rb
205
222
  - lib/qe/immediate.rb
223
+ - lib/qe/locale.rb
206
224
  - lib/qe/qu.rb
207
225
  - lib/qe/resque.rb
208
226
  - lib/qe/sidekiq.rb
@@ -210,17 +228,22 @@ files:
210
228
  - lib/qe/testing/rspec.rb
211
229
  - lib/qe/version.rb
212
230
  - lib/qe/worker.rb
231
+ - lib/qe/worker/class_methods.rb
232
+ - lib/qe/worker/instance_methods.rb
213
233
  - qe.gemspec
214
234
  - spec/qe/action_spec.rb
215
235
  - spec/qe/beanstalk_spec.rb
216
236
  - spec/qe/delayed_job_spec.rb
217
237
  - spec/qe/enqueue_matcher_spec.rb
218
238
  - spec/qe/immediate_spec.rb
239
+ - spec/qe/locale_spec.rb
219
240
  - spec/qe/qu_spec.rb
220
241
  - spec/qe/resque_spec.rb
221
242
  - spec/qe/sidekiq_spec.rb
222
243
  - spec/qe/worker_spec.rb
223
244
  - spec/spec_helper.rb
245
+ - spec/support/hello_worker.rb
246
+ - spec/support/localized_worker.rb
224
247
  homepage: http://rubygems.org/gems/qe
225
248
  licenses: []
226
249
  post_install_message:
@@ -241,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
241
264
  version: '0'
242
265
  requirements: []
243
266
  rubyforge_project:
244
- rubygems_version: 1.8.24
267
+ rubygems_version: 1.8.25
245
268
  signing_key:
246
269
  specification_version: 3
247
270
  summary: A simple interface over several background job libraries like Resque, Sidekiq