Skip to content

Conversation

@kirs
Copy link
Member

@kirs kirs commented Jul 14, 2021

Context: #42271

There's lots of exciting work going in Ruby 3.0 with fibers, non-blocking IO and support for custom schedulers. Eventually we'd like to run Rails apps with ActiveRecord in non-blocking servers like Falcon. Those servers would require the code not to rely on thread-local variables, which ActiveRecord connection pool does right now.

This PR is an attempt to allow AR to take pool_class as an option to DB configuration. It will allow @ioquatix and the async ruby team to implement a fiber-local connection pool, and to run ActiveRecord on non-blocking servers.

main...kirs:async-rb is a quick and dirty example how a custom connection pool implementation might look like.

@eileencodes eileencodes self-assigned this Jul 14, 2021
@kirs
Copy link
Member Author

kirs commented Jul 14, 2021

Ideally, this should come not as a configuration option but as a method on the DB adapter class. That way we could have async_mysql adapter that would specify that it wants to use "async" pool. Something like:

module ActiveRecord module ConnectionAdapters class AbstractAdapter def pool_class ConnectionAdapters::ConnectionPool end module ActiveRecord module ConnectionAdapters class AsyncMysqlAdapter < AbstractMysqlAdapter def pool_class AsyncConnectionPool end 

However, we initialize the pool object before we resolve mysql2 to Mysql2Adapter as a class. That makes us unable to call something like adapter.pool_class as early as when initializing the pool.

Hence the reason why I made this an option of the connection config.

end

def pool_class
klass = db_config.configuration_hash.fetch(:pool_class, ConnectionAdapters::ConnectionPool)
Copy link
Member

@eileencodes eileencodes Jul 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how I feel about this implementation. There is already a class in the pool which is the class that established the connection. Now we're introducing another class that you then would need to re-implement all the methods on pool to use. That feels confusing to explain and implement. Is there another way to accomplish this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe worth investigating the design of Sequel, since they have got this part of the design working really well?

@rails-bot
Copy link

rails-bot bot commented Oct 14, 2021

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
Thank you for your contributions.

@rails-bot rails-bot bot added the stale label Oct 14, 2021
@rails-bot rails-bot bot closed this Oct 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

3 participants