ruby Mongoid数据库可缓存

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ruby Mongoid数据库可缓存相关的知识,希望对你有一定的参考价值。

# Concern to include in mongoid models that need database cache
#
#
module MongoidCacheable
  extend ActiveSupport::Concern

  class_methods do
    # Create database fields to cache an attribute
    # => Cache field, (Optional Cached_at DateTime field)
    #
    # == Params
    # +attr_name+ - Name of field to be cached (eg points_for_xxx)
    # +type+ - MongoDB Type for the cache field
    # +recache_procedure+ - block to be executed to recompute the value.
    # => Instance `self` sent as block param
    #
    # == Define methods
    # +[attr_name]_cache+ - The last cached value for the guy
    # +[attr_name]_recache+ - Recache the latest value (using $set)
    # +[attr_name]_clear_cache+ - To wipe the cache clean
    #
    # == Options
    # +:expires_in:+ - Expiration date for the cache.
    # => Will add an extra database field _cached_at to store cache time
    #
    # == Examples
    #
    #    cache_attribute(:points_for_contest, type: Integer, expires_in: 5.hours) do |i|
    #      MyPointService.new(i).total_value
    #    end
    #
    #    my_model.points_for_contest_cache # => cached_value or recomputed value if expired
    #
    def cache_attribute(attr_name, type:, expires_in: nil, &recache_procedure)
      cached_at_field_name = :"#{attr_name}_cached_at"
      cache_field_name = :"#{attr_name}_cache"

      field cache_field_name, type: type
      field(cached_at_field_name, type: DateTime, default: nil)

      # @Override the _cache method to read the attribute or recompute it
      define_method(:"#{attr_name}_cache") do
        # Avoid updates if app is in readonly mode
        # return super() if Rails.configuration.db_readonly

        if mongoid_cache_expired?(cached_at_field_name, expires_in: expires_in)
          send(:"#{attr_name}_recache")
        else
          super() # Need to write () explicitely
        end
      end

      # @Override
      # Patch attr= method to update cached_at field at the same time
      define_method(:"#{attr_name}_cache=") do |new_val|
        send("#{cached_at_field_name}=", DateTime.now)
        super(new_val) # Need to write () explicitely
      end

      # Recache method will call &recache_procedure
      # ...and update the cached_at timestamp
      # Performs a $set on the database and returns the cached value
      define_method(:"#{attr_name}_recache") do
        value = recache_procedure.call(self)
        set(
          cache_field_name => value,
          cached_at_field_name => DateTime.now
        )
        value
      end

      # Clear the cached value and cached_at timestamp
      define_method(:"#{attr_name}_clear_cache") do
        set(
          cache_field_name => nil,
          cached_at_field_name => nil
        )
      end
    end
  end

  included do
    # Returns true if the mongoid cache has expired
    # +cached_at_name+ - Mongoid field _cached_at
    # +:expires_in:+ - Expiration time for the cache
    def mongoid_cache_expired?(cached_at_name, expires_in: nil)
      cached_at = send(cached_at_name)
      return true if cached_at.blank? # Always cache at least once
      return false if expires_in.blank? # Never auto-recache if expiration is nil
      DateTime.now > (cached_at + expires_in)
    end
  end
end

以上是关于ruby Mongoid数据库可缓存的主要内容,如果未能解决你的问题,请参考以下文章

批量查找 mongoDB 记录(使用 mongoid ruby​​ 适配器)

Mongoid 在 ruby​​ 1.9.3 上失败

使用 Mongoid 和 Ruby 查询最近 30 天的日期范围?

ruby mongoid_document.rb

Ruby on Rails 是 mongodb - mongoid

ruby mongoid存储架会话Rack :: Session :: RackAndMongo