clockwork 1.3.1 → 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.
- checksums.yaml +4 -4
 - data/README.md +29 -3
 - data/clockwork.gemspec +1 -1
 - data/lib/clockwork/database_events/event.rb +3 -2
 - data/lib/clockwork/database_events/event_collection.rb +4 -27
 - data/lib/clockwork/database_events/event_store.rb +6 -1
 - data/lib/clockwork/database_events/manager.rb +5 -1
 - data/test/database_events/support/active_record_fake.rb +4 -0
 - data/test/database_events/synchronizer_test.rb +34 -2
 - data/test/database_events/test_helpers.rb +13 -0
 - metadata +1 -1
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 6614568ab73c78b0be1866b355ba1cd288cce5a6
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: a083d36f8fc30fb7b55f86278b1fd1e3577d4915
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: dffa0ee3bcd26a2febaafebac063f71a46857001654b3748b292601f4134a9f64c0186b626bb72bc4c4d39eaec1a41e3c162d6ca5b64d53de248176854cd7915
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 169d1db6499306e74dd86c89767e92818ffcc3d55873ac9dd04ddec9fe8b2d5648cb685e1dfbac4d3ad7bff4e467fcd2046e9c4cb0c680aef079906b354fd76a
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -142,9 +142,9 @@ module Clockwork 
     | 
|
| 
       142 
142 
     | 
    
         
             
            end
         
     | 
| 
       143 
143 
     | 
    
         
             
            ```
         
     | 
| 
       144 
144 
     | 
    
         | 
| 
       145 
     | 
    
         
            -
            This tells clockwork to fetch all `ClockworkDatabaseEvent` instances from the database,  
     | 
| 
      
 145 
     | 
    
         
            +
            This tells clockwork to fetch all `ClockworkDatabaseEvent` instances from the database, and create an internal clockwork event for each one. Each clockwork event will be configured based on the instance's `frequency` and, optionally, its `at`, `name`, `if?` and `tz` methods. The code above 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 
146 
     | 
    
         | 
| 
       147 
     | 
    
         
            -
            When one of the events is ready to be run (based on it's `frequency`, `at` and  
     | 
| 
      
 147 
     | 
    
         
            +
            When one of the events is ready to be run (based on it's `frequency`, and possible `at`, `if?` and `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 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.
         
     | 
| 
       148 
148 
     | 
    
         | 
| 
       149 
149 
     | 
    
         
             
            ### Your Model Classes
         
     | 
| 
       150 
150 
     | 
    
         | 
