Changeset 263

Show
Ignore:
Timestamp:
12/10/07 15:15:13 (9 months ago)
Author:
gethema..@gmail.com
Message:

implement ability to schedule different worker methods

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/README

    r233 r263  
    3333 
    3434=== Configuration 
    35   Use rake task for initial configuration: 
    36  
    37  * Cron style scheduling and config 
     35Use rake task for initial configuration: 
     36 
     37* Cron style scheduling and config 
    3838 
    3939   | :backgroundrb: 
     
    4343   | :schedules: 
    4444   |   :foo_worker: 
    45    |     :worker_method: foobar 
    46    |     :trigger_args: */5 * * * * * * 
    47  
    48  * Normal Unix scheduler 
     45   |     :foobar: 
     46   |       :trigger_args: */5 * * * * * * 
     47   |       :data: Hello World 
     48   |     :barbar: 
     49   |       :trigger_args: */10 * * * * * * 
     50 
     51Above sample configuration file would schedule worker methods 'foobar' and 'barbar' 
     52to be executed at different trigger periods. 
     53 
     54NOTE: Please note that, because of addition of this feature, format of backgroundrb.yml 
     55has changed slightly and hence modify your config file according to this new option. 
     56 
     57 
     58* Normal Unix scheduler 
     59 
    4960   | :backgroundrb: 
    5061   |   :ip: localhost 
     
    5263   | :schedules: 
    5364   |   :foo_worker: 
    54    |     :worker_method: foobar 
    55    |     :trigger_args: 
    56    |        :start: <%= Time.now + 5.seconds %> 
    57    |        :end: <%= Time.now + 10.minutes %> 
    58    |        :repeat_interval: <%= 1.minute %> 
    59  
    60  * Plain config 
     65   |     :foobar: 
     66   |       :trigger_args: 
     67   |         :start: <%= Time.now + 5.seconds %> 
     68   |         :end: <%= Time.now + 10.minutes %> 
     69   |         :repeat_interval: <%= 1.minute %> 
     70 
     71* Plain config 
     72 
    6173   | :backgroundrb: 
    6274   |   :ip: 0.0.0.0 
    6375   |   :port: 11006 
    6476 
     77 
    6578=== Scheduling 
    66   There are three schemes for periodic execution and scheduling. 
    67   - Cron Scheduling 
     79 
     80There are three schemes for periodic execution and scheduling. 
     81 
     82- Cron Scheduling 
    6883    You can use configuration file for cron scheduling of workers. Method specified in configuration 
    6984    file would be called periodically. You should take care of the fact that, time gap between periodic 
     
    7186    If a method takes longer time than the time window specified, your method invocations would lag 
    7287    perpetually. 
    73   - Normal Scheduler 
     88 
     89- Normal Scheduler 
    7490    You can use second form of scheduling as shown in config file. 
    75   - add_periodic_timer method 
     91 
     92- add_periodic_timer method 
    7693    A third and very basic form of scheduling that you can use is, "add_periodic_timer" method. You can call 
    7794    method from anywhere in your worker. 
     
    8198           end 
    8299 
    83     Above snippet would register the proc for periodic execution at every 5 seconds. 
     100Above snippet would register the proc for periodic execution at every 5 seconds. 
    84101 
    85102=== A Word about Cron Scheduler 
     
    209226  For example, following code in a rails controller will start "error_worker" and schedule to run according to trigger arguments. 
    210227 
    211     MiddleMan.new_worker(:worker => :error_worker, :job_key => :hello_world, 
    212       :data => "wow_man",:schedule => { :trigger_args => "*/5 * * * * * *",:worker_method => :hello_world }) 
     228    MiddleMan.new_worker(:worker => :error_worker, :job_key => :hello_world,:data => "wow_man",:schedule => { :hello_world => { :trigger_args => "*/5 * * * * * *",:data => "hello_world" }}) 
     229 
     230  NOTE: Please note that first data argument would be passed to create method inside your worker, however 
     231  one specified under :schedule heading would be used by worker method, when its schedule comes. 
    213232 
    214233  To stop a worker, you can use: 
  • trunk/examples/foo_controller.rb

    r217 r263  
    99 
    1010  def start_worker 
    11     MiddleMan.new_worker(:worker => :error_worker, :job_key => :hello_world, :data => "wow_man",:schedule => { :trigger_args => "*/5 * * * * * *",:worker_method => :hello_world }) 
     11    MiddleMan.new_worker(:worker => :error_worker, :job_key => :hello_world,:data => "wow_man",:schedule => { :hello_world => { :trigger_args => "*/5 * * * * * *",:data => "hello_world" }}) 
    1212    render :text => "worker starterd" 
    1313  end 
     
    1616    MiddleMan.delete_worker(:worker => :error_worker, :job_key => :hello_world) 
    1717    render :text => "worker deleted" 
     18  end 
     19 
     20  def invoke_worker_method 
     21    worker_response = MiddleMan.send_request(:worker => :world_worker, :worker_method => :hello_world) 
     22    render :text => worker_response 
     23  end 
     24 
     25  def renew 
     26    MiddleMan.ask_work(:worker => :renewal_worker, :worker_method => :load_policies) 
     27    render :text => "method invoked" 
    1828  end 
    1929 
  • trunk/server/meta_worker.rb

    r262 r263  
    2727      elsif(@config_file[:schedules] && @config_file[:schedules][worker_name.to_sym]) 
    2828        @my_schedule = @config_file[:schedules][worker_name.to_sym] 
    29         load_schedule if @my_schedule 
     29        new_load_schedule if @my_schedule 
    3030      end 
    3131      if respond_to?(:create) 
     
    3939    def load_schedule_from_args 
    4040      @my_schedule = @worker_options[:schedule] 
    41       load_schedule if @my_schedule 
     41      new_load_schedule if @my_schedule 
    4242    end 
    4343 
     
    8383      end 
    8484      @run_time = @trigger.fire_time_after(Time.now).to_i 
     85    end 
     86 
     87    # new experimental scheduler 
     88    def new_load_schedule 
     89      @worker_method_triggers = { } 
     90      @my_schedule.each do |key,value| 
     91        case value[:trigger_args] 
     92        when String 
     93          cron_args = value[:trigger_args] || "0 0 0 0 0" 
     94          trigger = BackgrounDRb::CronTrigger.new(cron_args) 
     95        when Hash 
     96          trigger = BackgrounDRb::Trigger.new(value[:trigger_args]) 
     97        end 
     98        @worker_method_triggers[key] = { :trigger => trigger,:data => value[:data],:runtime => trigger.fire_time_after(Time.now).to_i } 
     99      end 
    85100    end 
    86101 
     
    137152    def connection_completed; end 
    138153 
    139     # we are overriding the function that checks for timers 
    140154    def check_for_timer_events 
    141155      super 
    142       return unless @my_schedule 
    143       if @run_time < Time.now.to_i 
    144         # self.send(@my_schedule[:worker_method]) if self.respond_to?(@my_schedule[:worker_method]) 
    145         invoke_worker_method 
    146         @run_time = @trigger.fire_time_after(Time.now).to_i 
     156      return if @worker_method_triggers.nil? or @worker_method_triggers.empty? 
     157      @worker_method_triggers.each do |key,value| 
     158        if value[:runtime] < Time.now.to_i 
     159          (t_data = value[:data]) ? send(key,t_data) : send(key) 
     160          value[:runtime] = value[:trigger].fire_time_after(Time.now).to_i 
     161        end 
    147162      end 
    148163    end 
     164 
     165    # we are overriding the function that checks for timers 
     166#     def check_for_timer_events 
     167#       super 
     168#       return unless @my_schedule 
     169#       if @run_time < Time.now.to_i 
     170#         # self.send(@my_schedule[:worker_method]) if self.respond_to?(@my_schedule[:worker_method]) 
     171#         invoke_worker_method 
     172#         @run_time = @trigger.fire_time_after(Time.now).to_i 
     173#       end 
     174#     end 
    149175 
    150176    def invoke_worker_method