[Help needed] `after_create_commit` raises `Isolator::BackgroundJobError`?
rwehresmann opened this issue · comments
I've been trying to test isolator
on my application, however, I keep receiving
Isolator::BackgroundJobError:
You are trying to enqueue background job inside db transaction. In case of transaction failure, this may lead to data inconsistency and unexpected bugs
Details: MyWorker ([387])
This is raised from my model (ApplicationRecord
) in a line like
after_commit :call_my_worker, on: :create
I'm opening this issue just to ask if there isn't any basic configuration I'm missing and should be aware of.
Hey,
Could you please provide more details? Rails version, Isolator version, environment in which you observe this issue (development, test, production), database configuration (multi-db or not, etc.)
Ruby v3.2.2
Rails v7.0.8
Env Test
Isolator 0.11
Multi database with postgresql
Isolator 0.11
Let's upgrade Isolator first (the latest version is 1.0.1) and see if it helps.
Multi database with postgresql
Is the model in question use the primary database or some other? That could be smth with multi-db support
Tried with 1.0.1, with no success.
Is the model in question use the primary database or some other? That could be smth with multi-db support
Yes, it uses the primary DB.
Thanks!
Okay, the next step would be running a failing test with Active Record logs and try to figure out what's going on there. Here is a quick snippet to drop into your spec_helper.rb
or test_helper.rb
:
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord.verbose_query_logs = true
Thanks for the support @palkan ! Do you know what exactly I should be looking for? The log is huge and I have sensitive data so I cannot paste it here, but what I can see regarding multiple databases (i have 3) is that it follows the pattern of:
- Select table names from a specific database:
select table_name from information_schema.views where table_schema = 'analytics_test'
- Disable triggers:
ALTER TABLE :table1 DISABLE TRIGGER ALL;
ALTER TABLE :table2 DISABLE TRIGGER ALL;
ALTER TABLE :table3 DISABLE TRIGGER ALL;
ALTER TABLE :table4 DISABLE TRIGGER ALL;
ALTER TABLE :table5 DISABLE TRIGGER ALL;
ALTER TABLE :table6 DISABLE TRIGGER ALL;
ALTER TABLE :table7 DISABLE TRIGGER ALL;
ALTER TABLE :table8 DISABLE TRIGGER ALL;
ALTER TABLE :table9 DISABLE TRIGGER ALL;
ALTER TABLE :table10 DISABLE TRIGGER ALL;
ALTER TABLE :table11 DISABLE TRIGGER ALL;
ALTER TABLE :table12 DISABLE TRIGGER ALL;
ALTER TABLE :table13 DISABLE TRIGGER ALL;
ALTER TABLE :table14 DISABLE TRIGGER ALL;
ALTER TABLE :table15 DISABLE TRIGGER ALL;
ALTER TABLE :table16 DISABLE TRIGGER ALL;
ALTER TABLE :table17 DISABLE TRIGGER ALL;
ALTER TABLE :table18 DISABLE TRIGGER ALL;
ALTER TABLE :table19 DISABLE TRIGGER ALL;
- Delete data from tables;
- Enable triggers;
- Disable triggers again
- Select tables from next database and do it all again;
- The last database is where the data will be created for the test I'm using as example, and it does all the steps except the 5 of disabling triggers once more, where it starts creating the necessary data to perform the test
Hey @rwehresmann!
Sorry for late response.
Have no good clues for now, but we can try one more debugging technique (using the latest Isolator). We can define Isolator callbacks to see how it monitors transactions:
Isolator.on_transaction_open do |event|
puts "New transaction from #{event[:connection_id]}.\n" \
"Current depth: #{event[:depth]}\n" \
"From: #{Isolator.backtrace_cleaner.call(caller).take(5).to_a.join("\n")}"
end
# This callback is called every time a transaction is completed
Isolator.on_transaction_close do |event|
puts "Transaction completed from #{event[:connection_id]}.\n" \
"Current depth: #{event[:depth]}\n" \
"From: #{Isolator.backtrace_cleaner.call(caller).take(5).to_a.join("\n")}"
end