| 
         @@ -158,10 +158,14 @@ When one of the events is ready to be run (based on it's `frequency`, `at` and p 
     | 
|
| 
       158 
158 
     | 
    
         | 
| 
       159 
159 
     | 
    
         
             
                - `frequency` returning the how frequently (in seconds) the database event should be run
         
     | 
| 
       160 
160 
     | 
    
         | 
| 
       161 
     | 
    
         
            -
                - ` 
     | 
| 
      
 161 
     | 
    
         
            +
                - `attributes` returning a hash of [attribute name] => [attribute value] values (or really anything that we can use store on registering the event, and then compare again to see if the state has changed later)
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
                - (optionally) `at` return any acceptable clockwork `:at` string
         
     | 
| 
       162 
164 
     | 
    
         | 
| 
       163 
165 
     | 
    
         
             
                - (optionally) `name` returning the name for the event (used to identify it in the Clcockwork output)
         
     | 
| 
       164 
166 
     | 
    
         | 
| 
      
 167 
     | 
    
         
            +
                - (optionally) `if?` returning either true or false, depending on whether the database event should run at the given time (this method will be passed the time as a parameter, much like the standard clockwork `:if`)
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
       165 
169 
     | 
    
         
             
                - (optionally) `tz` returning the timezone to use (default is the local timezone)
         
     | 
| 
       166 
170 
     | 
    
         | 
| 
       167 
171 
     | 
    
         
             
            #### Example Setup
         
     | 
| 
         @@ -220,6 +224,28 @@ end 
     | 
|
| 
       220 
224 
     | 
    
         
             
            ...
         
     | 
| 
       221 
225 
     | 
    
         
             
            ```
         
     | 
| 
       222 
226 
     | 
    
         | 
| 
      
 227 
     | 
    
         
            +
            #### Example use of `if?`
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
            Database events support the ability to run events if certain conditions are met. This can be used to only run events on a given day, week, or month, or really any criteria you could conceive. Best of all, these criteria e.g. which day to
         
     | 
| 
      
 230 
     | 
    
         
            +
            run it on can be attributes on your Model, and therefore change dynamically as you change the Model in the database.
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
            So for example, if you had a Model that had a `day` and `month` integer attribute, you could specify that the Database event should only run on a particular day of a particular month as follows:
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 235 
     | 
    
         
            +
            # app/models/clockwork_database_event.rb
         
     | 
| 
      
 236 
     | 
    
         
            +
            class ClockworkDatabaseEvent < ActiveRecord::Base
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
              ...
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
              def if?(time)
         
     | 
| 
      
 241 
     | 
    
         
            +
                time.day == day && time.month == month
         
     | 
| 
      
 242 
     | 
    
         
            +
              end
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
              ...
         
     | 
| 
      
 245 
     | 
    
         
            +
            end
         
     | 
| 
      
 246 
     | 
    
         
            +
            ```
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
       223 
249 
     | 
    
         
             
            Event Parameters
         
     | 
| 
       224 
250 
     | 
    
         
             
            ----------
         
     | 
| 
       225 
251 
     | 
    
         | 
    
        data/clockwork.gemspec
    CHANGED
    
    
| 
         @@ -4,12 +4,13 @@ module Clockwork 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
                class Event < Clockwork::Event
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
                  attr_accessor :event_store, : 
     | 
| 
      
 7 
     | 
    
         
            +
                  attr_accessor :event_store, :model_attributes
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                  def initialize(manager, period, job, block, event_store, options={})
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(manager, period, job, block, event_store, model_attributes, options={})
         
     | 
| 
       10 
10 
     | 
    
         
             
                    super(manager, period, job, block, options)
         
     | 
| 
       11 
11 
     | 
    
         
             
                    @event_store = event_store
         
     | 
| 
       12 
12 
     | 
    
         
             
                    @event_store.register(self, job)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @model_attributes = model_attributes
         
     | 
| 
       13 
14 
     | 
    
         
             
                  end
         
     | 
| 
       14 
15 
     | 
    
         | 
| 
       15 
16 
     | 
    
         
             
                  def name
         
     | 
| 
         @@ -14,9 +14,7 @@ module Clockwork 
     | 
|
| 
       14 
14 
     | 
    
         
             
                  def has_changed?(model)
         
     | 
| 
       15 
15 
     | 
    
         
             
                    return true if event.nil?
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                     
     | 
| 
       18 
     | 
    
         
            -
                      frequency != model.frequency ||
         
     | 
| 
       19 
     | 
    
         
            -
                        ats != model_ats(model)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    event.model_attributes != model.attributes
         
     | 
| 
       20 
18 
     | 
    
         
             
                  end
         
     | 
| 
       21 
19 
     | 
    
         | 
| 
       22 
20 
     | 
    
         
             
                  def unregister
         
     | 
| 
         @@ -27,33 +25,12 @@ module Clockwork 
     | 
|
| 
       27 
25 
     | 
    
         | 
| 
       28 
26 
     | 
    
         
             
                  attr_reader :events, :manager
         
     | 
| 
       29 
27 
     | 
    
         | 
| 
      
 28 
     | 
    
         
            +
                  # All events in the same collection (for a model instance) are equivalent
         
     | 
| 
      
 29 
     | 
    
         
            +
                  # so we can use any of them. Only their @at variable will be different,
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # but we don't care about that here.
         
     | 
| 
       30 
31 
     | 
    
         
             
                  def event
         
     | 
| 
       31 
32 
     | 
    
         
             
                    events.first
         
     | 
| 
       32 
33 
     | 
    
         
             
                  end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                  def has_name?
         
     | 
| 
       35 
     | 
    
         
            -
                    event.job_has_name?
         
     | 
| 
       36 
     | 
    
         
            -
                  end
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                  def name
         
     | 
| 
       39 
     | 
    
         
            -
                    event.name
         
     | 
| 
       40 
     | 
    
         
            -
                  end
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                  def frequency
         
     | 
| 
       43 
     | 
    
         
            -
                    event.frequency
         
     | 
| 
       44 
     | 
    
         
            -
                  end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                  def ats
         
     | 
| 
       47 
     | 
    
         
            -
                    events.collect(&:at).compact
         
     | 
| 
       48 
     | 
    
         
            -
                  end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                  def model_ats(model)
         
     | 
| 
       51 
     | 
    
         
            -
                    at_strings_for(model).collect{|at| At.parse(at) }
         
     | 
| 
       52 
     | 
    
         
            -
                  end
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                  def at_strings_for(model)
         
     | 
| 
       55 
     | 
    
         
            -
                    model.at.to_s.split(',').map(&:strip)
         
     | 
| 
       56 
     | 
    
         
            -
                  end
         
     | 
| 
       57 
34 
     | 
    
         
             
                end
         
     | 
| 
       58 
35 
     | 
    
         
             
              end
         
     | 
| 
       59 
36 
     | 
    
         
             
            end
         
     | 
| 
         @@ -112,11 +112,16 @@ module Clockwork 
     | 
|
| 
       112 
112 
     | 
    
         
             
                    options = {
         
     | 
| 
       113 
113 
     | 
    
         
             
                      :from_database => true,
         
     | 
| 
       114 
114 
     | 
    
         
             
                      :synchronizer => self,
         
     | 
| 
       115 
     | 
    
         
            -
                      :at => at_strings_for(model)
         
     | 
| 
       116 
115 
     | 
    
         
             
                    }
         
     | 
| 
       117 
116 
     | 
    
         | 
| 
      
 117 
     | 
    
         
            +
                    options[:at] = at_strings_for(model) if model.respond_to?(:at)
         
     | 
| 
      
 118 
     | 
    
         
            +
                    options[:if] = ->(time){ model.if?(time) } if model.respond_to?(:if?)
         
     | 
| 
       118 
119 
     | 
    
         
             
                    options[:tz] = model.tz if model.respond_to?(:tz)
         
     | 
| 
       119 
120 
     | 
    
         | 
| 
      
 121 
     | 
    
         
            +
                    # store the state of the model at time of registering so we can
         
     | 
| 
      
 122 
     | 
    
         
            +
                    # easily compare and determine if state has changed later
         
     | 
| 
      
 123 
     | 
    
         
            +
                    options[:model_attributes] = model.attributes
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
       120 
125 
     | 
    
         
             
                    options
         
     | 
| 
       121 
126 
     | 
    
         
             
                  end
         
     | 
| 
       122 
127 
     | 
    
         | 
| 
         @@ -10,7 +10,11 @@ module Clockwork 
     | 
|
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
                  def register(period, job, block, options)
         
     | 
| 
       12 
12 
     | 
    
         
             
                    @events << if options[:from_database]
         
     | 
| 
       13 
     | 
    
         
            -
                       
     | 
| 
      
 13 
     | 
    
         
            +
                      synchronizer = options.fetch(:synchronizer)
         
     | 
| 
      
 14 
     | 
    
         
            +
                      model_attributes = options.fetch(:model_attributes)
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                      Clockwork::DatabaseEvents::Event.
         
     | 
| 
      
 17 
     | 
    
         
            +
                        new(self, period, job, (block || handler), synchronizer, model_attributes, options)
         
     | 
| 
       14 
18 
     | 
    
         
             
                    else
         
     | 
| 
       15 
19 
     | 
    
         
             
                      Clockwork::Event.new(self, period, job, block || handler, options)
         
     | 
| 
       16 
20 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -10,8 +10,6 @@ require_relative 'test_helpers' 
     | 
|
| 
       10 
10 
     | 
    
         
             
            describe Clockwork::DatabaseEvents::Synchronizer do
         
     | 
| 
       11 
11 
     | 
    
         
             
              before do
         
     | 
| 
       12 
12 
     | 
    
         
             
                @now = Time.now
         
     | 
| 
       13 
     | 
    
         
            -
                DatabaseEventModel.delete_all
         
     | 
| 
       14 
     | 
    
         
            -
                DatabaseEventModel2.delete_all
         
     | 
| 
       15 
13 
     | 
    
         | 
| 
       16 
14 
     | 
    
         
             
                Clockwork.manager = @manager = Clockwork::DatabaseEvents::Manager.new
         
     | 
| 
       17 
15 
     | 
    
         
             
                class << @manager
         
     | 
| 
         @@ -21,6 +19,9 @@ describe Clockwork::DatabaseEvents::Synchronizer do 
     | 
|
| 
       21 
19 
     | 
    
         | 
| 
       22 
20 
     | 
    
         
             
              after do
         
     | 
| 
       23 
21 
     | 
    
         
             
                Clockwork.clear!
         
     | 
| 
      
 22 
     | 
    
         
            +
                DatabaseEventModel.delete_all
         
     | 
| 
      
 23 
     | 
    
         
            +
                DatabaseEventModel2.delete_all
         
     | 
| 
      
 24 
     | 
    
         
            +
                DatabaseEventModelWithIf.delete_all
         
     | 
| 
       24 
25 
     | 
    
         
             
              end
         
     | 
| 
       25 
26 
     | 
    
         | 
| 
       26 
27 
     | 
    
         
             
              describe "setup" do
         
     | 
| 
         @@ -254,6 +255,37 @@ describe Clockwork::DatabaseEvents::Synchronizer do 
     | 
|
| 
       254 
255 
     | 
    
         
             
                  end
         
     | 
| 
       255 
256 
     | 
    
         
             
                end
         
     | 
| 
       256 
257 
     | 
    
         | 
| 
      
 258 
     | 
    
         
            +
                describe "with model that responds to `if?`" do
         
     | 
| 
      
 259 
     | 
    
         
            +
             
     | 
| 
      
 260 
     | 
    
         
            +
                  before do
         
     | 
| 
      
 261 
     | 
    
         
            +
                    @events_run = []
         
     | 
| 
      
 262 
     | 
    
         
            +
                  end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                  describe "when model.if? is true" do
         
     | 
| 
      
 265 
     | 
    
         
            +
                    it 'runs' do
         
     | 
| 
      
 266 
     | 
    
         
            +
                      DatabaseEventModelWithIf.create(:if_state => true, :frequency => 10)
         
     | 
| 
      
 267 
     | 
    
         
            +
                      setup_sync(model: DatabaseEventModelWithIf, :every => 1.minute, :events_run => @events_run)
         
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
      
 269 
     | 
    
         
            +
                      tick_at(@now, :and_every_second_for => 9.seconds)
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
      
 271 
     | 
    
         
            +
                      assert_equal 1, @events_run.length
         
     | 
| 
      
 272 
     | 
    
         
            +
                    end
         
     | 
| 
      
 273 
     | 
    
         
            +
                  end
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
      
 275 
     | 
    
         
            +
                  describe "when model.if? is false" do
         
     | 
| 
      
 276 
     | 
    
         
            +
                    it 'does not run' do
         
     | 
| 
      
 277 
     | 
    
         
            +
                      DatabaseEventModelWithIf.create(:if_state => false, :frequency => 10, :name => 'model with if?')
         
     | 
| 
      
 278 
     | 
    
         
            +
                      setup_sync(model: DatabaseEventModelWithIf, :every => 1.minute, :events_run => @events_run)
         
     | 
| 
      
 279 
     | 
    
         
            +
             
     | 
| 
      
 280 
     | 
    
         
            +
                      tick_at(@now, :and_every_second_for => 1.minute)
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
      
 282 
     | 
    
         
            +
                      # require 'byebug'
         
     | 
| 
      
 283 
     | 
    
         
            +
                      # byebug if events_run.length > 0
         
     | 
| 
      
 284 
     | 
    
         
            +
                      assert_equal 0, @events_run.length
         
     | 
| 
      
 285 
     | 
    
         
            +
                    end
         
     | 
| 
      
 286 
     | 
    
         
            +
                  end
         
     | 
| 
      
 287 
     | 
    
         
            +
                end
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
       257 
289 
     | 
    
         
             
                describe "with task that responds to `tz`" do
         
     | 
| 
       258 
290 
     | 
    
         
             
                  before do
         
     | 
| 
       259 
291 
     | 
    
         
             
                    @events_run = []
         
     | 
| 
         @@ -55,4 +55,17 @@ end 
     | 
|
| 
       55 
55 
     | 
    
         
             
            class DatabaseEventModelWithoutName
         
     | 
| 
       56 
56 
     | 
    
         
             
              include ActiveRecordFake
         
     | 
| 
       57 
57 
     | 
    
         
             
              attr_accessor :frequency, :at
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            class DatabaseEventModelWithIf
         
     | 
| 
      
 61 
     | 
    
         
            +
              include ActiveRecordFake
         
     | 
| 
      
 62 
     | 
    
         
            +
              attr_accessor :name, :frequency, :at, :tz, :if_state
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              def name
         
     | 
| 
      
 65 
     | 
    
         
            +
                @name || "#{self.class}:#{id}"
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              def if?(time)
         
     | 
| 
      
 69 
     | 
    
         
            +
                @if_state
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
       58 
71 
     | 
    
         
             
            end
         
     |