简体   繁体   中英

How can I run a Clockwork job manually?

Title says it all really.

Is it possible to run Clockwork jobs manually? Eg if I have a clock.rb file

module Clockwork
  every(15.minutes, 'api.sync_shifts') do
    Shift.sync
  end

  on(:after_run) do |event, t|
    REDIS.hset("clockwork:last_run", event.job, t)
  end
end

I'd like to be able to call something like Clockwork.run('api.sync_shifts') .

I looked through the clockwork source and didn't see anything useful. Obviously, I can run, in this example, the Shift.sync method manually, but then I'd lose my after_run/before_run callbacks that I'm using to monitor my job statuses.

No, this is not possible.

This is the relevant method in the clockwork gem that handles callbacks and runs configured events:

def tick(t=Time.now)
  if (fire_callbacks(:before_tick))
    events = events_to_run(t)
    events.each do |event|
      if (fire_callbacks(:before_run, event, t))
        event.run(t)
        fire_callbacks(:after_run, event, t)
      end
    end
  end
  fire_callbacks(:after_tick)
  events
end

This method loads all events that should run at the current time (returned from the events_to_run method). It iterates over all events in events_to_run and fires callbacks and runs the event .

To be able to run individual events and still have all callbacks fired, this method would need to change to something like this:

def tick(t=Time.now)
  if (fire_callbacks(:before_tick))
    events = events_to_run(t)
    events.each do |event|
      run_event_with_callbacks(event)
    end
  end
  fire_callbacks(:after_tick)
  events
end

def run_event_with_callbacks(event)
  if (fire_callbacks(:before_run, event, t))
    event.run(t)
      fire_callbacks(:after_run, event, t)
    end
  end
end

That would allow running individual events with firing callbacks. Furthermore, you would need a method to load an individual event. Perhaps something like this:

def load_event(job)
  # finds only the first event when there are multiple 
  # events registered for the same job
  @events.find { |event| event.job == job }
end

But since the events are registered in a Manager , you would need an instance of a manager which is correctly initialized with all events defined in the config.

To keep a long story short: This is not possible at the moment and it would need many changes to the structure of the code to make that possible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM