urge 0.0.1 → 0.0.2
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 +8 -8
- data/lib/urge/persistence/active_record_persistence.rb +7 -13
- data/lib/urge/version.rb +1 -1
- data/lib/urge.rb +111 -4
- data/spec/aasm.sqlite3.db +0 -0
- data/spec/{lib → models}/active_record/dual_action_model_spec.rb +10 -12
- data/spec/{lib → models}/active_record/simple_model_spec.rb +40 -11
- data/spec/{lib → models}/dual_action_spec.rb +13 -13
- data/spec/{lib → models}/scheduled_spec.rb +20 -16
- data/spec/spec_helper.rb +2 -22
- metadata +10 -11
- data/lib/urge/scheduled.rb +0 -95
    
        checksums.yaml
    CHANGED
    
    | @@ -1,15 +1,15 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            !binary "U0hBMQ==":
         | 
| 3 3 | 
             
              metadata.gz: !binary |-
         | 
| 4 | 
            -
                 | 
| 4 | 
            +
                Nzg5ZjVlOTg2MWUzYWE5NTYxZTliZmE3Y2ZiOWVkMzA1N2JjMTRlNg==
         | 
| 5 5 | 
             
              data.tar.gz: !binary |-
         | 
| 6 | 
            -
                 | 
| 6 | 
            +
                MmFhZjQyZTUzYTBlNGQ2Njg4MTBiNjU0NzFkNDNjZmQ2ZTMyYjg0OQ==
         | 
| 7 7 | 
             
            !binary "U0hBNTEy":
         | 
| 8 8 | 
             
              metadata.gz: !binary |-
         | 
| 9 | 
            -
                 | 
| 10 | 
            -
                 | 
| 11 | 
            -
                 | 
| 9 | 
            +
                MzNlN2Y2M2M5ZDRmYThmOWQxZmMyYzg1N2EyN2YwOTA5NTBiZTdiNDcxYzQ2
         | 
| 10 | 
            +
                ZDg0MDhjYjU4NjExNmJhYmU5ZjRlZjQzNTZkZTk1ZjgwYTJlOWU2NTY3NTc1
         | 
| 11 | 
            +
                YTYxOWU5ZjUxNWQ4OTZiZWZkMTAzNTkzNDFiNTBlMzhjZTQ2ZmE=
         | 
| 12 12 | 
             
              data.tar.gz: !binary |-
         | 
| 13 | 
            -
                 | 
| 14 | 
            -
                 | 
| 15 | 
            -
                 | 
| 13 | 
            +
                M2FiM2I2MThjY2UxNTdiMzMyNzcwYTJiMDA0YmMxODQ1MDgwNDI1MjhlZGJk
         | 
| 14 | 
            +
                ZjYxMTQyOTVlOGJmZDViZjEwZDE1MTYyNzE5YjNjODJlNmFmZWU1MjNkOWU3
         | 
| 15 | 
            +
                MzQ2MmFiN2FhMjE1YzYzM2IxODk0YzQ4MTJkOWI3OGViNmQxZWI=
         | 
| @@ -11,10 +11,10 @@ module Urge | |
| 11 11 | 
             
                  module ClassMethods
         | 
| 12 12 |  | 
| 13 13 | 
             
                    # AR finder
         | 
| 14 | 
            -
                    def  | 
| 15 | 
            -
                      options =  | 
| 14 | 
            +
                    def urgent( name, at = DateTime.now )
         | 
| 15 | 
            +
                      options = urge_schedules[name]
         | 
| 16 16 | 
             
                      raise 'Unknown schedule' unless options
         | 
| 17 | 
            -
                      where( "#{ | 
| 17 | 
            +
                      where( "#{urge_attr_name(name)} < ?", at )
         | 
| 18 18 | 
             
                    end
         | 
| 19 19 |  | 
| 20 20 |  | 
| @@ -36,22 +36,16 @@ module Urge | |
| 36 36 | 
             
                    #   matches
         | 
| 37 37 | 
             
                    # end
         | 
| 38 38 |  | 
| 39 | 
            -
                     | 
| 40 | 
            -
             | 
| 41 | 
            -
                      now = DateTime.now
         | 
| 42 | 
            -
                      logger.debug "run_all! Time now: #{now}"
         | 
| 43 | 
            -
                      ready_to_run( now ).each do |task|
         | 
| 44 | 
            -
                        logger.debug "Task of class #{task.class.name} is about to be run! (with a bang)"
         | 
| 45 | 
            -
                        task.run!( name )
         | 
| 46 | 
            -
                      end
         | 
| 39 | 
            +
                    def urge_all!( name )
         | 
| 40 | 
            +
                      urgent( name ).each { |u| u.urge!( name ) }
         | 
| 47 41 | 
             
                    end
         | 
| 48 42 |  | 
| 49 43 | 
             
                  end
         | 
| 50 44 |  | 
| 51 45 | 
             
                  module InstanceMethods
         | 
| 52 46 |  | 
| 53 | 
            -
                    def  | 
| 54 | 
            -
                       | 
| 47 | 
            +
                    def urge!( name, options = {} )
         | 
| 48 | 
            +
                      urge( name, options )
         | 
| 55 49 | 
             
                      save!
         | 
| 56 50 | 
             
                    end
         | 
| 57 51 |  | 
    
        data/lib/urge/version.rb
    CHANGED
    
    
    
        data/lib/urge.rb
    CHANGED
    
    | @@ -1,10 +1,117 @@ | |
| 1 1 | 
             
            require 'urge/version'
         | 
| 2 | 
            -
            require 'urge/scheduled'
         | 
| 3 2 | 
             
            require 'urge/persistence'
         | 
| 4 3 |  | 
| 5 | 
            -
            # require 'urge/credit_control'
         | 
| 6 | 
            -
             | 
| 7 4 | 
             
            require 'logging'
         | 
| 8 5 |  | 
| 9 6 | 
             
            module Urge
         | 
| 10 | 
            -
             | 
| 7 | 
            +
             | 
| 8 | 
            +
              module ClassMethods
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                # def run_all( name )
         | 
| 11 | 
            +
                #   now = DateTime.now
         | 
| 12 | 
            +
                #   logger.debug "run_all. Time now: #{now}"
         | 
| 13 | 
            +
                #   ready_to_run( name, now ).each do |task|
         | 
| 14 | 
            +
                #     logger.debug "Task of class #{task.class.name} named: #{name} is about to be run"
         | 
| 15 | 
            +
                #     task.run( name )
         | 
| 16 | 
            +
                #   end
         | 
| 17 | 
            +
                # end
         | 
| 18 | 
            +
                # 
         | 
| 19 | 
            +
                # def inspect_all( name )
         | 
| 20 | 
            +
                #   now = DateTime.now
         | 
| 21 | 
            +
                #   tasks = ready_to_run( name, now )
         | 
| 22 | 
            +
                #   logger.info "inspect_queue. Time now: #{now}. The following #{tasks.size} tasks are ready to run"
         | 
| 23 | 
            +
                #   tasks.each { |task| logger.info task.inspect }
         | 
| 24 | 
            +
                #   tasks
         | 
| 25 | 
            +
                # end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def urge_logger
         | 
| 28 | 
            +
                  @@urge_logger ||= Logging.logger[self]
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def urge_schedule( name, options = {} )
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  urge_logger.info "Defining schedule: #{name}. Options: #{options}. Class: #{self.name}"
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  # Warn if a schedule with this name already exists, but don't bail out.
         | 
| 36 | 
            +
                  # It's not necessarily an error. Rails autoloading classes is an example where it's not...
         | 
| 37 | 
            +
                  urge_logger.warn "A schedule with this name already exists. Old options: #{urge_schedules[name]}" if urge_schedules[name]
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  # NEW. Set defaults. The name pf the action metod is the same as the name of the schedule, and the name of the timestamp
         | 
| 40 | 
            +
                  # attribute is likewise, but with _at appended.
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  # For example, if the schedule name is 'check_credit', the signature of the action method - unless overridden - is 
         | 
| 43 | 
            +
                  # expected to be 
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  # def check_credit( options )
         | 
| 46 | 
            +
                  # end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  # The timestamp name - unless set explicitly - is check_credit_at
         | 
| 49 | 
            +
                  options[:timestamp_name] ||= "#{name}_at"
         | 
| 50 | 
            +
                  options[:action] ||= name
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  urge_schedules[name] = options
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                def urge_schedules
         | 
| 56 | 
            +
                  @@urge_per_class_schedules ||= {}
         | 
| 57 | 
            +
                  @@urge_per_class_schedules[self.name] ||= {}
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def urge_all_schedules
         | 
| 61 | 
            +
                  @@urge_per_class_schedules
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                # private
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                def urge_attr_name( name )
         | 
| 67 | 
            +
                  raise 'Non existent schedule name' unless urge_schedules[name]
         | 
| 68 | 
            +
                  urge_schedules[name][:timestamp_name]
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              # 
         | 
| 74 | 
            +
              # 
         | 
| 75 | 
            +
              # 
         | 
| 76 | 
            +
              module InstanceMethods
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                def urgent?( name )
         | 
| 79 | 
            +
                  ts = self.send( urge_attr_name( name ) )
         | 
| 80 | 
            +
                  ts ? (DateTime.now >= ts) : false
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                def urge_reschedule( name, _when )
         | 
| 84 | 
            +
                  urge_logger.debug "ScheduledTask#reschedule about to reschedule for #{_when}"
         | 
| 85 | 
            +
                  self.send( "#{urge_attr_name(name)}=", _when )
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                # Takes action and reschedules itself. That is all, and that is enough!
         | 
| 89 | 
            +
                def urge( name, options = {} )
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  return false unless urgent?( name )
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  interval = self.send( self.class.urge_schedules[name][:action].to_sym, options )
         | 
| 94 | 
            +
                  urge_reschedule( name, interval ? interval.from_now : nil )
         | 
| 95 | 
            +
                  true
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
              private
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                def urge_attr_name( name )
         | 
| 102 | 
            +
                  self.class.urge_attr_name( name )
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
                
         | 
| 105 | 
            +
                def urge_logger
         | 
| 106 | 
            +
                  self.class.urge_logger
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
              
         | 
| 109 | 
            +
              end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
              def self.included(base)
         | 
| 112 | 
            +
                base.extend ClassMethods
         | 
| 113 | 
            +
                base.send :include, InstanceMethods
         | 
| 114 | 
            +
                Urge::Persistence.set_persistence(base)
         | 
| 115 | 
            +
              end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
            end
         | 
    
        data/spec/aasm.sqlite3.db
    CHANGED
    
    | Binary file | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 3 | 
             
            load_schema
         | 
| 4 4 |  | 
| @@ -14,10 +14,10 @@ logger = Logging.logger['simple'] | |
| 14 14 |  | 
| 15 15 | 
             
            class DualActionGuest < ActiveRecord::Base
         | 
| 16 16 |  | 
| 17 | 
            -
              include Urge | 
| 17 | 
            +
              include Urge
         | 
| 18 18 |  | 
| 19 | 
            -
              urge_schedule( :status_check,    : | 
| 20 | 
            -
              urge_schedule( :insurance_check, : | 
| 19 | 
            +
              urge_schedule( :status_check,    :timestamp_name => :status_check_at, :action => :check_status )
         | 
| 20 | 
            +
              urge_schedule( :insurance_check, :timestamp_name => :insurance_check_at, :action => :check_insurance )
         | 
| 21 21 |  | 
| 22 22 | 
             
              def status_checked?
         | 
| 23 23 | 
             
                @status_checked
         | 
| @@ -83,13 +83,13 @@ describe 'AR model with more than one schedule' do | |
| 83 83 | 
             
                    @checks = [:status_check, :insurance_check]
         | 
| 84 84 | 
             
                  end
         | 
| 85 85 |  | 
| 86 | 
            -
                  it "both checks should be  | 
| 87 | 
            -
                    @checks.each { |c| @guest.should  | 
| 86 | 
            +
                  it "both checks should be urgent" do
         | 
| 87 | 
            +
                    @checks.each { |c| @guest.should be_urgent( c ) }
         | 
| 88 88 | 
             
                  end
         | 
| 89 89 |  | 
| 90 90 | 
             
                  context "when run" do
         | 
| 91 91 | 
             
                    before(:each) do
         | 
| 92 | 
            -
                      @checks.each { |c| @guest. | 
| 92 | 
            +
                      @checks.each { |c| @guest.urge( c )}
         | 
| 93 93 | 
             
                    end
         | 
| 94 94 |  | 
| 95 95 | 
             
                    it "should result in the guest having his status and his insurance checked" do
         | 
| @@ -118,14 +118,12 @@ describe "AR finders" do | |
| 118 118 |  | 
| 119 119 | 
             
              it "should return the correct number guests ready to run" do
         | 
| 120 120 |  | 
| 121 | 
            -
                logger.info "All schedules: #{DualActionGuest.all_schedules}"
         | 
| 122 | 
            -
                
         | 
| 123 121 | 
             
                expect {
         | 
| 124 | 
            -
                  DualActionGuest. | 
| 122 | 
            +
                  DualActionGuest.urgent( :default )
         | 
| 125 123 | 
             
                }.to raise_error( RuntimeError )
         | 
| 126 124 |  | 
| 127 | 
            -
                DualActionGuest. | 
| 128 | 
            -
                DualActionGuest. | 
| 125 | 
            +
                DualActionGuest.urgent( :status_check ).should have(@count).items
         | 
| 126 | 
            +
                DualActionGuest.urgent( :insurance_check ).should have(@count).items
         | 
| 129 127 | 
             
              end
         | 
| 130 128 |  | 
| 131 129 | 
             
            end
         | 
| @@ -1,17 +1,16 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 3 | 
             
            load_schema
         | 
| 4 4 |  | 
| 5 5 | 
             
            class SimpleGuest < ActiveRecord::Base
         | 
| 6 6 |  | 
| 7 | 
            -
              include Urge | 
| 8 | 
            -
             | 
| 9 | 
            -
              urge_schedule( :default, :scheduled_for => :scheduled_for, :action => :take_action )
         | 
| 7 | 
            +
              include Urge
         | 
| 8 | 
            +
              urge_schedule( :default, :timestamp_name => :scheduled_for, :action => :take_action )
         | 
| 10 9 |  | 
| 11 10 | 
             
            private
         | 
| 12 11 |  | 
| 13 12 | 
             
              def take_action( options )
         | 
| 14 | 
            -
                logger.debug "In take_action. About to return  | 
| 13 | 
            +
                logger.debug "In take_action. About to return nil"
         | 
| 15 14 | 
             
                nil
         | 
| 16 15 | 
             
              end
         | 
| 17 16 |  | 
| @@ -52,7 +51,7 @@ describe 'Simplest active record model' do | |
| 52 51 | 
             
              end
         | 
| 53 52 |  | 
| 54 53 | 
             
              it "should be ready to run" do
         | 
| 55 | 
            -
                @guest.should  | 
| 54 | 
            +
                @guest.should be_urgent( :default )
         | 
| 56 55 | 
             
              end
         | 
| 57 56 |  | 
| 58 57 | 
             
              it "should raise an exception if an attempt is made to access a schedule that doesn't exist" do
         | 
| @@ -61,9 +60,9 @@ describe 'Simplest active record model' do | |
| 61 60 | 
             
                }.to raise_error
         | 
| 62 61 | 
             
              end
         | 
| 63 62 |  | 
| 64 | 
            -
              context "when  | 
| 63 | 
            +
              context "when urged" do
         | 
| 65 64 | 
             
                before(:each) do
         | 
| 66 | 
            -
                  @guest. | 
| 65 | 
            +
                  @guest.urge :default
         | 
| 67 66 | 
             
                end
         | 
| 68 67 |  | 
| 69 68 | 
             
                it "should not be rescheduled" do
         | 
| @@ -73,7 +72,7 @@ describe 'Simplest active record model' do | |
| 73 72 |  | 
| 74 73 | 
             
            end
         | 
| 75 74 |  | 
| 76 | 
            -
            describe " | 
| 75 | 
            +
            describe "Class method finders" do
         | 
| 77 76 |  | 
| 78 77 | 
             
              before(:each) do
         | 
| 79 78 |  | 
| @@ -85,9 +84,39 @@ describe "AR finders" do | |
| 85 84 | 
             
                end
         | 
| 86 85 | 
             
              end
         | 
| 87 86 |  | 
| 88 | 
            -
              it "should  | 
| 89 | 
            -
                SimpleGuest. | 
| 87 | 
            +
              it "should find the correct number of urgent guests" do
         | 
| 88 | 
            +
                SimpleGuest.urgent( :default ).should have(@count).items
         | 
| 90 89 | 
             
              end
         | 
| 91 90 |  | 
| 92 91 | 
             
            end
         | 
| 93 92 |  | 
| 93 | 
            +
             | 
| 94 | 
            +
            describe "AR saving. 10 guests, when scheduled" do
         | 
| 95 | 
            +
              
         | 
| 96 | 
            +
              before(:each) do
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                SimpleGuest.delete_all
         | 
| 99 | 
            +
                @count = 10
         | 
| 100 | 
            +
                @count.times do |index|
         | 
| 101 | 
            +
                  FactoryGirl.create :simple_guest, :scheduled_for => 1.day.ago
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
                
         | 
| 104 | 
            +
              end
         | 
| 105 | 
            +
              
         | 
| 106 | 
            +
              it "should return the correct number of urgent guests" do
         | 
| 107 | 
            +
                SimpleGuest.urgent( :default ).should have(@count).items
         | 
| 108 | 
            +
              end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
              context "when urged" do
         | 
| 111 | 
            +
                
         | 
| 112 | 
            +
                before(:each) do
         | 
| 113 | 
            +
                  SimpleGuest.urge_all! :default
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
                
         | 
| 116 | 
            +
                it "should have no urgent guests" do
         | 
| 117 | 
            +
                  SimpleGuest.urgent( :default ).should be_empty
         | 
| 118 | 
            +
                end
         | 
| 119 | 
            +
                
         | 
| 120 | 
            +
              end
         | 
| 121 | 
            +
              
         | 
| 122 | 
            +
            end
         | 
| @@ -1,11 +1,11 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 3 | 
             
            # 
         | 
| 4 4 | 
             
            # 
         | 
| 5 5 | 
             
            # 
         | 
| 6 6 | 
             
            class TwoTask
         | 
| 7 7 |  | 
| 8 | 
            -
              include Urge | 
| 8 | 
            +
              include Urge
         | 
| 9 9 |  | 
| 10 10 | 
             
              attr_accessor :scheduled_for_one, :scheduled_for_two
         | 
| 11 11 |  | 
| @@ -15,13 +15,13 @@ class TwoTask | |
| 15 15 | 
             
                @scheduled_for_one = attrs[:scheduled_for_one]
         | 
| 16 16 | 
             
                @scheduled_for_two = attrs[:scheduled_for_two]
         | 
| 17 17 |  | 
| 18 | 
            -
                @logger = options[:logger] || Logging.logger[' | 
| 18 | 
            +
                @logger = options[:logger] || Logging.logger['test']
         | 
| 19 19 |  | 
| 20 20 | 
             
                @actions = options[:actions]
         | 
| 21 21 | 
             
              end
         | 
| 22 22 |  | 
| 23 | 
            -
              urge_schedule( :one, : | 
| 24 | 
            -
              urge_schedule( :two, : | 
| 23 | 
            +
              urge_schedule( :one, :timestamp_name => :scheduled_for_one, :action => :take_one )
         | 
| 24 | 
            +
              urge_schedule( :two, :timestamp_name => :scheduled_for_two, :action => :take_two )
         | 
| 25 25 |  | 
| 26 26 | 
             
              def take_one( options )
         | 
| 27 27 | 
             
                @actions << :action_one
         | 
| @@ -35,7 +35,7 @@ class TwoTask | |
| 35 35 |  | 
| 36 36 | 
             
            end
         | 
| 37 37 |  | 
| 38 | 
            -
            describe Urge | 
| 38 | 
            +
            describe Urge do
         | 
| 39 39 |  | 
| 40 40 | 
             
              context "when applied to an in memory object requiring two separate actions, that object" do
         | 
| 41 41 |  | 
| @@ -53,10 +53,10 @@ describe Urge::Scheduled do | |
| 53 53 | 
             
                  @actions.should be_empty
         | 
| 54 54 | 
             
                end
         | 
| 55 55 |  | 
| 56 | 
            -
                context "when  | 
| 56 | 
            +
                context "when urged in the context of task 1" do
         | 
| 57 57 |  | 
| 58 58 | 
             
                  before(:each) do
         | 
| 59 | 
            -
                    @object. | 
| 59 | 
            +
                    @object.urge( :one )
         | 
| 60 60 | 
             
                  end
         | 
| 61 61 |  | 
| 62 62 | 
             
                  it "should produce one action" do
         | 
| @@ -70,10 +70,10 @@ describe Urge::Scheduled do | |
| 70 70 |  | 
| 71 71 | 
             
                end
         | 
| 72 72 |  | 
| 73 | 
            -
                context "when  | 
| 73 | 
            +
                context "when urged in the context of task 2" do
         | 
| 74 74 |  | 
| 75 75 | 
             
                  before(:each) do
         | 
| 76 | 
            -
                    @object. | 
| 76 | 
            +
                    @object.urge( :two )
         | 
| 77 77 | 
             
                  end
         | 
| 78 78 |  | 
| 79 79 | 
             
                  it "should produce another action" do
         | 
| @@ -87,11 +87,11 @@ describe Urge::Scheduled do | |
| 87 87 |  | 
| 88 88 | 
             
                end
         | 
| 89 89 |  | 
| 90 | 
            -
                context "when  | 
| 90 | 
            +
                context "when urged in the context of both tasks" do
         | 
| 91 91 |  | 
| 92 92 | 
             
                  before(:each) do
         | 
| 93 | 
            -
                    @object. | 
| 94 | 
            -
                    @object. | 
| 93 | 
            +
                    @object.urge( :one )
         | 
| 94 | 
            +
                    @object.urge( :two )
         | 
| 95 95 | 
             
                  end
         | 
| 96 96 |  | 
| 97 97 | 
             
                  it "should produce two actions" do
         | 
| @@ -1,38 +1,42 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 3 | 
             
            Logging.logger['simple'].tap {|logger| 
         | 
| 4 4 | 
             
              logger.add_appenders 'colourful_stdout'
         | 
| 5 5 | 
             
              logger.level = :info
         | 
| 6 6 | 
             
            }
         | 
| 7 7 |  | 
| 8 | 
            -
             | 
| 9 8 | 
             
            # 
         | 
| 10 9 | 
             
            # 
         | 
| 11 10 | 
             
            # 
         | 
| 12 11 | 
             
            class Simple
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              # By including the Urge module, we drag in all the class methods from that module
         | 
| 14 | 
            +
              include Urge
         | 
| 13 15 |  | 
| 14 | 
            -
               | 
| 15 | 
            -
              
         | 
| 16 | 
            -
              attr_accessor :scheduled_for
         | 
| 16 | 
            +
              attr_accessor :something_at
         | 
| 17 17 | 
             
              attr_reader :actions, :logger
         | 
| 18 18 |  | 
| 19 19 | 
             
              def initialize( attrs = {} )
         | 
| 20 | 
            -
                self. | 
| 20 | 
            +
                self.something_at = attrs[:something_at]
         | 
| 21 21 |  | 
| 22 22 | 
             
                @logger = Logging.logger['simple']
         | 
| 23 23 | 
             
                @actions = []
         | 
| 24 24 | 
             
              end
         | 
| 25 25 |  | 
| 26 | 
            -
              urge_schedule | 
| 26 | 
            +
              urge_schedule :something, :action => 'do_something'
         | 
| 27 27 |  | 
| 28 28 | 
             
              def do_something( options )
         | 
| 29 29 | 
             
                @actions << :foo
         | 
| 30 30 | 
             
                nil
         | 
| 31 31 | 
             
              end
         | 
| 32 32 |  | 
| 33 | 
            +
              # def self.attr_name( name )
         | 
| 34 | 
            +
              #   raise 'ILLEGAL!'
         | 
| 35 | 
            +
              # end
         | 
| 36 | 
            +
              
         | 
| 33 37 | 
             
            end
         | 
| 34 38 |  | 
| 35 | 
            -
            describe Urge | 
| 39 | 
            +
            describe Urge do
         | 
| 36 40 |  | 
| 37 41 | 
             
              context "when applied to a simple, in memory object" do
         | 
| 38 42 |  | 
| @@ -47,10 +51,10 @@ describe Urge::Scheduled do | |
| 47 51 |  | 
| 48 52 | 
             
                context "that is not scheduled" do
         | 
| 49 53 |  | 
| 50 | 
            -
                  context "when  | 
| 54 | 
            +
                  context "when urged to do something" do
         | 
| 51 55 |  | 
| 52 56 | 
             
                    before(:each) do
         | 
| 53 | 
            -
                      @object. | 
| 57 | 
            +
                      @object.urge( :something )
         | 
| 54 58 | 
             
                    end
         | 
| 55 59 |  | 
| 56 60 | 
             
                    it "should do nothing" do
         | 
| @@ -64,13 +68,13 @@ describe Urge::Scheduled do | |
| 64 68 | 
             
                context "that has been scheduled to run 1 second ago" do
         | 
| 65 69 |  | 
| 66 70 | 
             
                  before(:each) do
         | 
| 67 | 
            -
                    @object. | 
| 71 | 
            +
                    @object.something_at = 1.second.ago
         | 
| 68 72 | 
             
                  end
         | 
| 69 73 |  | 
| 70 | 
            -
                  context "when  | 
| 74 | 
            +
                  context "when urged in the correct context" do
         | 
| 71 75 |  | 
| 72 76 | 
             
                    before(:each) do
         | 
| 73 | 
            -
                      @object. | 
| 77 | 
            +
                      @object.urge( :something )
         | 
| 74 78 | 
             
                    end
         | 
| 75 79 |  | 
| 76 80 | 
             
                    it "should produce one action" do
         | 
| @@ -79,16 +83,16 @@ describe Urge::Scheduled do | |
| 79 83 | 
             
                    end
         | 
| 80 84 |  | 
| 81 85 | 
             
                    it "should not be rescheduled" do
         | 
| 82 | 
            -
                      @object. | 
| 86 | 
            +
                      @object.something_at.should be_nil
         | 
| 83 87 | 
             
                    end
         | 
| 84 88 |  | 
| 85 89 | 
             
                  end
         | 
| 86 90 |  | 
| 87 | 
            -
                  context "when  | 
| 91 | 
            +
                  context "when urged in a non existent context" do
         | 
| 88 92 |  | 
| 89 93 | 
             
                    it "should raise an error" do
         | 
| 90 94 | 
             
                      expect {
         | 
| 91 | 
            -
                        @object. | 
| 95 | 
            +
                        @object.urge( :doesnt_exist )
         | 
| 92 96 | 
             
                      }.to raise_error( RuntimeError )
         | 
| 93 97 | 
             
                    end
         | 
| 94 98 |  | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -26,7 +26,7 @@ Logging.configure do | |
| 26 26 | 
             
                )
         | 
| 27 27 | 
             
              )
         | 
| 28 28 |  | 
| 29 | 
            -
              test_loggers = %w{  | 
| 29 | 
            +
              test_loggers = %w{ test }
         | 
| 30 30 | 
             
              # test_loggers = []
         | 
| 31 31 |  | 
| 32 32 | 
             
              test_loggers.each do |name|
         | 
| @@ -40,31 +40,13 @@ end | |
| 40 40 |  | 
| 41 41 | 
             
            require 'aasm'
         | 
| 42 42 | 
             
            require 'logging'
         | 
| 43 | 
            -
            require 'urge/scheduled'
         | 
| 44 43 | 
             
            require 'active_support/time'
         | 
| 45 44 | 
             
            require 'active_record'
         | 
| 46 45 | 
             
            require 'factory_girl'
         | 
| 47 46 |  | 
| 48 47 | 
             
            FactoryGirl.find_definitions
         | 
| 49 48 |  | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
              include Urge::Scheduled
         | 
| 53 | 
            -
              
         | 
| 54 | 
            -
              attr_reader :logger
         | 
| 55 | 
            -
             | 
| 56 | 
            -
              def initialize( name, options = {} )
         | 
| 57 | 
            -
                if options[:logger]
         | 
| 58 | 
            -
                  @logger = options[:logger]
         | 
| 59 | 
            -
                else
         | 
| 60 | 
            -
                  @logger = Logging.logger['scheduled_task_test']
         | 
| 61 | 
            -
                end
         | 
| 62 | 
            -
                self.name = name
         | 
| 63 | 
            -
              end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
            end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
            ActiveRecord::Base.logger = Logging.logger['credit_control_test']
         | 
| 49 | 
            +
            ActiveRecord::Base.logger = Logging.logger['test']
         | 
| 68 50 |  | 
| 69 51 | 
             
            def load_schema
         | 
| 70 52 | 
             
              config = YAML::load( IO.read( File.dirname(__FILE__) + '/database.yml' ) )
         | 
| @@ -72,6 +54,4 @@ def load_schema | |
| 72 54 | 
             
              load( File.dirname(__FILE__) + "/schema.rb" )
         | 
| 73 55 | 
             
            end
         | 
| 74 56 |  | 
| 75 | 
            -
            class Client < ActiveRecord::Base
         | 
| 76 | 
            -
            end
         | 
| 77 57 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: urge
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Nick Adams
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2013-03- | 
| 11 | 
            +
            date: 2013-03-04 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activerecord
         | 
| @@ -110,15 +110,14 @@ files: | |
| 110 110 | 
             
            - lib/urge/persistence.rb
         | 
| 111 111 | 
             
            - lib/urge/persistence/active_record_persistence.rb
         | 
| 112 112 | 
             
            - lib/urge/persistence/base.rb
         | 
| 113 | 
            -
            - lib/urge/scheduled.rb
         | 
| 114 113 | 
             
            - lib/urge/version.rb
         | 
| 115 114 | 
             
            - spec/aasm.sqlite3.db
         | 
| 116 115 | 
             
            - spec/database.yml
         | 
| 117 116 | 
             
            - spec/factories/factory.rb
         | 
| 118 | 
            -
            - spec/ | 
| 119 | 
            -
            - spec/ | 
| 120 | 
            -
            - spec/ | 
| 121 | 
            -
            - spec/ | 
| 117 | 
            +
            - spec/models/active_record/dual_action_model_spec.rb
         | 
| 118 | 
            +
            - spec/models/active_record/simple_model_spec.rb
         | 
| 119 | 
            +
            - spec/models/dual_action_spec.rb
         | 
| 120 | 
            +
            - spec/models/scheduled_spec.rb
         | 
| 122 121 | 
             
            - spec/schema.rb
         | 
| 123 122 | 
             
            - spec/spec_helper.rb
         | 
| 124 123 | 
             
            - urge.gemspec
         | 
| @@ -149,9 +148,9 @@ test_files: | |
| 149 148 | 
             
            - spec/aasm.sqlite3.db
         | 
| 150 149 | 
             
            - spec/database.yml
         | 
| 151 150 | 
             
            - spec/factories/factory.rb
         | 
| 152 | 
            -
            - spec/ | 
| 153 | 
            -
            - spec/ | 
| 154 | 
            -
            - spec/ | 
| 155 | 
            -
            - spec/ | 
| 151 | 
            +
            - spec/models/active_record/dual_action_model_spec.rb
         | 
| 152 | 
            +
            - spec/models/active_record/simple_model_spec.rb
         | 
| 153 | 
            +
            - spec/models/dual_action_spec.rb
         | 
| 154 | 
            +
            - spec/models/scheduled_spec.rb
         | 
| 156 155 | 
             
            - spec/schema.rb
         | 
| 157 156 | 
             
            - spec/spec_helper.rb
         | 
    
        data/lib/urge/scheduled.rb
    DELETED
    
    | @@ -1,95 +0,0 @@ | |
| 1 | 
            -
            require 'logging'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Urge
         | 
| 4 | 
            -
              module Scheduled
         | 
| 5 | 
            -
                module ClassMethods
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                  def run_all( name )
         | 
| 8 | 
            -
                    now = DateTime.now
         | 
| 9 | 
            -
                    logger.debug "run_all. Time now: #{now}"
         | 
| 10 | 
            -
                    ready_to_run( name, now ).each do |task|
         | 
| 11 | 
            -
                      logger.debug "Task of class #{task.class.name} named: #{name} is about to be run"
         | 
| 12 | 
            -
                      task.run( name )
         | 
| 13 | 
            -
                    end
         | 
| 14 | 
            -
                  end
         | 
| 15 | 
            -
                    
         | 
| 16 | 
            -
                  def inspect_all( name )
         | 
| 17 | 
            -
                    now = DateTime.now
         | 
| 18 | 
            -
                    tasks = ready_to_run( name, now )
         | 
| 19 | 
            -
                    logger.info "inspect_queue. Time now: #{now}. The following #{tasks.size} tasks are ready to run"
         | 
| 20 | 
            -
                    tasks.each { |task| logger.info task.inspect }
         | 
| 21 | 
            -
                    tasks
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
                  
         | 
| 24 | 
            -
                  def logger
         | 
| 25 | 
            -
                    @@logger ||= Logging.logger[self]
         | 
| 26 | 
            -
                  end
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                  def urge_schedule( name, options = {} )
         | 
| 29 | 
            -
                    logger.info "Defining schedule: #{name}. Options: #{options}. Class: #{self.name}"
         | 
| 30 | 
            -
                    raise 'Cannot have two schedules with the same name' if schedules[name]
         | 
| 31 | 
            -
                    schedules[name] = options
         | 
| 32 | 
            -
                  end
         | 
| 33 | 
            -
                  
         | 
| 34 | 
            -
                  def schedules
         | 
| 35 | 
            -
                    @@per_class_schedules ||= {}
         | 
| 36 | 
            -
                    @@per_class_schedules[self.name] ||= {}
         | 
| 37 | 
            -
                  end
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                  def attr_name( name )
         | 
| 40 | 
            -
                    raise 'Non existent schedule name' if schedules[name].blank?
         | 
| 41 | 
            -
                    schedules[name][:scheduled_for] || "scheduled_for_#{name}"
         | 
| 42 | 
            -
                  end
         | 
| 43 | 
            -
                  
         | 
| 44 | 
            -
                  def all_schedules
         | 
| 45 | 
            -
                    @@per_class_schedules
         | 
| 46 | 
            -
                  end
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                end
         | 
| 49 | 
            -
              
         | 
| 50 | 
            -
                module InstanceMethods
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                  def ready_to_run?( name )
         | 
| 53 | 
            -
                    ts = self.send( attr_name( name ) )
         | 
| 54 | 
            -
                    ts ? (DateTime.now >= ts) : false
         | 
| 55 | 
            -
                  end
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                  def reschedule( name, _when )
         | 
| 58 | 
            -
                    logger.debug "ScheduledTask#reschedule about to reschedule for #{_when}"
         | 
| 59 | 
            -
                    self.send( "#{attr_name(name)}=", _when )
         | 
| 60 | 
            -
                  end
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                  # Takes action and reschedules itself. That is all, and that is enough!
         | 
| 63 | 
            -
                  def run( name, options = {} )
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                    return false unless ready_to_run?( name )
         | 
| 66 | 
            -
                    
         | 
| 67 | 
            -
                    logger.debug "About to call take_action_#{name}"
         | 
| 68 | 
            -
                    interval = internal_take_action( name, options )
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                    logger.debug "Action taken. Calculated run interval: #{interval ? interval : 'none - task will *not* be rescheduled'}"
         | 
| 71 | 
            -
                    reschedule( name, interval ? interval.from_now : nil )
         | 
| 72 | 
            -
                    
         | 
| 73 | 
            -
                    true
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                  end
         | 
| 76 | 
            -
             | 
| 77 | 
            -
                private
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                  def internal_take_action( name, options )
         | 
| 80 | 
            -
                    self.send( self.class.schedules[name][:action] || "take_action_#{name}".to_sym, options )
         | 
| 81 | 
            -
                  end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                  def attr_name( name )
         | 
| 84 | 
            -
                    self.class.attr_name( name )
         | 
| 85 | 
            -
                  end
         | 
| 86 | 
            -
                  
         | 
| 87 | 
            -
                end
         | 
| 88 | 
            -
              
         | 
| 89 | 
            -
                def self.included(base)
         | 
| 90 | 
            -
                  base.extend ClassMethods
         | 
| 91 | 
            -
                  base.send :include, InstanceMethods
         | 
| 92 | 
            -
                  Urge::Persistence.set_persistence(base)
         | 
| 93 | 
            -
                end
         | 
| 94 | 
            -
              end
         | 
| 95 | 
            -
            end
         |