Title says it all really.
Is it possible to run Clockwork jobs manually? E.g. 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.