say_when 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +5 -0
  4. data/Guardfile +50 -0
  5. data/README.md +135 -2
  6. data/Rakefile +1 -0
  7. data/lib/say_when.rb +33 -18
  8. data/lib/say_when/configuration.rb +16 -0
  9. data/lib/say_when/cron_expression.rb +19 -21
  10. data/lib/say_when/poller/base_poller.rb +108 -0
  11. data/lib/say_when/poller/celluloid_poller.rb +30 -0
  12. data/lib/say_when/poller/concurrent_poller.rb +31 -0
  13. data/lib/say_when/poller/simple_poller.rb +37 -0
  14. data/lib/say_when/processor/active_job_strategy.rb +35 -0
  15. data/lib/say_when/processor/simple_strategy.rb +13 -0
  16. data/lib/say_when/processor/test_strategy.rb +21 -0
  17. data/lib/say_when/scheduler.rb +67 -101
  18. data/lib/say_when/storage/active_record_strategy.rb +204 -0
  19. data/lib/say_when/storage/base_job.rb +96 -0
  20. data/lib/say_when/storage/memory_strategy.rb +140 -0
  21. data/lib/say_when/tasks.rb +15 -3
  22. data/lib/say_when/triggers/base.rb +3 -3
  23. data/lib/say_when/triggers/cron_strategy.rb +2 -3
  24. data/lib/say_when/triggers/instance_strategy.rb +3 -4
  25. data/lib/say_when/triggers/once_strategy.rb +3 -4
  26. data/lib/say_when/utils.rb +16 -0
  27. data/lib/say_when/version.rb +1 -1
  28. data/say_when.gemspec +10 -5
  29. data/test/minitest_helper.rb +45 -15
  30. data/test/say_when/configuration_test.rb +14 -0
  31. data/test/say_when/cron_expression_test.rb +140 -0
  32. data/test/say_when/poller/base_poller_test.rb +42 -0
  33. data/test/say_when/poller/celluloid_poller_test.rb +17 -0
  34. data/test/say_when/poller/concurrent_poller_test.rb +19 -0
  35. data/test/say_when/poller/simple_poller_test.rb +27 -0
  36. data/test/say_when/processor/active_job_strategy_test.rb +31 -0
  37. data/test/say_when/processor/simple_strategy_test.rb +15 -0
  38. data/test/say_when/scheduler_test.rb +41 -57
  39. data/test/say_when/storage/active_record_strategy_test.rb +134 -0
  40. data/test/say_when/storage/memory_strategy_test.rb +96 -0
  41. data/test/say_when/triggers/cron_strategy_test.rb +11 -0
  42. data/test/say_when/triggers/instance_strategy_test.rb +13 -0
  43. data/test/say_when/triggers/once_strategy_test.rb +2 -2
  44. data/test/say_when_test.rb +20 -0
  45. metadata +110 -36
  46. data/lib/say_when/base_job.rb +0 -96
  47. data/lib/say_when/processor/active_messaging.rb +0 -21
  48. data/lib/say_when/processor/base.rb +0 -19
  49. data/lib/say_when/processor/shoryuken.rb +0 -14
  50. data/lib/say_when/processor/simple.rb +0 -17
  51. data/lib/say_when/storage/active_record/acts.rb +0 -92
  52. data/lib/say_when/storage/active_record/job.rb +0 -100
  53. data/lib/say_when/storage/active_record/job_execution.rb +0 -14
  54. data/lib/say_when/storage/memory/base.rb +0 -36
  55. data/lib/say_when/storage/memory/job.rb +0 -53
  56. data/test/say_when/cron_expression_spec.rb +0 -74
  57. data/test/say_when/processor/active_messaging_test.rb +0 -41
  58. data/test/say_when/storage/active_record/job_test.rb +0 -90
  59. data/test/say_when/storage/memory/job_test.rb +0 -32
  60. data/test/say_when/storage/memory/trigger_test.rb +0 -54
  61. data/test/support/models.rb +0 -33
