active_record_host_pool icon indicating copy to clipboard operation
active_record_host_pool copied to clipboard

Make ARHP's connection switching thread safe

Open zdennis opened this issue 5 years ago • 5 comments

What does this PR do?

This PR makes ARHP database switching thread-safe by:

  1. updating access to the the host pool database in a thread local manner.
  2. always switch the database (and let mysql handle it being a no-op when it doesn't need to switch)
  3. augment the connection adapter's internal @config to 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.

zdennis avatar Jun 10 '20 15:06 zdennis

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.

zdennis avatar Jun 12 '20 18:06 zdennis

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.

zdennis avatar Jun 24 '20 21:06 zdennis

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.

zdennis avatar Jun 25 '20 18:06 zdennis

I spent the morning looking at this with @mervync and.... I think it should work??

KJTsanaktsidis avatar Jun 29 '22 01:06 KJTsanaktsidis

addendum: turns out this isn't production tested.

mervync avatar Jun 30 '22 16:06 mervync

We have some thread safety tests now that should cover this!

HeyNonster avatar Oct 05 '24 09:10 HeyNonster