ruby元編程的首次嘗試和 memcached的使用


    今天做項目中遇到一個很常見問題,很多平均值比如:評分,送貨時間平均值需要緩存,計算消耗的代價過大,也沒有實時性的要求所以也沒有必要。因爲ruby目前部署服務器還是已多進程的方式爲主的故選擇memcached做緩存來實現進程間的數據共享(如果以後是多線程的部署方式,通過一個全局的hash效率應該會高)。

memcached安裝:

sudo apt-get install memcached(注意,雖然項目名是memcache,但這裏memcached)

ruby 客戶端安裝:

sudo apt-get install libsasl2-dev
gem install memcached

memcached有專門用於計數的函數(猜想效率會高)。
memcached一次取多條數據效率會高。
因爲緩存是個常見問題,故希望通過元編程解決這個問題。可以緩存任何函數的結果。並設置過期時間。

代碼:

module MethodCached
  def method_cached(fun,time)
    define_method :"#{fun}_cached",->(*splat){str_key =(self.id.to_s+fun.to_s+splat.map{|o| o.to_s}.join("_"))
    begin
       return $cache.get str_key
    rescue
      $cache.set str_key,(res=self.send(fun,*splat)),time
      return res
    end
    }
  end
end




使用,在類裏面:

extend MethodCached
method_cached :function_name,10

10代表10秒過期
直接就可以調用 function_name_cached
extend 將模塊裏面的方法變成類方法
include 將模塊裏面的方法變成實例方法

在ruby編程裏,當前上下境的self很重要,所有的函數調用都是基於該self.
module被extend之後,method_cached是類方法,裏面self指向類,故define_method定義的是實例方法(類對象的單例類define_method是定義類方法)在define_method的內部,self指向實例,self.send(fun)調用的是實例方法。


測試:

assert_equal 4.5,stores(:one).ontime_score_cached
orders(:one).store_ontime_scores.build(:score=>3)
orders(:one).save
assert_equal 4.5,stores(:one).ontime_score_cached
sleep(1)
assert_equal 4.5,stores(:one).ontime_score_cached
sleep(6)
assert_equal 4.0,stores(:one).ontime_score_cached

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章