@@ -0,0 +1,96 @@
1
+ # encoding: utf-8
2
+
3
+ require 'minitest_helper'
4
+ require 'say_when/storage/memory_strategy'
5
+
6
+ describe SayWhen::Storage::MemoryStrategy do
7
+
8
+ let(:valid_attributes) {
9
+ {
10
+ trigger_strategy: :cron,
11
+ trigger_options: { expression: '0 0 12 ? * * *', time_zone: 'Pacific Time (US & Canada)' },
12
+ :name => 'Memory::Job::Test',
13
+ :group => 'Test',
14
+ :data => { foo: 'bar', result: 1 },
15
+ :job_class => 'SayWhen::Test::TestTask',
16
+ :job_method => 'execute'
17
+ }
18
+ }
19
+
20
+ let(:strategy) { SayWhen::Storage::MemoryStrategy }
21
+
22
+ let(:job) { strategy.create(valid_attributes) }
23
+
24
+ it 'job can be created' do
25
+ j = strategy.create(valid_attributes)
26
+ j.wont_be_nil
27
+ end
28
+
29
+ it 'can execute the task for the job' do
30
+ job.execute_job( { result: 1 } ).must_equal 1
31
+ end
32
+
33
+ it 'can execute the job' do
34
+ j = strategy.create(valid_attributes)
35
+ j.execute.must_equal 1
36
+ end
37
+
38
+ it 'can serialize' do
39
+ j = strategy.create(valid_attributes)
40
+ j.to_hash[:job_class].must_equal 'SayWhen::Test::TestTask'
41
+ end
42
+
43
+ it 'can acquire and release the next job' do
44
+ j = strategy.create(valid_attributes)
45
+ j.wont_be_nil
46
+ next_job = strategy.acquire_next(2.days.since)
47
+ next_job.wont_be_nil
48
+ next_job.status.must_equal "acquired"
49
+ strategy.release(next_job)
50
+ next_job.status.must_equal "waiting"
51
+ end
52
+
53
+ it 'can reset acquired jobs' do
54
+ j = strategy.create(valid_attributes)
55
+ j.status = 'acquired'
56
+ j.updated_at = 2.hours.ago
57
+ strategy.reset_acquired(3600)
58
+ j.status.must_equal 'waiting'
59
+ end
60
+
61
+ it 'can be fired' do
62
+ opts = valid_attributes[:trigger_options]
63
+ ce = SayWhen::CronExpression.new(opts[:expression], opts[:time_zone])
64
+ j = strategy.create(valid_attributes)
65
+ nfa = ce.last_fire_at(j.updated_at - 1.second)
66
+ lfa = ce.last_fire_at(nfa - 1.second)
67
+ j.next_fire_at = nfa
68
+ j.last_fire_at = lfa
69
+
70
+ now = Time.now
71
+ Time.stub(:now, now) do
72
+ strategy.fired(j, now)
73
+ j.next_fire_at.must_equal ce.next_fire_at(now)
74
+ j.last_fire_at.must_equal now
75
+ j.status.must_equal SayWhen::Storage::BaseJob::STATE_WAITING
76
+ end
77
+ end
78
+
79
+ it "can be serialized to a hash" do
80
+ j = strategy.create(valid_attributes)
81
+ strategy.serialize(j).class.must_equal Hash
82
+ end
83
+
84
+ it "can be deserialized from a hash" do
85
+ j = strategy.deserialize(valid_attributes)
86
+ j.class.must_equal SayWhen::Storage::MemoryStrategy::Job
87
+ end
88
+
89
+ it "can reset acquired jobs" do
90
+ j = strategy.create(valid_attributes)
91
+ j.status = 'acquired'
92
+ j.updated_at = 2.hours.ago
93
+ SayWhen::Storage::MemoryStrategy::Job.reset_acquired(3600)
94
+ j.status.must_equal 'waiting'
95
+ end
96
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'minitest_helper'
4
+ require 'say_when/triggers/cron_strategy'
5
+
6
+ describe SayWhen::Triggers::CronStrategy do
7
+ it 'should be constucted with a cron expression' do
8
+ t = SayWhen::Triggers::CronStrategy.new(expression: '0 0 * ? * * *', job: {})
9
+ t.wont_be_nil
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ require 'minitest_helper'
4
+ require 'say_when/triggers/instance_strategy'
5
+
6
+ describe SayWhen::Triggers::InstanceStrategy do
7
+ it 'should be constucted with next_at_method option' do
8
+ job = Minitest::Mock.new
9
+ job.expect(:scheduled, true)
10
+ t = SayWhen::Triggers::InstanceStrategy.new(next_at_method: 'test_next_at_method', job: job)
11
+ t.wont_be_nil
12
+ end
13
+ end
@@ -7,14 +7,14 @@ describe SayWhen::Triggers::OnceStrategy do
7
7
 
