Cache SHOW COLUMNS

上一篇 / 下一篇  2008-01-11 11:36:11 / 精华(2)

查看( 3 ) / 评论( 4 )
今天recity发布第二版本,优化了半天,终于达到一个稍微满意的速度,闲下来也写了篇bllog轻松下:)

原文发在我的blog上
http://mmm.javaeye.com/blog/155123

这个东西据说在production已经cache了,是的,确实是的!

今天主要的目的是折腾 :) 于是乎google一把,看有没有现成的plugin,呵呵,俺想偷懒 :D

没找到plugins,但是找到一个不错的patch:http://dev.rubyonrails.org/attac ... _column_names.patch

哦,原来就是这么个东西,开始动手,把它转换成plugins

先说明下,这个只是初步入门级别,没什么深入研究的可是为什么要写这篇文章:
呵呵,纯属折腾。。。


新建一个plugin

CODE:

ruby script/generate plugin CacheColumns将cache_column_name.patch的代码稍作修改填到我们的lib/cache_columns里去
这里面的columns和reset_column_information是实类方法,所以我们可以使用

CODE:

base.instance_eval do
  block goes here
end
来覆盖原始的method

首先请先备份原始的两个method

CODE:

        alias old_columns columns
        alias old_reset_column_information reset_column_information
新建一个全局的变量Hash来缓存columns

CODE:

@@columns = {}OK,include 到ActiveRecord::Base里去

CODE:

ActiveRecord::Base.send :include, CacheColumns::ActiveRecord打完收工 :)

完整代码如下:
/vendor/plugins/cache_columns/init.rb

CODE:

ActiveRecord::Base.send :include, CacheColumns::ActiveRecord/vendor/plugins/cache_columns/lib/cache_columns.rb

CODE:

module CacheColumns
  module ActiveRecord
    @@columns = {}

    def self.included(base)
      base.instance_eval do
        alias old_columns columns
        alias old_reset_column_information reset_column_information

        def columns
          if  @@columns[table_name].nil?
            @@columns[table_name] = connection.columns(table_name, "#{name} Columns")
            @@columns[table_name].each {|column| column.primary = column.name == primary_key}
          end
          @@columns[table_name]
        end

        #  # Resets all the cached information about columns, which will cause them to be reloaded on the next request.
        def reset_column_information
          generated_methods.each { |name| undef_method(name) }
          @column_names = @columns_hash = @content_columns = @dynamic_methods_hash = @read_methods = @inheritance_column = nil
          @@columns.delete(table_name)
        end

        def reset_column_cache #:nodoc:
          @@columns = {}
        end
      end
    end
end
代码我放到code.google.com上面去了

CODE:

svn co [url]http://cache-columns.googlecode.com/svn/trunk[/url]哦,你想缓存到memcached中?好吧,我们再继续修改之,有过一次经历,这次再动手就简单多了。

CODE:

require 'memcache_util'

module CacheColumns
  module ActiveRecord
    def self.included(base)
      base.instance_eval do
        alias old_columns columns
        alias old_reset_column_information reset_column_information
        @ttl = 60 * 30 #增加个配置选择?

        def columns
          record =  get_columns(table_name)
          unless record
            record = connection.columns(table_name, "#{name} Columns")
            record.each {|column| column.primary = column.name == primary_key}
            cache_store record
          end
          record
        end

        #  # Resets all the cached information about columns, which will cause them to be reloaded on the next request.
        def reset_column_information
          generated_methods.each { |name| undef_method(name) }
          @column_names = @columns_hash = @content_columns = @dynamic_methods_hash = @read_methods = @inheritance_column = nil
          cache_delete
        end

        #get columns from memcached
        def get_columns(name)
          start_time = Time.now
          record = Cache.get cache_key_memcache
          elapsed = Time.now - start_time
          ActiveRecord::Base.logger.debug('CacheColumns Get (%0.6f)  %s' % [elapsed, cache_key_memcache])
          record
        end

        #store columns
        def cache_store(record)
          start_time = Time.now
          Cache.put cache_key_memcache, record, @ttl
          elapsed = Time.now - start_time
          ActiveRecord::Base.logger.debug('CacheColumns Set (%0.6f)  %s' % [elapsed, cache_key_memcache])
          record
        end

        def cache_key_memcache
          "active_record:columns:#{table_name}"
        end

        def cache_delete
          Cache.delete  cache_key_memcache
        end
      end
    end
  end
end
[本帖最后由 martin 于 2008-1-16 12:33 编辑]

TAG:

red_world maninred 发布于2008-01-15 22:44:45
不错,martin就是厉害。学习一下。如果这个能做个视频就更好了。
lgn21st发布于2008-01-16 01:25:37
martin你为了recity上线也太忙啦,没有在上海rails聚会上看到你风流倜傥的身影!
Martin's Thought martin 发布于2008-01-16 09:27:33

QUOTE:

原帖由 lgn21st 于 2008-1-16 01:25 发表
martin你为了recity上线也太忙啦,没有在上海rails聚会上看到你风流倜傥的身影!
呵呵,太可惜了,上次没能去,下次一定过去:)
Martin's Thought martin 发布于2008-01-16 09:28:03

QUOTE:

原帖由 maninred 于 2008-1-15 22:44 发表
不错,martin就是厉害。学习一下。如果这个能做个视频就更好了。
要是下次有时间,我一定满足这个要求:)
我来说两句

(可选)

日历

« 2009-07-05  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 286
  • 日志数: 19
  • 建立时间: 2007-08-13
  • 更新时间: 2008-01-23

RSS订阅

Open Toolbar