say_when 1.0.0 → 2.0.0

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