clockwork 0.7.7 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +55 -48
- data/Rakefile +1 -1
- data/clockwork.gemspec +1 -1
- data/clockworkd.1 +62 -0
- data/lib/clockwork/at.rb +5 -1
- data/lib/clockwork/database_events.rb +26 -0
- data/lib/clockwork/database_events/event.rb +38 -0
- data/lib/clockwork/database_events/manager.rb +20 -0
- data/lib/clockwork/database_events/registry.rb +39 -0
- data/lib/clockwork/database_events/sync_performer.rb +94 -0
- data/test/database_events/sync_performer_test.rb +283 -0
- data/test/database_events/test_helpers.rb +101 -0
- metadata +36 -52
- data/lib/clockwork/manager_with_database_tasks.rb +0 -150
- data/test/manager_with_database_tasks_test.rb +0 -292
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7deeb150ded639846749af6efb04b31157dc430f
|
4
|
+
data.tar.gz: d97f85b001f54997b6c5fd5f2c160da31c8d0a73
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b6d0b9c662b085d8243aaa23e00fc1c4549810ec3d346ce0b789eef518f7c839ea830d9c8ec7b785d33cdce81a3587e13b097673cd5ca3e133e40f8133007edb
|
7
|
+
data.tar.gz: b162bd32440586badc9156aa06738bda2ad581474d23bf7daf946d8c8a6aa7e55d6e63129ebd9776dc100bc02a2bfae02b21b06f31d3510968c0410f1c724f53
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2010-2014 Adam Wiggins, tomykaira <tomykaira@gmail.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -103,50 +103,70 @@ every(1.hour, 'feeds.refresh') { Feed.send_later(:refresh) }
|
|
103
103
|
every(1.day, 'reminders.send', :at => '01:30') { Reminder.send_later(:send_reminders) }
|
104
104
|
```
|
105
105
|
|
106
|
-
Use with database
|
106
|
+
Use with database events
|
107
107
|
-----------------------
|
108
108
|
|
109
|
-
|
109
|
+
In addition to managing static events in your `clock.rb`, you can configure clockwork to synchronise with dynamic events from a database. Like static events, these database-backed events say when they should be run, and how frequently; the difference being that if you change those settings in the database, they will be reflected in clockwork.
|
110
110
|
|
111
|
-
To
|
111
|
+
To keep the database events in sync with clockwork, a special manager class `DatabaseEvents::Manager` is used. You tell it to sync a database-backed model using the `sync_database_events` method, and then, at the frequency you specify, it will fetch all the events from the database, and ensure clockwork is using the latest settings.
|
112
|
+
|
113
|
+
### Example `clock.rb` file
|
114
|
+
|
115
|
+
Here we're using an `ActiveRecord` model called `ClockworkDatabaseEvent` to store events in the database:
|
112
116
|
|
113
117
|
```ruby
|
114
118
|
require 'clockwork'
|
115
|
-
require 'clockwork/
|
119
|
+
require 'clockwork/manager_with_database_events'
|
116
120
|
require_relative './config/boot'
|
117
121
|
require_relative './config/environment'
|
118
|
-
|
122
|
+
|
119
123
|
module Clockwork
|
120
124
|
|
121
125
|
# required to enable database syncing support
|
122
|
-
Clockwork.manager =
|
126
|
+
Clockwork.manager = DatabaseEvents::Manager.new
|
123
127
|
|
124
|
-
|
125
|
-
# Where your model will acts as a worker:
|
126
|
-
id = instance_job_name.split(':').last
|
127
|
-
task = MyScheduledTask.find(id)
|
128
|
-
task.perform_async
|
128
|
+
sync_database_events model: ClockworkDatabaseEvent, every: 1.minute do |model_instance|
|
129
129
|
|
130
|
-
#
|
131
|
-
|
130
|
+
# do some work e.g...
|
131
|
+
|
132
|
+
# running a DelayedJob task, where #some_action is a method
|
133
|
+
# you've defined on the model, which does the work you need
|
134
|
+
model_instance.delay.some_action
|
135
|
+
|
136
|
+
# performing some work with Sidekiq
|
137
|
+
YourSidekiqWorkerClass.perform_async
|
132
138
|
end
|
133
139
|
|
134
|
-
[
|
140
|
+
[other events if you have]
|
135
141
|
|
136
142
|
end
|
137
143
|
```
|
138
144
|
|
139
|
-
This tells clockwork to fetch all
|
145
|
+
This tells clockwork to fetch all `ClockworkDatabaseEvent` instances from the database, creating an internal clockwork event for each one, configured based on the instance's `frequency`, `at` and optionally `name` and `tz` methods. It also says to reload the events from the database every `1.minute`; we need pick up any changes in the database frequently (choose a sensible reload frequency by changing the `every:` option).
|
146
|
+
|
147
|
+
When one of the events is ready to be run (based on it's `frequency`, `at` and possible `tz` methods), clockwork arranges for the block passed to `sync_database_events` to be run. The above example shows how you could use either DelayedJob or Sidekiq to simply kick off a worker job. This approach is good because the ideal is to use clockwork as a simple scheduler, and avoid making it carry out any long-running tasks.
|
140
148
|
|
141
|
-
|
149
|
+
### Your Model Classes
|
150
|
+
|
151
|
+
`ActiveRecord` models are a perfect candidate for the model class. Having said that, the only requirements are:
|
142
152
|
|
143
153
|
1. the class responds to `all` returning an array of instances from the database
|
154
|
+
|
144
155
|
2. the instances returned respond to:
|
145
|
-
`frequency` returning the how frequently (in seconds) the database task should be run
|
146
|
-
`name` returning the task's job name (this is what gets passed into the block above)
|
147
|
-
`at` return nil or `''` if not using `:at`, or otherwise any acceptable clockwork `:at` string
|
148
156
|
|
149
|
-
|
157
|
+
- `id` returning a unique identifier (this is needed to track changes to event settings)
|
158
|
+
|
159
|
+
- `frequency` returning the how frequently (in seconds) the database event should be run
|
160
|
+
|
161
|
+
- `at` return nil or `''` if not using `:at`, or otherwise any acceptable clockwork `:at` string
|
162
|
+
|
163
|
+
- (optionally) `name` returning the name for the event (used to identify it in the Clcockwork output)
|
164
|
+
|
165
|
+
- (optionally) `tz` returning the timezone to use (default is the local timezone)
|
166
|
+
|
167
|
+
#### Example Setup
|
168
|
+
|
169
|
+
Here's an example of one way of setting up your ActiveRecord models:
|
150
170
|
|
151
171
|
```ruby
|
152
172
|
# db/migrate/20140302220659_create_frequency_periods.rb
|
@@ -160,45 +180,30 @@ class CreateFrequencyPeriods < ActiveRecord::Migration
|
|
160
180
|
end
|
161
181
|
end
|
162
182
|
|
163
|
-
#
|
164
|
-
class
|
183
|
+
# 20140302221102_create_clockwork_database_events.rb
|
184
|
+
class CreateClockworkDatabaseEvents < ActiveRecord::Migration
|
165
185
|
def change
|
166
|
-
create_table :
|
186
|
+
create_table :clockwork_database_events do |t|
|
167
187
|
t.integer :frequency_quantity
|
168
188
|
t.references :frequency_period
|
169
189
|
t.string :at
|
170
190
|
|
171
191
|
t.timestamps
|
172
192
|
end
|
173
|
-
add_index :
|
193
|
+
add_index :clockwork_database_events, :frequency_period_id
|
174
194
|
end
|
175
195
|
end
|
176
196
|
|
177
|
-
# app/models/
|
178
|
-
class
|
179
|
-
include Sidekiq::Worker
|
180
|
-
|
197
|
+
# app/models/clockwork_database_event.rb
|
198
|
+
class ClockworkDatabaseEvent < ActiveRecord::Base
|
181
199
|
belongs_to :frequency_period
|
182
|
-
attr_accessible :frequency_quantity, :frequency_period_id, :at
|
200
|
+
attr_accessible :frequency_quantity, :frequency_period_id, :at
|
183
201
|
|
184
|
-
# Used by clockwork to schedule how frequently this
|
202
|
+
# Used by clockwork to schedule how frequently this event should be run
|
185
203
|
# Should be the intended number of seconds between executions
|
186
204
|
def frequency
|
187
205
|
frequency_quantity.send(frequency_period.name.pluralize)
|
188
206
|
end
|
189
|
-
|
190
|
-
# Used by clockwork to name this task internally for its logging
|
191
|
-
# Should return a reference for this task to be used in clockwork
|
192
|
-
# Include the instance ID if you want to be able to retrieve the
|
193
|
-
# model instance inside the sync_database_tasks block in clock.rb
|
194
|
-
def name
|
195
|
-
"Database_MyScheduledTask:#{id}"
|
196
|
-
end
|
197
|
-
|
198
|
-
# Method required by Sidekiq
|
199
|
-
def perform
|
200
|
-
# the task that will be performed in the background
|
201
|
-
end
|
202
207
|
end
|
203
208
|
|
204
209
|
# app/models/frequency_period.rb
|
@@ -215,8 +220,6 @@ end
|
|
215
220
|
...
|
216
221
|
```
|
217
222
|
|
218
|
-
You could, of course, create a separate Sidekiq or DelayedJob worker class under app/workers, and simply use the model referenced by clockwork to trigger that worker to run asynchronously.
|
219
|
-
|
220
223
|
Event Parameters
|
221
224
|
----------
|
222
225
|
|
@@ -297,7 +300,11 @@ Clockwork.every(1.second, 'myjob', :if => lambda { |_| true })
|
|
297
300
|
|
298
301
|
### :thread
|
299
302
|
|
300
|
-
|
303
|
+
In default, clockwork runs in single-process, single-thread.
|
304
|
+
If an event handler takes long time, the main routine of clockwork is blocked until it ends.
|
305
|
+
Clockwork does not misbehave, but the next event is blocked, and runs when the process is returned to the clockwork routine.
|
306
|
+
|
307
|
+
This `:thread` option is to avoid blocking. An event with `:thread => true` runs in a different thread.
|
301
308
|
|
302
309
|
```ruby
|
303
310
|
Clockwork.every(1.day, 'run.me.in.new.thread', :thread => true)
|
@@ -441,12 +448,12 @@ end
|
|
441
448
|
Finally, you can use tasks synchronised from a database as described in detail above:
|
442
449
|
|
443
450
|
```ruby
|
444
|
-
|
451
|
+
sync_database_events model: MyEvent, every: 1.minute do |instance_job_name|
|
445
452
|
# what to do with each instance
|
446
453
|
end
|
447
454
|
```
|
448
455
|
|
449
|
-
You can use multiple `
|
456
|
+
You can use multiple `sync_database_events` if you wish, so long as you use different model classes for each (ActiveRecord Single Table Inheritance could be a good idea if you're doing this).
|
450
457
|
|
451
458
|
In production
|
452
459
|
-------------
|
data/Rakefile
CHANGED
data/clockwork.gemspec
CHANGED
data/clockworkd.1
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
.TH CLOCKWORKD 1 "August 2014" "Ruby Gem" "clockwork"
|
2
|
+
|
3
|
+
.SH NAME
|
4
|
+
clockworkd - daemon executing clockwork scripts
|
5
|
+
|
6
|
+
.SH SYNOPSIS
|
7
|
+
\fBclockworkd\fR [-c \fIFILE\fR] [\fIOPTIONS\fR] {start|stop|restart|run}
|
8
|
+
|
9
|
+
.SH DESCRIPTION
|
10
|
+
\fBclockworkd\fR executes clockwork script as a daemon.
|
11
|
+
|
12
|
+
You will need the \fBdaemons\fR gem to use \fBclockworkd\fR. It is not automatically installed, please install by yourself.
|
13
|
+
|
14
|
+
.SH OPTIONS
|
15
|
+
.TP
|
16
|
+
\fB--pid-dir\fR=\fIDIR\fR
|
17
|
+
Alternate directory in which to store the process ids. Default is \fIGEM_LOCATION\fR/tmp.
|
18
|
+
|
19
|
+
.TP
|
20
|
+
\fB-i\fR, \fB--identifier\fR=\fISTR\fR
|
21
|
+
An identifier for the process. Default is clock file name.
|
22
|
+
|
23
|
+
.TP
|
24
|
+
\fB-l\fR, \fB--log\fR
|
25
|
+
Redirect both STDOUT and STDERR to a logfile named clockworkd[.\fIidentifier\fR].output in the pid-file directory.
|
26
|
+
|
27
|
+
.TP
|
28
|
+
\fB--log-dir\fR=\fIDIR\fR
|
29
|
+
A specific directory to put the log files into. Default location is pid directory.
|
30
|
+
|
31
|
+
.TP
|
32
|
+
\fB-m\fR, \fB--monitor\fR
|
33
|
+
Start monitor process.
|
34
|
+
|
35
|
+
.TP
|
36
|
+
\fB-c\fR, \fB--clock\fR=\fIFILE\fR
|
37
|
+
Clock .rb file. Default is \fIGEM_LOCATION\fR/clock.rb.
|
38
|
+
|
39
|
+
.TP
|
40
|
+
\fB-d\fR, \fB--dir\fR=\fIDIR\fR
|
41
|
+
Directory to change to once the process starts
|
42
|
+
|
43
|
+
.TP
|
44
|
+
\fB-h\fR, \fB--help\fR
|
45
|
+
Show help message.
|
46
|
+
|
47
|
+
.SH BUGS
|
48
|
+
If you find a bug, please create an issue \fIhttps://github.com/tomykaira/clockwork/issues\fR.
|
49
|
+
|
50
|
+
For a bug fix or a feature request, please send a pull-request. Do not forget to add tests to show how your feature works, or what bug is fixed. All existing tests and new tests must pass (TravisCI is watching).
|
51
|
+
|
52
|
+
.SH AUTHORS
|
53
|
+
Created by Adam Wiggins.
|
54
|
+
|
55
|
+
Inspired by rufus-scheduler and resque-scheduler.
|
56
|
+
|
57
|
+
Design assistance from Peter van Hardenberg and Matthew Soldo.
|
58
|
+
|
59
|
+
Patches contributed by Mark McGranaghan and Lukáš Konarovský.
|
60
|
+
|
61
|
+
.SH SEE ALSO
|
62
|
+
\fIhttps://github.com/tomykaira/clockwork\fR.
|
data/lib/clockwork/at.rb
CHANGED
@@ -33,7 +33,7 @@ module Clockwork
|
|
33
33
|
raise FailedToParse, at
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
attr_accessor :min, :hour, :wday
|
37
37
|
|
38
38
|
def initialize(min, hour=NOT_SPECIFIED, wday=NOT_SPECIFIED)
|
39
39
|
@min = min
|
@@ -48,6 +48,10 @@ module Clockwork
|
|
48
48
|
(@wday == NOT_SPECIFIED or t.wday == @wday)
|
49
49
|
end
|
50
50
|
|
51
|
+
def == other
|
52
|
+
@min == other.min && @hour == other.hour && @wday == other.wday
|
53
|
+
end
|
54
|
+
|
51
55
|
private
|
52
56
|
def valid?
|
53
57
|
@min == NOT_SPECIFIED || (0..59).cover?(@min) &&
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'database_events/event'
|
2
|
+
require_relative 'database_events/sync_performer'
|
3
|
+
require_relative 'database_events/registry'
|
4
|
+
require_relative 'database_events/manager'
|
5
|
+
|
6
|
+
# TERMINOLOGY
|
7
|
+
#
|
8
|
+
# For clarity, we have chosen to define terms as follows for better communication in the code, and when
|
9
|
+
# discussing the database event implementation.
|
10
|
+
#
|
11
|
+
# "Event": "Native" Clockwork events, whether Clockwork::Event or Clockwork::DatabaseEvents::Event
|
12
|
+
# "Model": Database-backed model instances representing events to be created in Clockwork
|
13
|
+
|
14
|
+
module Clockwork
|
15
|
+
|
16
|
+
module Methods
|
17
|
+
def sync_database_events(options={}, &block)
|
18
|
+
DatabaseEvents::SyncPerformer.setup(options, &block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
extend Methods
|
23
|
+
|
24
|
+
module DatabaseEvents
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Clockwork
|
2
|
+
|
3
|
+
module DatabaseEvents
|
4
|
+
|
5
|
+
class Event < Clockwork::Event
|
6
|
+
|
7
|
+
attr_accessor :sync_performer, :at
|
8
|
+
|
9
|
+
def initialize(manager, period, job, block, sync_performer, options={})
|
10
|
+
super(manager, period, job, block, options)
|
11
|
+
@sync_performer = sync_performer
|
12
|
+
@sync_performer.register(self, job)
|
13
|
+
end
|
14
|
+
|
15
|
+
def name
|
16
|
+
(job.respond_to?(:name) && job.name) ? job.name : "#{job.class}:#{job.id}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
name
|
21
|
+
end
|
22
|
+
|
23
|
+
def name_or_frequency_has_changed?(model)
|
24
|
+
name_has_changed?(model) || frequency_has_changed?(model)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def name_has_changed?(model)
|
29
|
+
!job.respond_to?(:name) || job.name != model.name
|
30
|
+
end
|
31
|
+
|
32
|
+
def frequency_has_changed?(model)
|
33
|
+
@period != model.frequency
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Clockwork
|
2
|
+
|
3
|
+
module DatabaseEvents
|
4
|
+
|
5
|
+
class Manager < Clockwork::Manager
|
6
|
+
|
7
|
+
def unregister(event)
|
8
|
+
@events.delete(event)
|
9
|
+
end
|
10
|
+
|
11
|
+
def register(period, job, block, options)
|
12
|
+
@events << if options[:from_database]
|
13
|
+
Clockwork::DatabaseEvents::Event.new(self, period, job, (block || handler), options.fetch(:sync_performer), options)
|
14
|
+
else
|
15
|
+
Clockwork::Event.new(self, period, job, block || handler, options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Clockwork
|
2
|
+
|
3
|
+
module DatabaseEvents
|
4
|
+
|
5
|
+
class Registry
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@events = Hash.new []
|
9
|
+
end
|
10
|
+
|
11
|
+
def register(event, model)
|
12
|
+
@events[model.id] = @events[model.id] + [event]
|
13
|
+
end
|
14
|
+
|
15
|
+
def unregister(model)
|
16
|
+
unregister_by_id(model.id)
|
17
|
+
end
|
18
|
+
|
19
|
+
def unregister_by_id(id)
|
20
|
+
@events[id].each{|e| Clockwork.manager.unregister(e) }
|
21
|
+
@events.delete(id)
|
22
|
+
end
|
23
|
+
|
24
|
+
def unregister_all_except(ids)
|
25
|
+
(@events.keys - ids).each{|id| unregister_by_id(id) }
|
26
|
+
end
|
27
|
+
|
28
|
+
# all events of same id will have same frequency/name, just different ats
|
29
|
+
def event_for(model)
|
30
|
+
events_for(model).first
|
31
|
+
end
|
32
|
+
|
33
|
+
def events_for(model)
|
34
|
+
@events[model.id]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative '../database_events'
|
2
|
+
|
3
|
+
module Clockwork
|
4
|
+
|
5
|
+
module DatabaseEvents
|
6
|
+
|
7
|
+
class SyncPerformer
|
8
|
+
|
9
|
+
PERFORMERS = []
|
10
|
+
|
11
|
+
def self.setup(options={}, &block)
|
12
|
+
model_class = options.fetch(:model) { raise KeyError, ":model must be set to the model class" }
|
13
|
+
every = options.fetch(:every) { raise KeyError, ":every must be set to the database sync frequency" }
|
14
|
+
|
15
|
+
sync_performer = self.new(model_class, &block)
|
16
|
+
|
17
|
+
# create event that syncs clockwork events with events coming from database-backed model
|
18
|
+
Clockwork.manager.every every, "sync_database_events_for_model_#{model_class}" do
|
19
|
+
sync_performer.sync
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(model_class, &proc)
|
24
|
+
@model_class = model_class
|
25
|
+
@block = proc
|
26
|
+
@database_event_registry = Registry.new
|
27
|
+
|
28
|
+
PERFORMERS << self
|
29
|
+
end
|
30
|
+
|
31
|
+
# delegates to Registry
|
32
|
+
def register(event, model)
|
33
|
+
@database_event_registry.register(event, model)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Ensure clockwork events reflect events from database-backed model
|
37
|
+
# Adds any new events, modifies updated ones, and delets removed ones
|
38
|
+
def sync
|
39
|
+
model_ids_that_exist = []
|
40
|
+
|
41
|
+
@model_class.all.each do |model|
|
42
|
+
model_ids_that_exist << model.id
|
43
|
+
if are_different?(@database_event_registry.event_for(model), model)
|
44
|
+
create_or_recreate_event(model)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
@database_event_registry.unregister_all_except(model_ids_that_exist)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
def are_different?(event, model)
|
52
|
+
return true if event.nil?
|
53
|
+
event.name_or_frequency_has_changed?(model) || ats_have_changed?(model)
|
54
|
+
end
|
55
|
+
|
56
|
+
def ats_have_changed?(model)
|
57
|
+
model_ats = ats_array_for_event(model)
|
58
|
+
event_ats = ats_array_from_model(model)
|
59
|
+
|
60
|
+
model_ats != event_ats
|
61
|
+
end
|
62
|
+
|
63
|
+
def ats_array_for_event(model)
|
64
|
+
@database_event_registry.events_for(model).collect{|event| event.at }.compact
|
65
|
+
end
|
66
|
+
|
67
|
+
def ats_array_from_model(model)
|
68
|
+
(at_strings_for(model) || []).collect{|at| At.parse(at) }
|
69
|
+
end
|
70
|
+
|
71
|
+
def at_strings_for(model)
|
72
|
+
model.at.to_s.empty? ? nil : model.at.split(',').map(&:strip)
|
73
|
+
end
|
74
|
+
|
75
|
+
def create_or_recreate_event(model)
|
76
|
+
if @database_event_registry.event_for(model)
|
77
|
+
@database_event_registry.unregister(model)
|
78
|
+
end
|
79
|
+
|
80
|
+
options = {
|
81
|
+
:from_database => true,
|
82
|
+
:sync_performer => self,
|
83
|
+
:at => at_strings_for(model)
|
84
|
+
}
|
85
|
+
|
86
|
+
options[:tz] = model.tz if model.respond_to?(:tz)
|
87
|
+
|
88
|
+
# we pass actual model instance as the job, rather than just name
|
89
|
+
Clockwork.manager.every model.frequency, model, options, &@block
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|