I have an application that uses a third party service. My application can create authentication for that service which it stores in the DB. That authentication can't be committed in the same transaction because it needs to be in the DB to be used. To make this work, I open a thread to create a new DB connection and commit the authentication record immediately
I seem to be running into a problem by using this thread. Without the thread, all the code runs smoothly, everything works up until I have to use the auth, and then I get a 401 because it isn't in the DB yet
Below you can follow what is happening. When I create a user, it triggers different callbacks until you get to run_backround_job
. It seems to hang on perform_later
. When I remove the thread code and have it execute immediately, everything works. But for some reason it get's stuck on queueing a job if it is in a separate thread.
Here's code that represents what is happening:
class User < ApplicationRecord
belongs_to :organization
after_create :use_auth
def use_auth
organization.find_or_create_auth
end
end
class Organization < ApplicationRecord
has_many :authentications
has_many :users
def find_or_create_auth
Thread.new do
ApplicationRecord.connection_pool.with_connection do
authentications.find_or_create_by(name: name)
end
end.join.value
end
end
class Authentication < ApplicationRecord
belongs_to :organization
after_create :run_background_job
def run_background_job
AuthBackgroundJob.perform_later(id)
end
end
rails (5.0.0) puma (3.6.0) sidekiq (4.1.4)
Use after_commit :run_background_job
.