clockwork 0.7.7 → 1.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.
- 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
|