sidekiq-activerecord 0.0.2 → 0.0.3
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 +7 -0
- data/.gitignore +4 -1
- data/.rspec +3 -3
- data/.travis.yml +5 -5
- data/Gemfile +14 -0
- data/README.md +39 -79
- data/lib/sidekiq/active_record/manager_worker.rb +34 -19
- data/lib/sidekiq/active_record/task_worker.rb +119 -71
- data/lib/sidekiq/active_record/version.rb +1 -1
- data/sidekiq-activerecord.gemspec +1 -1
- data/spec/sidekiq/active_record/manager_worker_spec.rb +33 -2
- data/spec/sidekiq/active_record/task_worker_spec.rb +133 -23
- data/spec/spec_helper.rb +4 -0
- metadata +26 -44
- data/Gemfile.lock +0 -71
- data/pkg/sidekiq-activerecord-0.0.1.gem +0 -0
- data/pkg/sidekiq-activerecord-0.0.2.gem +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f4546acc561ce4ce6579666b4b05a66006ec39d9
|
4
|
+
data.tar.gz: 73e5e411912bca36600f5bf091fb010767119f00
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 716f41cd85a9809af9965675eca4220b7d35f5607cb42abfea2fe5c1251fb7d2a8f466219db43bcaefb19e9ab77b604a0926a11482039bb0f89a4333c4fc19af
|
7
|
+
data.tar.gz: b5ec0c789fa00a57ee2464f72a88c40b930dd1683c858d914d8a1330059bf13338abd002d15537ea8419c089e37b76e719495ef34aaa4b1c6490e7b77a8fe018
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
--color
|
2
|
+
--format documentation
|
3
|
+
--require spec_helper
|
data/.travis.yml
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
3
|
-
|
2
|
+
before_install: gem install bundler
|
3
|
+
script: bundle exec rake
|
4
4
|
rvm:
|
5
5
|
- 1.9.3
|
6
6
|
- jruby-19mode
|
7
|
-
- rbx
|
7
|
+
- rbx-2
|
8
8
|
- 2.0.0
|
9
|
-
- 2.1
|
9
|
+
- 2.1.2
|
10
10
|
matrix:
|
11
11
|
allow_failures:
|
12
|
-
- rvm: rbx
|
12
|
+
- rvm: rbx-2
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,116 +1,76 @@
|
|
1
|
-
|
1
|
+
[Sidekiq::Activerecord](https://github.com/sidekiq-orm/sidekiq-activerecord) encapsulates common patterns and various interactions between [Sidekiq](https://github.com/mperham/sidekiq) and [ActiveRecord](http://guides.rubyonrails.org/active_record_basics.html).
|
2
2
|
|
3
|
-
|
3
|
+
[](https://travis-ci.org/sidekiq-orm/sidekiq-activerecord)
|
4
4
|
|
5
|
-
|
5
|
+
***
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
gem 'sidekiq-activerecord'
|
10
|
-
|
11
|
-
And then execute:
|
7
|
+
## Common Patterns
|
8
|
+
If you've been using Sidekiq for a while, you've probably noticed a recurring pattern in your workers:
|
12
9
|
|
13
|
-
$ bundle
|
14
|
-
|
15
|
-
Or install it yourself as:
|
16
|
-
|
17
|
-
$ gem install sidekiq-activerecord
|
18
10
|
|
19
|
-
|
11
|
+
## [Sidekiq::ActiveRecord::TaskWorker](https://github.com/sidekiq-orm/sidekiq-activerecord/wiki/Task-Worker)
|
12
|
+
A very conventional pattern, is to have a worker that gets a model identifier, loads it and runs some custom logic on the model.
|
20
13
|
|
21
|
-
|
14
|
+
[```TaskWorker```]https://github.com/sidekiq-orm/sidekiq-activerecord/wiki/Task-Worker) provides a simple and clean interface, which reduces the boilerplate and exposes only the custom logic.
|
22
15
|
|
23
|
-
|
24
|
-
A parent worker which goes over some model collection and enqueues a child worker for each model in the collection.
|
16
|
+
Here's a simple example:
|
25
17
|
|
26
18
|
```ruby
|
27
|
-
class
|
28
|
-
include Sidekiq::Worker
|
19
|
+
class UserTaskWorker < Sidekiq::ActiveRecord::TaskWorker
|
29
20
|
|
30
|
-
|
31
|
-
User.active.each do |user|
|
32
|
-
ChildWorker.perform_async(user.id)
|
33
|
-
end
|
34
|
-
end
|
21
|
+
sidekiq_task_model :user # or User
|
35
22
|
|
23
|
+
def perform_on_user
|
24
|
+
UserService.run(user)
|
25
|
+
end
|
26
|
+
|
36
27
|
end
|
37
28
|
```
|
29
|
+
For a more see the [TaskWorker documention](https://github.com/sidekiq-orm/sidekiq-activerecord/wiki/Task-Worker).
|
38
30
|
|
39
|
-
## Sidekiq::ManagerWorker - Example
|
40
31
|
|
41
|
-
|
42
|
-
class UserTaskWorker
|
43
|
-
include Sidekiq::TaskWorker
|
44
|
-
end
|
32
|
+
***
|
45
33
|
|
46
|
-
class UserSyncer
|
47
|
-
include Sidekiq::ActiveRecord::ManagerWorker
|
48
34
|
|
35
|
+
## [Sidekiq::ActiveRecord::ManagerWorker](https://github.com/sidekiq-orm/sidekiq-activerecord/wiki/Manager-Worker)
|
36
|
+
Another farily common ```Sidekiq::Worker``` pattern, is a parent worker which goes over a model collection and enqueues a child worker for each model in the collection.
|
37
|
+
|
38
|
+
Here's a simple example:
|
39
|
+
```ruby
|
40
|
+
# Parent Worker
|
41
|
+
class UserSyncer < Sidekiq::ActiveRecord::ManagerWorker
|
49
42
|
sidekiq_delegate_task_to :user_task_worker # or UserTaskWorker
|
50
|
-
sidekiq_manager_options :batch_size => 500,
|
51
|
-
:identifier_key => :user_token,
|
52
|
-
:additional_keys => [:status]
|
53
43
|
end
|
54
|
-
|
55
|
-
UserSyncer.perform_query_async(User.active, :batch_size => 300)
|
56
44
|
```
|
57
|
-
|
58
|
-
## Model Task Workers
|
59
|
-
|
60
|
-
A worker which gets a model.id (like ChildWorker above) loads it, validates it and runs some logic on the model.
|
61
|
-
|
45
|
+
Then, just call the worker with the model collection:
|
62
46
|
```ruby
|
63
|
-
|
64
|
-
include Sidekiq::Worker
|
65
|
-
|
66
|
-
def perform(user_id)
|
67
|
-
user = User.find(user_id)
|
68
|
-
return unless user.present?
|
69
|
-
return unless user.active?
|
70
|
-
|
71
|
-
UserService.run(user)
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
47
|
+
UserSyncer.perform_query_async(User.active)
|
75
48
|
```
|
76
49
|
|
77
|
-
|
78
|
-
|
79
|
-
```ruby
|
80
|
-
class UserMailerTaskWorker
|
81
|
-
include Sidekiq::ActiveRecord::TaskWorker
|
50
|
+
For a more see the [ManagerWorker documention](https://github.com/sidekiq-orm/sidekiq-activerecord/wiki/Manager-Worker).
|
82
51
|
|
83
|
-
|
84
|
-
sidekiq_task_options :identifier_key => :token
|
52
|
+
***
|
85
53
|
|
86
|
-
|
87
|
-
|
88
|
-
end
|
54
|
+
# Documention
|
55
|
+
Checkout the project's [Wiki Page](https://github.com/sidekiq-orm/sidekiq-activerecord/wiki)
|
89
56
|
|
90
|
-
|
91
|
-
def not_found_model(token)
|
92
|
-
Log.error "User not found for token:#{token}"
|
93
|
-
end
|
57
|
+
***
|
94
58
|
|
95
|
-
|
96
|
-
def model_valid?(user)
|
97
|
-
user.active?
|
98
|
-
end
|
59
|
+
# Installation
|
99
60
|
|
100
|
-
|
101
|
-
def invalid_model(user)
|
102
|
-
Log.error "User #{user.token} is invalid"
|
103
|
-
end
|
61
|
+
Add this line to your application's Gemfile:
|
104
62
|
|
105
|
-
|
63
|
+
gem 'sidekiq-activerecord'
|
106
64
|
|
65
|
+
And then execute:
|
107
66
|
|
108
|
-
|
109
|
-
|
67
|
+
$ bundle
|
68
|
+
|
69
|
+
***
|
110
70
|
|
111
71
|
## Contributing
|
112
72
|
|
113
|
-
1. Fork it ( http://github.com/
|
73
|
+
1. Fork it ( http://github.com/sidekiq-orm/sidekiq-activerecord/fork )
|
114
74
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
115
75
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
116
76
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -1,17 +1,19 @@
|
|
1
1
|
module Sidekiq
|
2
2
|
module ActiveRecord
|
3
|
-
|
4
|
-
|
3
|
+
class ManagerWorker
|
4
|
+
include Sidekiq::Worker
|
5
5
|
|
6
6
|
DEFAULT_IDENTIFIER_KEY = :id
|
7
7
|
DEFAULT_BATCH_SIZE = 1000
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
9
|
+
def perform(options = {})
|
10
|
+
default_query = self.class.get_default_models_query
|
11
|
+
self.class.perform_query_async(default_query, options)
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
15
17
|
# For a given model collection, it delegates each model to a sub-worker (e.g TaskWorker)
|
16
18
|
# Specify the TaskWorker with the `sidekiq_delegate_task_to` method.
|
17
19
|
#
|
@@ -24,7 +26,9 @@ module Sidekiq
|
|
24
26
|
#
|
25
27
|
# @example:
|
26
28
|
# class UserTaskWorker
|
27
|
-
#
|
29
|
+
# def perform(user_id)
|
30
|
+
# # user task logic
|
31
|
+
# end
|
28
32
|
# end
|
29
33
|
#
|
30
34
|
# class UserSyncer
|
@@ -44,7 +48,7 @@ module Sidekiq
|
|
44
48
|
#
|
45
49
|
def perform_query_async(models_query, options = {})
|
46
50
|
set_runtime_options(options)
|
47
|
-
models = models_query
|
51
|
+
models = prepare_models_query(models_query)
|
48
52
|
models.find_in_batches(batch_size: batch_size) do |models_batch|
|
49
53
|
model_attributes = models_batch.map { |model| model_attributes(model) }
|
50
54
|
Sidekiq::Client.push_bulk(class: worker_class, args: model_attributes)
|
@@ -72,10 +76,24 @@ module Sidekiq
|
|
72
76
|
# :additional_keys - additional model keys
|
73
77
|
# :batch_size - Specifies the size of the batch. Default to 1000.
|
74
78
|
def sidekiq_manager_options(opts = {})
|
75
|
-
|
79
|
+
@sidekiq_manager_options_hash = get_sidekiq_manager_options.merge((opts || {}))
|
76
80
|
end
|
77
81
|
|
78
|
-
#
|
82
|
+
# The default of query to run, when the workers runs perform
|
83
|
+
# example
|
84
|
+
# class UserManagerWorker < Sidekiq::ActiveRecord::ManagerWorker
|
85
|
+
# sidekiq_delegate_task_to UserTaskWorker
|
86
|
+
# default_models_query -> { User.active }
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# UserManagerWorker.perform_async(:batch_size => 300)
|
90
|
+
def default_models_query(query)
|
91
|
+
@query = query
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_default_models_query
|
95
|
+
@query.call() if @query.present?
|
96
|
+
end
|
79
97
|
|
80
98
|
def default_worker_manager_options
|
81
99
|
{
|
@@ -93,10 +111,9 @@ module Sidekiq
|
|
93
111
|
additional_attributes.unshift(id_attribute)
|
94
112
|
end
|
95
113
|
|
96
|
-
def
|
97
|
-
|
98
|
-
|
99
|
-
attrs
|
114
|
+
def prepare_models_query(models_query)
|
115
|
+
selected_attributes = [models_query.primary_key.to_sym, identifier_key, additional_keys].uniq
|
116
|
+
models_query.select(selected_attributes)
|
100
117
|
end
|
101
118
|
|
102
119
|
def worker_class
|
@@ -104,10 +121,6 @@ module Sidekiq
|
|
104
121
|
manager_options[:worker_class]
|
105
122
|
end
|
106
123
|
|
107
|
-
def default_identifier?
|
108
|
-
identifier_key == DEFAULT_IDENTIFIER_KEY
|
109
|
-
end
|
110
|
-
|
111
124
|
def identifier_key
|
112
125
|
manager_options[:identifier_key]
|
113
126
|
end
|
@@ -125,7 +138,7 @@ module Sidekiq
|
|
125
138
|
end
|
126
139
|
|
127
140
|
def get_sidekiq_manager_options
|
128
|
-
|
141
|
+
@sidekiq_manager_options_hash ||= default_worker_manager_options
|
129
142
|
end
|
130
143
|
|
131
144
|
def runtime_options
|
@@ -135,7 +148,9 @@ module Sidekiq
|
|
135
148
|
def set_runtime_options(options={})
|
136
149
|
@sidekiq_manager_runtime_options = options.delete_if { |_, v| v.to_s.strip == '' }
|
137
150
|
end
|
151
|
+
|
138
152
|
end
|
153
|
+
|
139
154
|
end
|
140
155
|
end
|
141
156
|
end
|
@@ -1,88 +1,86 @@
|
|
1
1
|
module Sidekiq
|
2
2
|
module ActiveRecord
|
3
|
-
|
4
|
-
|
3
|
+
class TaskWorker
|
4
|
+
include Sidekiq::Worker
|
5
5
|
|
6
|
-
|
7
|
-
base.extend(ClassMethods)
|
8
|
-
base.class_attribute :sidekiq_task_options_hash
|
9
|
-
end
|
6
|
+
attr_reader :task_model
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
model = fetch_model(identifier)
|
42
|
-
return not_found_model(identifier) unless model.present?
|
43
|
-
|
44
|
-
if model_valid?(model)
|
45
|
-
perform_on_model(model, *args)
|
46
|
-
else
|
47
|
-
invalid_model(model)
|
48
|
-
end
|
49
|
-
end
|
8
|
+
# @example:
|
9
|
+
# class UserMailerTaskWorker < Sidekiq::ActiveRecord::TaskWorker
|
10
|
+
#
|
11
|
+
# sidekiq_task_model :user_model # or UserModel
|
12
|
+
# sidekiq_task_options :identifier_key => :token
|
13
|
+
#
|
14
|
+
# def perform_on_model
|
15
|
+
# UserMailer.deliver_registration_confirmation(user, email_type)
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# def not_found_model(token)
|
19
|
+
# Log.error "User not found for token:#{token}"
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# def should_perform_on_model?
|
23
|
+
# user.active?
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# def did_not_perform_on_model
|
27
|
+
# Log.error "User #{user.token} is inactive"
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
#
|
33
|
+
# UserMailerTaskWorker.perform(user.id, :new_email)
|
34
|
+
#
|
35
|
+
def perform(identifier, *args)
|
36
|
+
@task_model = fetch_model(identifier, *args)
|
37
|
+
return not_found_model(identifier, *args) unless @task_model.present?
|
50
38
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
model_klass
|
56
|
-
end
|
57
|
-
get_sidekiq_task_options[:model_class] = model_klass
|
39
|
+
if should_perform_on_model?
|
40
|
+
perform_on_model(*args)
|
41
|
+
else
|
42
|
+
did_not_perform_on_model
|
58
43
|
end
|
44
|
+
end
|
59
45
|
|
60
|
-
|
61
|
-
|
62
|
-
|
46
|
+
def perform_on_model(*args)
|
47
|
+
task_model
|
48
|
+
end
|
63
49
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
50
|
+
# Hook that can block perform_on_model from being triggered,
|
51
|
+
# e.g in cases when the model is no longer valid
|
52
|
+
def should_perform_on_model?
|
53
|
+
true
|
54
|
+
end
|
68
55
|
|
69
|
-
|
70
|
-
|
71
|
-
|
56
|
+
# Hook to handel a model that was not performed
|
57
|
+
def did_not_perform_on_model
|
58
|
+
task_model
|
59
|
+
end
|
72
60
|
|
73
|
-
|
74
|
-
|
75
|
-
|
61
|
+
# Hook to handel not found model
|
62
|
+
def not_found_model(identifier, *args)
|
63
|
+
identifier
|
64
|
+
end
|
76
65
|
|
77
|
-
|
66
|
+
def fetch_model(identifier, *args)
|
67
|
+
self.class.model_class.find_by(self.class.identifier_key => identifier)
|
68
|
+
end
|
78
69
|
|
79
|
-
|
80
|
-
|
70
|
+
|
71
|
+
class << self
|
72
|
+
|
73
|
+
def sidekiq_task_model(model_klass)
|
74
|
+
return if model_klass.blank?
|
75
|
+
|
76
|
+
setup_task_model_alias(model_klass)
|
77
|
+
|
78
|
+
get_sidekiq_task_options[:model_class] = active_record_class(model_klass)
|
81
79
|
end
|
82
80
|
|
83
81
|
def model_class
|
84
82
|
klass = get_sidekiq_task_options[:model_class]
|
85
|
-
fail NotImplementedError.new('`
|
83
|
+
fail NotImplementedError.new('`sidekiq_task_model` was not specified') unless klass.present?
|
86
84
|
klass
|
87
85
|
end
|
88
86
|
|
@@ -96,11 +94,49 @@ module Sidekiq
|
|
96
94
|
#
|
97
95
|
# :identifier_key - the model identifier column. Default 'id'
|
98
96
|
def sidekiq_task_options(opts = {})
|
99
|
-
|
97
|
+
@sidekiq_task_options_hash = get_sidekiq_task_options.merge((opts).symbolize_keys!)
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
# aliases task_model with the name of the model
|
104
|
+
#
|
105
|
+
# example:
|
106
|
+
# sidekiq_task_model: AdminUser # or :admin_user
|
107
|
+
#
|
108
|
+
# then the worker will have access to `admin_user`, which is an alias to `task_model`
|
109
|
+
#
|
110
|
+
# def perform_on_admin_user
|
111
|
+
# admin_user == task_model
|
112
|
+
# end
|
113
|
+
#
|
114
|
+
# it will add the following method aliases to the hooks:
|
115
|
+
#
|
116
|
+
# def not_found_admin_user; end
|
117
|
+
# def should_perform_on_admin_user?; end
|
118
|
+
# def did_not_perform_on_admin_user; end
|
119
|
+
#
|
120
|
+
def setup_task_model_alias(model_klass_name)
|
121
|
+
if model_klass_name.is_a?(Class)
|
122
|
+
model_klass_name = model_klass_name.name.underscore
|
123
|
+
end
|
124
|
+
{
|
125
|
+
:task_model => model_klass_name,
|
126
|
+
:fetch_model => "fetch_#{model_klass_name}",
|
127
|
+
:not_found_model => "not_found_#{model_klass_name}",
|
128
|
+
:should_perform_on_model? => "should_perform_on_#{model_klass_name}?",
|
129
|
+
:did_not_perform_on_model => "did_not_perform_on_#{model_klass_name}",
|
130
|
+
:perform_on_model => "perform_on_#{model_klass_name}"
|
131
|
+
}.each do |old_name, new_name|
|
132
|
+
self.class_exec do
|
133
|
+
alias_method new_name.to_sym, old_name
|
134
|
+
end
|
135
|
+
end
|
100
136
|
end
|
101
137
|
|
102
138
|
def get_sidekiq_task_options
|
103
|
-
|
139
|
+
@sidekiq_task_options_hash ||= default_worker_task_options
|
104
140
|
end
|
105
141
|
|
106
142
|
def default_worker_task_options
|
@@ -108,7 +144,19 @@ module Sidekiq
|
|
108
144
|
identifier_key: :id
|
109
145
|
}
|
110
146
|
end
|
147
|
+
|
148
|
+
def active_record_class(model_klass)
|
149
|
+
begin
|
150
|
+
model_klass = model_klass.to_s.classify.constantize
|
151
|
+
raise unless model_klass <= ::ActiveRecord::Base
|
152
|
+
rescue
|
153
|
+
fail ArgumentError.new '`sidekiq_task_model` must be an ActiveRecord model'
|
154
|
+
end
|
155
|
+
model_klass
|
156
|
+
end
|
157
|
+
|
111
158
|
end
|
159
|
+
|
112
160
|
end
|
113
161
|
end
|
114
162
|
end
|
@@ -21,8 +21,8 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_dependency 'sidekiq', '>= 2.16'
|
22
22
|
spec.add_dependency 'activerecord', '>= 4.0'
|
23
23
|
|
24
|
+
spec.add_development_dependency 'rake'
|
24
25
|
spec.add_development_dependency 'rspec', '3.0.0.rc1'
|
25
26
|
spec.add_development_dependency 'database_cleaner', '>= 1.2.0'
|
26
|
-
spec.add_development_dependency 'sqlite3', '>= 1.3.9'
|
27
27
|
spec.add_development_dependency 'factory_girl', '~> 4.0'
|
28
28
|
end
|
@@ -9,8 +9,7 @@ describe Sidekiq::ActiveRecord::ManagerWorker do
|
|
9
9
|
let(:worker_class) { MockUserWorker }
|
10
10
|
let(:sidekiq_client) { Sidekiq::Client }
|
11
11
|
|
12
|
-
class UserManagerWorker
|
13
|
-
include Sidekiq::ActiveRecord::ManagerWorker
|
12
|
+
class UserManagerWorker < Sidekiq::ActiveRecord::ManagerWorker
|
14
13
|
sidekiq_delegate_task_to MockUserWorker
|
15
14
|
end
|
16
15
|
|
@@ -21,6 +20,24 @@ describe Sidekiq::ActiveRecord::ManagerWorker do
|
|
21
20
|
|
22
21
|
let(:models_query) { User.active }
|
23
22
|
|
23
|
+
describe 'perform with default models query' do
|
24
|
+
|
25
|
+
before do
|
26
|
+
class UserManagerWorker < Sidekiq::ActiveRecord::ManagerWorker
|
27
|
+
sidekiq_delegate_task_to MockUserWorker
|
28
|
+
default_models_query -> { User.active }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:default_models_query) { User.active }
|
33
|
+
let(:worker_options) { {:batch_size => 300} }
|
34
|
+
|
35
|
+
it 'runs `perform_query_async` with the default models query and the specified options' do
|
36
|
+
expect(UserManagerWorker).to receive(:perform_query_async).with(default_models_query, worker_options)
|
37
|
+
UserManagerWorker.new.perform(worker_options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
24
41
|
describe 'perform_query_async' do
|
25
42
|
|
26
43
|
def run_worker(options = {})
|
@@ -37,6 +54,20 @@ describe Sidekiq::ActiveRecord::ManagerWorker do
|
|
37
54
|
|
38
55
|
let(:model_ids) { [[user_1.id], [user_2.id], [user_3.id]] }
|
39
56
|
|
57
|
+
context 'when a sidekiq_options is specified' do
|
58
|
+
|
59
|
+
before do
|
60
|
+
class UserManagerWorker
|
61
|
+
sidekiq_options :queue => :user_manager_queue
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'sets the queue' do
|
66
|
+
sidekiq_options = UserManagerWorker.send(:get_sidekiq_options)
|
67
|
+
expect(sidekiq_options['queue']).to eq :user_manager_queue
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
40
71
|
context 'when the worker_class is specified' do
|
41
72
|
|
42
73
|
class MockCustomWorker; end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
describe Sidekiq::ActiveRecord::TaskWorker do
|
2
2
|
|
3
|
-
class UserTaskWorker
|
4
|
-
include Sidekiq::ActiveRecord::TaskWorker
|
3
|
+
class UserTaskWorker < Sidekiq::ActiveRecord::TaskWorker
|
5
4
|
end
|
6
5
|
|
7
6
|
let!(:user) { create(:user, :active) }
|
8
7
|
|
9
|
-
subject(:
|
8
|
+
subject(:task_worker_class) { UserTaskWorker }
|
9
|
+
subject(:task_worker) { UserTaskWorker.new }
|
10
10
|
|
11
11
|
def run_worker
|
12
12
|
task_worker.perform(user.id)
|
@@ -30,17 +30,51 @@ describe Sidekiq::ActiveRecord::TaskWorker do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'sets the identifier_key' do
|
33
|
-
identifier =
|
33
|
+
identifier = task_worker_class.send(:identifier_key)
|
34
34
|
expect(identifier).to eq :email
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'calls the perform_on_model with the model' do
|
38
|
-
expect(task_worker).to receive(:perform_on_model)
|
38
|
+
expect(task_worker).to receive(:perform_on_model)
|
39
39
|
task_worker.perform(user.email)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
context 'when a
|
43
|
+
context 'when a sidekiq_options is specified' do
|
44
|
+
|
45
|
+
before do
|
46
|
+
class UserTaskWorker
|
47
|
+
sidekiq_options :queue => :user_queue
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'sets the queue' do
|
52
|
+
sidekiq_options = task_worker_class.send(:get_sidekiq_options)
|
53
|
+
expect(sidekiq_options['queue']).to eq :user_queue
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when the specified task model is not a class' do
|
58
|
+
|
59
|
+
it 'raises an ArgumentError' do
|
60
|
+
expect {
|
61
|
+
task_worker_class.send(:sidekiq_task_model, :something_unrelated)
|
62
|
+
}.to raise_error ArgumentError
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when the specified task model is not an ActiveRecord class' do
|
67
|
+
|
68
|
+
class NotActiveRecord; end
|
69
|
+
|
70
|
+
it 'raises an ArgumentError' do
|
71
|
+
expect {
|
72
|
+
task_worker_class.send(:sidekiq_task_model, NotActiveRecord)
|
73
|
+
}.to raise_error ArgumentError
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when a ActiveRecord class is specified' do
|
44
78
|
|
45
79
|
before do
|
46
80
|
class UserTaskWorker
|
@@ -49,13 +83,25 @@ describe Sidekiq::ActiveRecord::TaskWorker do
|
|
49
83
|
end
|
50
84
|
|
51
85
|
it 'sets the model' do
|
52
|
-
klass =
|
86
|
+
klass = task_worker_class.send(:model_class)
|
53
87
|
expect(klass).to eq User
|
54
88
|
end
|
55
89
|
|
90
|
+
describe 'task_model' do
|
91
|
+
it 'sets the model' do
|
92
|
+
run_worker
|
93
|
+
expect(task_worker.task_model).to eq user
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'has an alias of `task_model` withe for the specified model name' do
|
97
|
+
run_worker
|
98
|
+
expect(task_worker.user).to eq user
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
56
102
|
end
|
57
103
|
|
58
|
-
context 'when
|
104
|
+
context 'when an ActiveRecord class name is specified' do
|
59
105
|
before do
|
60
106
|
class UserTaskWorker
|
61
107
|
sidekiq_task_model :user
|
@@ -63,20 +109,45 @@ describe Sidekiq::ActiveRecord::TaskWorker do
|
|
63
109
|
end
|
64
110
|
|
65
111
|
it 'sets the model' do
|
66
|
-
klass =
|
112
|
+
klass = task_worker_class.send(:model_class)
|
67
113
|
expect(klass).to eq User
|
68
114
|
end
|
69
115
|
|
116
|
+
describe 'task_model' do
|
117
|
+
it 'sets the model' do
|
118
|
+
run_worker
|
119
|
+
expect(task_worker.task_model).to eq user
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'has an alias of `task_model` withe for the specified model name' do
|
123
|
+
run_worker
|
124
|
+
expect(task_worker.user).to eq user
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe 'when fetching the model' do
|
129
|
+
|
130
|
+
def run_worker
|
131
|
+
task_worker.perform(user.id, user.email)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'calls the fetch_model hook' do
|
135
|
+
expect(task_worker).to receive(:fetch_model).with(user.id, user.email)
|
136
|
+
run_worker
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
70
141
|
context 'when the model is not found' do
|
71
142
|
|
72
143
|
let(:trash_id) { user.id + 10 }
|
73
144
|
|
74
145
|
def run_worker
|
75
|
-
task_worker.perform(trash_id)
|
146
|
+
task_worker.perform(trash_id, user.email)
|
76
147
|
end
|
77
148
|
|
78
149
|
it 'calls the not_found_model hook' do
|
79
|
-
expect(task_worker).to receive(:not_found_model).with(trash_id)
|
150
|
+
expect(task_worker).to receive(:not_found_model).with(trash_id, user.email)
|
80
151
|
run_worker
|
81
152
|
end
|
82
153
|
|
@@ -84,54 +155,86 @@ describe Sidekiq::ActiveRecord::TaskWorker do
|
|
84
155
|
expect(task_worker).to_not receive(:perform_on_model)
|
85
156
|
run_worker
|
86
157
|
end
|
158
|
+
|
159
|
+
describe 'method alias' do
|
160
|
+
it 'has an alias of not_found_model hook with for the specified task model name' do
|
161
|
+
expect(task_worker.not_found_user(trash_id)).to eq trash_id
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
87
165
|
end
|
88
166
|
|
89
167
|
context 'when the mode is found' do
|
90
168
|
|
91
|
-
context 'when the
|
92
|
-
it 'calls the
|
93
|
-
expect(task_worker).to receive(:
|
169
|
+
context 'when the should_perform_on_model? hook is specified' do
|
170
|
+
it 'calls the should_perform_on_model? hook' do
|
171
|
+
expect(task_worker).to receive(:should_perform_on_model?)
|
94
172
|
run_worker
|
95
173
|
end
|
174
|
+
|
175
|
+
describe 'method alias' do
|
176
|
+
|
177
|
+
let(:mock_result) { 1234 }
|
178
|
+
|
179
|
+
before do
|
180
|
+
class UserTaskWorker
|
181
|
+
def should_perform_on_user?
|
182
|
+
1234
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'has an alias of should_perform_on_model? hook with for the specified task model name' do
|
188
|
+
run_worker
|
189
|
+
expect(task_worker.should_perform_on_user?).to eq mock_result
|
190
|
+
end
|
191
|
+
end
|
96
192
|
end
|
97
193
|
|
98
|
-
context 'when the model
|
194
|
+
context 'when the model should be performed' do
|
99
195
|
|
100
196
|
before do
|
101
|
-
allow(task_worker).to receive(:
|
197
|
+
allow(task_worker).to receive(:should_perform_on_model?).and_return(true)
|
102
198
|
end
|
103
199
|
|
104
200
|
it 'calls the perform_on_model with the model' do
|
105
|
-
expect(task_worker).to receive(:perform_on_model)
|
201
|
+
expect(task_worker).to receive(:perform_on_model)
|
106
202
|
run_worker
|
107
203
|
end
|
108
204
|
|
109
205
|
describe 'perform_on_model' do
|
110
206
|
context 'when passing only the model identifier' do
|
111
207
|
it 'calls the perform_on_model with the model' do
|
112
|
-
expect(task_worker).to receive(:perform_on_model)
|
208
|
+
expect(task_worker).to receive(:perform_on_model)
|
113
209
|
run_worker
|
114
210
|
end
|
115
211
|
end
|
116
212
|
|
117
213
|
context 'when passing additional arguments' do
|
118
214
|
it 'calls the perform_on_model with the model' do
|
119
|
-
expect(task_worker).to receive(:perform_on_model).with(user
|
215
|
+
expect(task_worker).to receive(:perform_on_model).with(user.email)
|
120
216
|
task_worker.perform(user.id, user.email)
|
121
217
|
end
|
122
218
|
end
|
123
219
|
|
220
|
+
describe 'method alias' do
|
221
|
+
it 'has an alias of perform_on_model hook with for the specified task model name' do
|
222
|
+
task_worker.perform(user.id)
|
223
|
+
expect(task_worker.perform_on_user).to eq user
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
124
227
|
end
|
125
228
|
end
|
126
229
|
|
127
|
-
context 'when the model
|
230
|
+
context 'when the model should not be performed' do
|
128
231
|
|
129
232
|
before do
|
130
|
-
allow(task_worker).to receive(:
|
233
|
+
allow(task_worker).to receive(:should_perform_on_model?).and_return(false)
|
131
234
|
end
|
132
235
|
|
133
|
-
it 'calls the
|
134
|
-
expect(task_worker).to receive(:
|
236
|
+
it 'calls the did_not_perform_on_model hook' do
|
237
|
+
expect(task_worker).to receive(:did_not_perform_on_model)
|
135
238
|
run_worker
|
136
239
|
end
|
137
240
|
|
@@ -140,6 +243,13 @@ describe Sidekiq::ActiveRecord::TaskWorker do
|
|
140
243
|
run_worker
|
141
244
|
end
|
142
245
|
|
246
|
+
describe 'method alias' do
|
247
|
+
it 'has an alias of did_not_perform_on_model hook with for the specified task model name' do
|
248
|
+
run_worker
|
249
|
+
expect(task_worker.did_not_perform_on_user).to eq user
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
143
253
|
end
|
144
254
|
|
145
255
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,100 +1,88 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.3
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Adam Farhi
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2014-05
|
11
|
+
date: 2014-06-05 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: sidekiq
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '2.16'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '2.16'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: activerecord
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '4.0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '4.0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
42
|
+
name: rake
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- - '
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
47
|
+
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- - '
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
54
|
+
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
56
|
+
name: rspec
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '='
|
68
60
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
61
|
+
version: 3.0.0.rc1
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '='
|
76
67
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
68
|
+
version: 3.0.0.rc1
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
|
-
name:
|
70
|
+
name: database_cleaner
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
|
-
version: 1.
|
75
|
+
version: 1.2.0
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
|
-
version: 1.
|
82
|
+
version: 1.2.0
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: factory_girl
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
87
|
- - ~>
|
100
88
|
- !ruby/object:Gem::Version
|
@@ -102,7 +90,6 @@ dependencies:
|
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
94
|
- - ~>
|
108
95
|
- !ruby/object:Gem::Version
|
@@ -118,7 +105,6 @@ files:
|
|
118
105
|
- .rspec
|
119
106
|
- .travis.yml
|
120
107
|
- Gemfile
|
121
|
-
- Gemfile.lock
|
122
108
|
- LICENSE.txt
|
123
109
|
- README.md
|
124
110
|
- Rakefile
|
@@ -126,8 +112,6 @@ files:
|
|
126
112
|
- lib/sidekiq/active_record/task_worker.rb
|
127
113
|
- lib/sidekiq/active_record/version.rb
|
128
114
|
- lib/sidekiq/activerecord.rb
|
129
|
-
- pkg/sidekiq-activerecord-0.0.1.gem
|
130
|
-
- pkg/sidekiq-activerecord-0.0.2.gem
|
131
115
|
- sidekiq-activerecord.gemspec
|
132
116
|
- spec/sidekiq/active_record/manager_worker_spec.rb
|
133
117
|
- spec/sidekiq/active_record/task_worker_spec.rb
|
@@ -139,27 +123,26 @@ files:
|
|
139
123
|
homepage: https://github.com/yelled3/sidekiq-activerecord
|
140
124
|
licenses:
|
141
125
|
- MIT
|
126
|
+
metadata: {}
|
142
127
|
post_install_message:
|
143
128
|
rdoc_options: []
|
144
129
|
require_paths:
|
145
130
|
- lib
|
146
131
|
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
-
none: false
|
148
132
|
requirements:
|
149
|
-
- -
|
133
|
+
- - '>='
|
150
134
|
- !ruby/object:Gem::Version
|
151
135
|
version: '0'
|
152
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
137
|
requirements:
|
155
|
-
- -
|
138
|
+
- - '>='
|
156
139
|
- !ruby/object:Gem::Version
|
157
140
|
version: '0'
|
158
141
|
requirements: []
|
159
142
|
rubyforge_project:
|
160
|
-
rubygems_version:
|
143
|
+
rubygems_version: 2.0.6
|
161
144
|
signing_key:
|
162
|
-
specification_version:
|
145
|
+
specification_version: 4
|
163
146
|
summary: Encapsulates various interactions between Sidekiq and ActiveRecord
|
164
147
|
test_files:
|
165
148
|
- spec/sidekiq/active_record/manager_worker_spec.rb
|
@@ -169,4 +152,3 @@ test_files:
|
|
169
152
|
- spec/support/database_cleaner.rb
|
170
153
|
- spec/support/factory_girl.rb
|
171
154
|
- spec/support/models.rb
|
172
|
-
has_rdoc:
|
data/Gemfile.lock
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
sidekiq-activerecord (0.0.2)
|
5
|
-
activerecord (>= 4.0)
|
6
|
-
sidekiq (>= 2.16)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
activemodel (4.1.1)
|
12
|
-
activesupport (= 4.1.1)
|
13
|
-
builder (~> 3.1)
|
14
|
-
activerecord (4.1.1)
|
15
|
-
activemodel (= 4.1.1)
|
16
|
-
activesupport (= 4.1.1)
|
17
|
-
arel (~> 5.0.0)
|
18
|
-
activesupport (4.1.1)
|
19
|
-
i18n (~> 0.6, >= 0.6.9)
|
20
|
-
json (~> 1.7, >= 1.7.7)
|
21
|
-
minitest (~> 5.1)
|
22
|
-
thread_safe (~> 0.1)
|
23
|
-
tzinfo (~> 1.1)
|
24
|
-
arel (5.0.1.20140414130214)
|
25
|
-
builder (3.2.2)
|
26
|
-
celluloid (0.15.2)
|
27
|
-
timers (~> 1.1.0)
|
28
|
-
connection_pool (2.0.0)
|
29
|
-
database_cleaner (1.2.0)
|
30
|
-
diff-lcs (1.2.5)
|
31
|
-
factory_girl (4.4.0)
|
32
|
-
activesupport (>= 3.0.0)
|
33
|
-
i18n (0.6.9)
|
34
|
-
json (1.8.1)
|
35
|
-
minitest (5.3.4)
|
36
|
-
redis (3.0.7)
|
37
|
-
redis-namespace (1.4.1)
|
38
|
-
redis (~> 3.0.4)
|
39
|
-
rspec (3.0.0.rc1)
|
40
|
-
rspec-core (= 3.0.0.rc1)
|
41
|
-
rspec-expectations (= 3.0.0.rc1)
|
42
|
-
rspec-mocks (= 3.0.0.rc1)
|
43
|
-
rspec-core (3.0.0.rc1)
|
44
|
-
rspec-support (= 3.0.0.rc1)
|
45
|
-
rspec-expectations (3.0.0.rc1)
|
46
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
47
|
-
rspec-support (= 3.0.0.rc1)
|
48
|
-
rspec-mocks (3.0.0.rc1)
|
49
|
-
rspec-support (= 3.0.0.rc1)
|
50
|
-
rspec-support (3.0.0.rc1)
|
51
|
-
sidekiq (3.1.0)
|
52
|
-
celluloid (>= 0.15.2)
|
53
|
-
connection_pool (>= 2.0.0)
|
54
|
-
json
|
55
|
-
redis (>= 3.0.6)
|
56
|
-
redis-namespace (>= 1.3.1)
|
57
|
-
sqlite3 (1.3.9)
|
58
|
-
thread_safe (0.3.3)
|
59
|
-
timers (1.1.0)
|
60
|
-
tzinfo (1.1.0)
|
61
|
-
thread_safe (~> 0.1)
|
62
|
-
|
63
|
-
PLATFORMS
|
64
|
-
ruby
|
65
|
-
|
66
|
-
DEPENDENCIES
|
67
|
-
database_cleaner (>= 1.2.0)
|
68
|
-
factory_girl (~> 4.0)
|
69
|
-
rspec (= 3.0.0.rc1)
|
70
|
-
sidekiq-activerecord!
|
71
|
-
sqlite3 (>= 1.3.9)
|
Binary file
|
Binary file
|