在Ruby on Rails中,如何在会话之间将对象保留在内存中

her*_*hey 16 memory persistence ruby-on-rails object

我正在尝试构建一些东西(最终是一个宝石,但现在是一个应用程序),其工作方式如下.

例如,假设DB记录是狗的品种.每个品种都有一个Dog父类和一个子类.直到运行时才知道实际品种.

当服务器开始时,它将从DB加载记录并根据记录实例化类的实例,例如我可能有两个小猎犬和贵宾犬.当有人来到服务器时,他们可能想要访问其中一个狗实例.

为什么不动态创建实例?在我的例子中,"狗"基本上是包含算法和数据的类.算法不会改变,数据变化很少(按天数排序),但算法本身的执行(使用数据和传递的一些动态数据,如时间戳)将每秒多次访问.

如果必须重新创建对象的实例并且每次只是为了在下一个请求时再次执行请求而加载数据(请求不会更改对象的状态),那将是愚蠢的.当我可以重复使用同一个对象时,我将创建并销毁多个对象.

将它保留在会话中是没有意义的,因为想要一只贵宾犬的人不需要在她的会话对象中有beagles信息; 这是无关紧要的(并且没有扩展).

如何将这些对象保留在内存中?我基本上想要一个查找表来保存实例.在Java中,我将创建一个包含某种类型的hashmap或数组的单例,它们位于内存中.在rails中我通过在lib文件夹中创建一个单例类来尝试这个.我认为 - 我可能不理解这一点 - 当会话消失时,实例(事实上它是单身人士没有实际意义)正在丢失.

我找到的最接近的答案是http://www.ruby-forum.com/topic/129372,它基本上将所有内容放在课程领域和方法中.不知怎的,似乎不对.

TIA!

另外:我来自Java.在Java中,我只是创建一个位于堆上或可能位于JNDI树中的对象,当HTTP请求进入时,它们将由一个servlet或EJB或一些每个请求项处理,然后可以访问持久对象.我似乎无法在rails中找到相应的东西.

ace*_*des 10

也许你的例子很简单.我假设您的对象非常复杂,并且您的基准测试表明构建它们对于每个请求都是不合理的.

在生产模式下,不会在请求之间卸载类,但是这些类的实例是.因此,使用班级的班级成员听起来像是找我的方式.只需使用它来存储您的实例.

class ObjectCache
  @@objects = {:beagle => Beagle.new, :poodle => Poodle.new}

  def lookup key
    @@objects[key.to_sym]
  end
end
Run Code Online (Sandbox Code Playgroud)


tad*_*man 6

我不会过分担心加载和丢弃对象,除非你能提出一个证明它是一个问题的基准.当然,每个请求都会创建大量的中间对象,这些通常会在几毫秒内创建和销毁.

通常最好只关注仅加载所需内容,对数据库进行反规范化以将频繁访问的数据或方法推送到方便的位置,或者将复杂计算的结果保存在缓存字段中.

基准测试,仅在需要时进行优化.

将模型实例保存到类高​​速缓存可以起作用,但它只是生产环境中的一个选项,其中模型类不会随每个请求重新加载.它还可以使您接收由陈旧数据引起的错误.

如果您有使用这些方法无法解决的扩展问题,您可能需要使用Rack和EventMachine的组合来研究为部分功能构建持久性服务器.有许多方法可以构建可以使用预先加载的数据集执行复杂计算的后台进程,但具体方法取决于几个因素,例如您正在使用的数据类型以及频率它将被访问.