在jruby线程和Rack应用程序之间共享全局引用

时间:2010-08-09 14:36:19

标签: ruby multithreading jruby

我正在尝试创建一个Stats计数器(类似于Twitter中用于scala的ostrich),但很难确保我的所有线程都可以访问它。我的Stats类定义如下:

class Stats
  @@counters = {}
  .. accessors ..

  def self.incr(counter, amt = 1)
    if !@@counters[counter]  
      @@counters[counter] = java.util.concurrent.atomic.AtomicInteger.new()
    end
    @@counters[counter].getAndAdd(amt)
  end
end

我知道计数器哈希本身的线程安全存在一些问题。如果我手动创建线程,他们似乎能够全局访问Stats.counters,但我正在尝试创建一个Rackup应用程序(Sinatra,使用jetty-rackup嵌入Jetty)来显示此信息,并在那个Sinatra应用程序中统计数据是空的。有没有一个很好的方法与应用程序的其他部分共享此计数器,或者sinatra正在做一些清除全局变量范围的事情?

1 个答案:

答案 0 :(得分:2)

我们在IRC #jruby上讨论了这个问题,但我只想在此重申一下后代,我最好的猜测是你遇到了jetty-rackup正在创建并汇集多个运行时用于服务请求的情况。这些运行时中的每一个都加载了相同的Ruby代码,但彼此不了解,类似于多个Ruby进程。您有很多选项可以在它们之间共享状态。

  • 使用Java类(带有单例实例或静态方法/字段)
  • 使用专门构建的Java内存缓存库
  • 使用Java Servlet会话
  • 使用外部机制(memcached,DB等)
  • 更多