Make ARHP's connection switching thread safe
What does this PR do?
This PR makes ARHP database switching thread-safe by:
- updating access to the the host pool database in a thread local manner.
- always switch the database (and let mysql handle it being a no-op when it doesn't need to switch)
- augment the connection adapter's internal
@configto also work in a thread local manner
Why is this helpful?
This allows ARHP to be used in Rails with concurrency turned on. Specifically for my use-case, this lets me set config.allow_concurrency=true in config/environments/test.rb for a feature/integration suite. Without this change concurrency has to be disabled and this makes request processing extremely slow.
Trade-offs
No longer caching the current database
Turning thread-safety on means that caching the current database no longer makes sense since the cached value may be stale based on other threads that have interacted with the database. Rather than querying the database to see what the current database is (which would work) the code now always issues the select_db call and lets MySQL handle responding to things. MySQL seems to treat operations that don't require switching the current database as no-ops and these are very fast.
Always calling clear_cache!
clear_cache! is always called now since the code no longer keeps track of the current database (and lets mysql manage that). This essentially kills any prepared statement caching that occurred, but this was already happening to a large degree when an application would switch databases.
I'm converting this back to a draft. Using this branch locally for testing has been working well but when running this against an app on TravisCI there are some failures that I need to identify if they are related to this patch.
It just hit me that this works great for the database switching to be thread-safe, but it doesn't do anything for the connection pool. I'll see about writing a test for that and see what shakes.
I've pushed up https://github.com/zendesk/active_record_host_pool/pull/63/commits/3b3572a7940061c6c0804b2371ef84506423c72c which exercises the connection pool by creating a number of records across threads.
I spent the morning looking at this with @mervync and.... I think it should work??
addendum: turns out this isn't production tested.
We have some thread safety tests now that should cover this!