Sidekiq isolator doesn't work if "sidekiq/testing" is required only AFTER "isolator"
timdiggins opened this issue · comments
What did you do?
Added isolator and required it at the end of my initializers
What did you expect to happen?
It would catch sidekiq calls duringt transactions in my existing specs
What actually happened?
Very few were caught (some were - perhaps to do with test ordering...)
My rspec support files were requiring "sidekiq/testing" after rails had been initialized.
When I required sidekiq/testing at the beginning of my initializer it then worked.
# config/initializers/z_isolator.rb
require "sidekiq/testing" if Rails.env.test?
unless Rails.env.production? # so we get it in staging too
require "isolator"
Isolator.configure do |config|
config.send_notifications = true
end
end
Additional context
Not 100% sure what you should do about this - could just put this in the README. It's a bit ugly to have a if Rails.env.testing? in an initializer but not the end of the world.
There may be additional context to how I'm using sidekiq testing mode (switching between fake and inline in different specs for example) but I think it's mainly when sidekiq/testing is required (and thus when it does a prepend on Sidekiq::Client)
Environment
Ruby Version:
2.7.6
Framework Version (Rails, whatever):
rails 6.0.2
Isolator Version:
0.8.0
That happens because sidekiq/testing
prepends the original client (and thus, overrides the patch made by Isolator):
https://github.com/mperham/sidekiq/blob/9feefc2d3653fc4c187ca3e46155d2736f2f3c62/lib/sidekiq/testing.rb#L89
could just put this in the README
Yeah, I think, we can add this specific caveat to the Readme. We already have a generic one:
Thus the order of loading gems matters
But here we have not just a gem, but a specific module.
There is a fix for Ruby 3+: we can patch the TestingClient module itself. But that wouldn't work in earlier versions.
Another option is to monitor new classes, and if Sidekiq::TestingClient
has been loaded, apply the patch one more time. That would be a great example of Ruby metaprogramming, but... isn't that too much?
Yeah, the metaprogramming would be very cool and clever, but sometimes stupid is best?
I think it would be good enough to mention in the README.
PS great great gem. I thought I had done all the after_commits I needed to until I installed this into a couple of projects. Suddenly: oooh that's why those sidekiq jobs sometimes fail first run... (doh!)