8
8
  it 'should be constucted with at option' do
9
9
  time_at = 1.second.ago
10
- o = SayWhen::Triggers::OnceStrategy.new({:at=>time_at})
10
+ o = SayWhen::Triggers::OnceStrategy.new(at: time_at, job: {})
11
11
  o.wont_be_nil
12
12
  o.once_at.must_equal time_at
13
13
  end
14
14
 
15
15
  it 'should return once at only once' do
16
16
  time_at = 1.second.ago
17
- o = SayWhen::Triggers::OnceStrategy.new({:at=>time_at})
17
+ o = SayWhen::Triggers::OnceStrategy.new(at: time_at, job: {})
18
18
  o.wont_be_nil
19
19
  o.next_fire_at.must_equal time_at
20
20
  o.next_fire_at(time_at + 10.second).must_be_nil
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ require 'minitest_helper'
4
+
5
+ describe SayWhen do
6
+
7
+ it 'provides a default logger' do
8
+ SayWhen.logger.wont_be_nil
9
+ end
10
+
11
+ it 'can set a new logger' do
12
+ l = Logger.new('/dev/null')
13
+ SayWhen.logger = l
14
+ l.must_equal l
15
+ end
16
+
17
+ it 'provides the scheduler' do
18
+ SayWhen.scheduler.wont_be_nil
19
+ end
20
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: say_when
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kuklewicz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-17 00:00:00.000000000 Z
11
+ date: 2017-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activerecord
28
+ name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: shoryuken
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: activemessaging
56
+ name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,21 +67,21 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: bundler
70
+ name: guard
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '1.3'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '1.3'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rake
84
+ name: guard-minitest
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: minitest
98
+ name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -109,7 +109,7 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: simplecov
112
+ name: coveralls
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
@@ -136,6 +136,62 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: activerecord
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: celluloid
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: concurrent-ruby
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: activejob
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
139
195
  description: Scheduling system for programmatically defined and stored jobs.
140
196
  email:
141
197
  - andrew@beginsinwonder.com
@@ -144,7 +200,9 @@ extensions: []
144
200
  extra_rdoc_files: []
145
201
  files:
146
202
  - ".gitignore"
203
+ - ".travis.yml"
147
204
  - Gemfile
205
+ - Guardfile
148
206
  - LICENSE
149
207
  - README.md
150
208
  - Rakefile
@@ -152,38 +210,47 @@ files:
152
210
  - lib/generators/say_when/migration/migration_generator.rb
153
211
  - lib/generators/say_when/migration/templates/migration.rb
154
212
  - lib/say_when.rb
155
- - lib/say_when/base_job.rb
213
+ - lib/say_when/configuration.rb
156
214
  - lib/say_when/cron_expression.rb
