Open jensb opened 1 year ago
Thanks for the feedback and ideas, i've wanted something similar myself!
here's something you can try. it's hacky but i think will work, and then you can give me feedback on the API/ergonomics. when you have something you like, i'll work a nicer api into the next release.
just put this code directly into your test. no need for invoking the clock
executable
require 'ruby-clock'
require "ruby-clock/dsl"
RubyClock.detect_and_load_rails_app
require 'rufus_monkeypatch'
RubyClock.instance.listen_to_signals
RubyClock.instance.prepare_rake
RubyClock.instance.schedule.pause
RubyClock.instance.add_rails_executor_to_around_actions
# above is the beginning of exe/clock
# load your Clockfile
load 'Clockfile'
# Now, everything is loaded and paused. You can access all jobs with this.
RubyClock.instance.schedule
# You can iterate through them and check the identifier.
# read about names/identifiers/slugs in the readme
RubyClock.instance.schedule.jobs.each do |j|
puts j.name
puts j.identifier
puts j.slug
j.call
end
Thank you, this actually worked on the first attempt! Here's what I did.
load Clockfile
into a test/test_helper_rubyclock.rb
.def run_clockjob(name) = RubyClock.instance.schedule.jobs.find {|j| j.name == name }.call
require
this file in all my integration test filesrun_clockjob('every_hour')
This also works on the console:
# Clockfile
using RubyClock::DSL
every '1 minute' , name: 'every_1min' do Rails.logger.info "Clockfile is active at #{Time.now}" end
$ rails c
Loading development environment (Rails 7.0.7.2)
rb(main):001:0> load 'test/test_helper_clock.rb'
Detected rails app has been loaded.
RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS is set to 29
=> true
irb(main):002:0> RubyClock.instance.schedule.jobs.find {|j| j.name == 'every_1min' }.call
Clockfile is active at 2023-08-27 21:43:04 +0200
=> 49
Maybe we can package this into a require 'ruby-clock/tests'
for tests, and then get something like
require 'ruby-clock/tests'
test "see if we can run a clockjob inside here" do
User.create(...)
RubyClock.run('create_remote_accounts') # short, easy, to the point DSL
assert RemoteApi.login_as(...)
end
What do you think? Also, will this work when calling jobs twice or running tests in parallel? (Rake has issues here)
Nice!! Thanks so much for sharing your code, I will use this to guide me for the next release.
I gave all my clockjobs explicit names (I found no other safe way to identify them)
in case you missed it, you can check in CI that your jobs all have unique slugs, and then you can find by slug instead of name. https://github.com/jjb/ruby-clock/#testing --check-slug-uniqueness
will this work when calling jobs twice or running tests in parallel? (Rake has issues here)
regarding rake, you can use the safest invocation method, rake
, to ensure the jobs don't overlap. see the code and article linked in this section https://github.com/jjb/ruby-clock/#rake-tasks
do you also mean at the rufus-scheduler level... i think if your job is threadsafe (instance variables directly in the block are almost certainly safe... but maybe it accesses other classes that aren't threadsafe), then you should be good. let me know if you meant something else.
Hi, I started using ruby-clock in a Rails project and so far I love it, great job! I have one question though: Is it possible to directly execute specific Clockfile tasks synchronously, as in 'now'? I think this would make a lot of sense for integration testing. For example,
This way, I can not just check if my async remote APi job works well (this would be a unit test) but also if I call it at the right point and if it is included in the correct cronjob.
Is something like this possible with ruby-clock? If not, do you think it makes sense to implement it?