QueryCache

Hi,

is someone interested in using the QueryCache? It seams to be an old part of rails. I enable the querycache in the database-specification with a:

  query_cache: true

and get an exception from ActiveRecord ... ConnectionSpecification There is an if-clause, which did not work together with query_cache (l. 247):

  def self.connection=(spec) #:nodoc:     if spec.kind_of?(ActiveRecord::ConnectionAdapters::AbstractAdapter)       active_connections[name] = spec     elsif spec.kind_of?(ConnectionSpecification)       config = spec.config.reverse_merge(:allow_concurrency => @@allow_concurrency)       self.connection = self.send(spec.adapter_method, config)     elsif spec.nil?       raise ConnectionNotEstablished     else       establish_connection spec     end   end

There is no clause for a QueryCache. But QueryCache acts like a connection. So I change it to:

    if spec.kind_of?(ActiveRecord::ConnectionAdapters::AbstractAdapter) or       spec.kind_of?(ActiveRecord::QueryCache)

The next problem was the concurrency-model of rails. The QueryCache deletes all entries if an update, insert or delete-action was done. But most performance-sensitive enviroments use a few ruby/rails/mongrel-processes. So the QueryCache-Module isn't scaleable.

In our Webshop we have different kinds of data. Some data, which isn't changed at runtime (Categories, Products) and data, which will be changed by user-actions.

I add a class-method to ActiveRecord::base, so that you can specify your class as 'cacheable'. Only this data will be cached. And I deleted the old update/insert/delete-semantic. Now the cache caches only 'cacheable'-classes. I add the rewrite of the query_cache-File at the end of this mail.

The reason? Why? In the past I'm working with spring/hibernate-apps. There ist the ehcache, which boosts the performance. If the application don't need to ask the database, it will be very fast. And because the ehcache ist between application-logic and database, you don't had to think about caching. I had some experience with template-caching and it's more intrusive.

With my few changes on the QueryCache, the performance will speed up from 4 Request per second to 6 requests per second. The database and the rails-app and the ab (apachebench) are on the same box. I hope the QueryCache will speed up more in an environment with the database on another box.

The next work will be the change of the datastructure for the cache. At the moment it's a ruby-hash. You will get memory-problems, if there are many cacheable-entities in the cache. An LRU or LFU-Module will be better. It may be possible, to use a size-Parameter with the cacheable-call. Than every class could have its own cache-size.

we will see. jens

query_cache.rb