157
- - lib/say_when/processor/active_messaging.rb
158
- - lib/say_when/processor/base.rb
159
- - lib/say_when/processor/shoryuken.rb
160
- - lib/say_when/processor/simple.rb
215
+ - lib/say_when/poller/base_poller.rb
216
+ - lib/say_when/poller/celluloid_poller.rb
217
+ - lib/say_when/poller/concurrent_poller.rb
218
+ - lib/say_when/poller/simple_poller.rb
219
+ - lib/say_when/processor/active_job_strategy.rb
220
+ - lib/say_when/processor/simple_strategy.rb
221
+ - lib/say_when/processor/test_strategy.rb
161
222
  - lib/say_when/railtie.rb
162
223
  - lib/say_when/scheduler.rb
163
- - lib/say_when/storage/active_record/acts.rb
164
- - lib/say_when/storage/active_record/job.rb
165
- - lib/say_when/storage/active_record/job_execution.rb
166
- - lib/say_when/storage/memory/base.rb
167
- - lib/say_when/storage/memory/job.rb
224
+ - lib/say_when/storage/active_record_strategy.rb
225
+ - lib/say_when/storage/base_job.rb
226
+ - lib/say_when/storage/memory_strategy.rb
168
227
  - lib/say_when/tasks.rb
169
228
  - lib/say_when/triggers/base.rb
170
229
  - lib/say_when/triggers/cron_strategy.rb
171
230
  - lib/say_when/triggers/instance_strategy.rb
172
231
  - lib/say_when/triggers/once_strategy.rb
232
+ - lib/say_when/utils.rb
173
233
  - lib/say_when/version.rb
174
234
  - lib/tasks/say_when.rake
175
235
  - say_when.gemspec
176
236
  - test/active_record_helper.rb
177
237
  - test/db/schema.rb
178
238
  - test/minitest_helper.rb
179
- - test/say_when/cron_expression_spec.rb
180
- - test/say_when/processor/active_messaging_test.rb
239
+ - test/say_when/configuration_test.rb
240
+ - test/say_when/cron_expression_test.rb
241
+ - test/say_when/poller/base_poller_test.rb
242
+ - test/say_when/poller/celluloid_poller_test.rb
243
+ - test/say_when/poller/concurrent_poller_test.rb
244
+ - test/say_when/poller/simple_poller_test.rb
245
+ - test/say_when/processor/active_job_strategy_test.rb
246
+ - test/say_when/processor/simple_strategy_test.rb
181
247
  - test/say_when/scheduler_test.rb
182
- - test/say_when/storage/active_record/job_test.rb
183
- - test/say_when/storage/memory/job_test.rb
184
- - test/say_when/storage/memory/trigger_test.rb
248
+ - test/say_when/storage/active_record_strategy_test.rb
249
+ - test/say_when/storage/memory_strategy_test.rb
250
+ - test/say_when/triggers/cron_strategy_test.rb
251
+ - test/say_when/triggers/instance_strategy_test.rb
185
252
  - test/say_when/triggers/once_strategy_test.rb
186
- - test/support/models.rb
253
+ - test/say_when_test.rb
187
254
  homepage: https://github.com/kookster/say_when
188
255
  licenses:
189
256
  - MIT
@@ -204,7 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
271
  version: '0'
205
272
  requirements: []
206
273
  rubyforge_project:
207
- rubygems_version: 2.2.2
274
+ rubygems_version: 2.5.1
208
275
  signing_key:
209
276
  specification_version: 4
210
277
  summary: Scheduling system for programmatically defined and stored jobs.
@@ -212,11 +279,18 @@ test_files:
212
279
  - test/active_record_helper.rb
213
280
  - test/db/schema.rb
214
281
  - test/minitest_helper.rb
215
- - test/say_when/cron_expression_spec.rb
216
- - test/say_when/processor/active_messaging_test.rb
282
+ - test/say_when/configuration_test.rb
283
+ - test/say_when/cron_expression_test.rb
284
+ - test/say_when/poller/base_poller_test.rb
285
+ - test/say_when/poller/celluloid_poller_test.rb
286
+ - test/say_when/poller/concurrent_poller_test.rb
287
+ - test/say_when/poller/simple_poller_test.rb
288
+ - test/say_when/processor/active_job_strategy_test.rb
289
+ - test/say_when/processor/simple_strategy_test.rb
217
290
  - test/say_when/scheduler_test.rb
218
- - test/say_when/storage/active_record/job_test.rb
219
- - test/say_when/storage/memory/job_test.rb
220
- - test/say_when/storage/memory/trigger_test.rb
291
+ - test/say_when/storage/active_record_strategy_test.rb
292
+ - test/say_when/storage/memory_strategy_test.rb
293
+ - test/say_when/triggers/cron_strategy_test.rb
294
+ - test/say_when/triggers/instance_strategy_test.rb
221
295
  - test/say_when/triggers/once_strategy_test.rb
222
- - test/support/models.rb
296
+ - test/say_when_test.rb
@@ -1,96 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module SayWhen
4
- module BaseJob
5
-
6
- # ready to be run, just waiting for its turn
7
- STATE_WAITING = 'waiting'
8
-
9
- # has been acquired b/c it is time to be triggered
10
- STATE_ACQUIRED = 'acquired'
11
-
12
- # # related job for the trigger is executing
13
- # STATE_EXECUTING = 'executing'
14
-
15
- # "Complete" means the trigger has no remaining fire times
16
- STATE_COMPLETE = 'complete'
17
-
18
- # A Trigger arrives at the error state when the scheduler
19
- # attempts to fire it, but cannot due to an error creating and executing
20
- # its related job.
21
- STATE_ERROR = 'error'
22
-
23
- def lock
24
- @_lock ||= Mutex.new
25
- end
26
-
27
- def trigger
28
- @trigger ||= load_trigger
29
- end
30
-
31
- def fired(fired_at=Time.now)
32
- self.lock.synchronize {
33
- self.last_fire_at = fired_at
34
- self.next_fire_at = trigger.next_fire_at(last_fire_at + 1.second) rescue nil
35
-
36
- if next_fire_at.nil?
37
- self.status = STATE_COMPLETE
38
- else
39
- self.status = STATE_WAITING
40
- end
41
- }
42
- end
43
-
44
- def release
45
- self.lock.synchronize {
46
- if self.status == STATE_ACQUIRED
47
- self.status = STATE_WAITING
48
- end
49
- }
50
- end
51
-
52
- def execute
53
- execute_job(data)
54
- end
55
-
56
- def load_trigger
57
- strategy = trigger_strategy || :once
58
- require "say_when/triggers/#{strategy}_strategy"
59
- trigger_class_name = "SayWhen::Triggers::#{strategy.to_s.camelize}Strategy"
60
- trigger_class = trigger_class_name.constantize
61
- trigger_class.new((trigger_options || {}).merge(:job=>self))
62
- end
63
-
64
- def execute_job(options)
65
- task_method = (job_method || 'execute').to_s
66
- task = get_task(task_method)
67
- task.send(task_method, options)
68
- end
69
-
70
- def get_task(task_method)
71
- task = nil
72
-
73
- if job_class
74
- tc = job_class.constantize
75
- if tc.respond_to?(task_method)
76
- task = tc
77
- else
78
- to = tc.new
79
- if to.respond_to?(task_method)
80
- task = to
81
- else
82
- raise "Neither '#{job_class}' class nor instance respond to '#{task_method}'"
83
- end
84
- end
85
- elsif scheduled
86
- if scheduled.respond_to?(task_method)
87
- task = scheduled
88
- else
89
- raise "Scheduled '#{scheduled.inspect}' does not respond to '#{task_method}'"
90
- end
91
- end
92
- task
93
- end
94
-
95
- end
96
- end