Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActiveRecord connection returned to the pool prematurely when nesting que jobs #411

Open
tomgi opened this issue Jan 4, 2024 · 0 comments

Comments

@tomgi
Copy link
Contributor

tomgi commented Jan 4, 2024

Hey, we run into a problem when combining que, active_record and PG advisory_lock in a highly concurrent environment.

The active database connection is being released back to the pool immediately when a que job is scheduled from within another que job.

Consider the following sample jobs:

class TestQueJob < Que::Job
  def run(id)
    conn = ::ActiveRecord::Base.connection

    TestQueJob2.enqueue    

    if conn != ::ActiveRecord::Base.connection
      raise "Connection changed"
    end
  end
end

class TestQueJob2 < Que::Job
  def run; end
end

When executed in a highly concurrent environment, it’s possible that the raise will be triggered.

If that happens inside of non-transactional advisory_lock, then it’s possible that when you try to release your lock, you will be given a different connection than was used to obtain that lock, e.g.

class TestQueJob < Que::Job
  def run(id)
    ActiveRecord::Base.connection.execute("SELECT pg_advisory_lock(#{id})")

    TestQueJob2.enqueue    

    ActiveRecord::Base.connection.execute("SELECT pg_advisory_unlock(#{id})")
  end
end

In that case, you can end up with a lock that is never released, or more specifically, released by the PG server when the que process exits and the connection is disconnected.

This is a problem for us, because we use advisory locks to synchronize access to specific DB records, which causes some jobs to be stuck until the que process is restarted.

I've done some digging and I'm planning to submit a PR with a fix proposal shortly 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant