Closed aks closed 6 years ago
I have a proposal for addressing this cache-coherency problem: create a full proxy connection object that is returned to and used by FreshConnection to AR Base methods, and through which the decision to redirect SQL queries to either the master or replica is deferred to the last possible moment.
In other words, the ActiveRecord::Base.connection
returns a FreshProxyConnection
, which is subclassed from ConnectionAdapters::AbstractAdapter
.
The FreshProxyConnection
maintains two pools of connections: @master_pool
and @replica_pool
, and defers the choice of connection until the last possible moment -- just before executing the SQL, via execute
.
This allows the QueryCache module to be effective at the ActiveRecord::Base
level, unifying the caches for both master and replica connections, since the query cache instance is now attached to the FreshProxyConnection
instead of either the original master connections or the replica connections.
By fully proxying the connection, and putting the master/replica switching at the lowest possible level, I believe that less method prepends/intercepts are needed, and only the lowest level methods need to be prepended/intercepted by FreshConnection.
Does this make sense?
Thank you! I'll think way to resolve this problem. Please wait a while.
Please see PR#19 which provides a fix with a test to confirm the problem and a test to confirm the solution.
I fixed a problem of query cache by simple way. #20 I think that there is more better way it. I'm thinking other way to solve this problem.
There is a problem with Rails caching and fresh_connection.
fresh_connection
maintains a replica connection pool, consisting of multiple connection instances, separate from the master connection pool, also one or more connection instances.The ActiveRecord Query Cache module inserts itself as class methods into the
AbstractAdapter
, but maintains the actual query cache as an instance variable on the connection instance.These two facts means that the query caches for the "master" connections are separate from that of the "replica" connections. So, the AR::Base methods of
update
,insert
, anddelete
methods, which clear the cache attached to a given connection, do not clear the corresponding cache in the other pool connections.So, when a read-only query for an AR model object is diverted to a replica connection, it's cache is likely (guaranteed) to be out-of-date from a recent update to that same object on the master connection.
For example: