temporarily_release_connection.rb

lib/sequel/extensions/temporarily_release_connection.rb
Last Update: 2024-05-06 12:06:37 -0700

The temporarily_release_connection extension adds support for temporarily releasing a checked out connection back to the connection pool. It is designed for use in multithreaded transactional integration tests, allowing a connection to start a transaction in one thread, but be temporarily released back to the connection pool, so it can be operated on safely by multiple threads inside a block. For example, the main thread could be running tests that send web requests, and a separate thread running a web server that is responding to those requests, and the same connection and transaction would be used for both.

To load the extension into the database:

DB.extension :temporarily_release_connection

After the extension is loaded, call the temporarily_release_connection method with the connection object to temporarily release the connection back to the pool. Example:

DB.transaction(rollback: :always, auto_savepoint: true) do |conn|
  DB.temporarily_release_connection(conn) do
    # Other threads can operate on connection safely inside the transaction
    yield
  end
end

For sharded connection pools, the second argument to temporarily_release_connection is respected, and specifies the server on which to temporarily release the connection.

The temporarily_release_connection extension is only supported with the threaded and timed_queue connection pools that ship with Sequel (and the sharded versions of each). To make sure that same connection object can be reacquired, it is only supported if the maximum connection pool size is 1, so set the Database :max_connections option to 1 if you plan to use this extension.

If the temporarily_release_connection method cannot reacquire the same connection it released to the pool, it will raise a Sequel::UnableToReacquireConnectionError exception. This should only happen if the connection has been disconnected while it was temporarily released. If this error is raised, Database#transaction will not rollback the transaction, since the connection object is likely no longer valid, and on poorly written database drivers, that could cause the process to crash.

Related modules: Sequel::TemporarilyReleaseConnection, Sequel::UnableToReacquireConnectionError