我需要从 Rails 应用程序中收集一些数据,对其进行聚合,然后定期将其发送到远程服务器。我在 application.rb 中的全局变量(我知道,我知道)中实例化我的聚合类。
在我的聚合类中,我启动了一个休眠 10 秒的线程,然后查看队列、处理数据并发送它。队列是存储在类的实例变量中的散列。
从 rails 控制器,我调用聚合器类中的一个方法来对散列中的数据进行排队。当然,这与读取队列的后台任务在不同的线程上。问题是后台任务永远不会在哈希中看到任何数据。在我的日志中,当我写入(从控制器线程)和从它读取(从后台线程)时,我都会打印出散列的 object_id。两个线程的 hash#object_id 匹配,但后台线程永远不会看到数据。
让我丧命的是,这在 rails 之外可以正常工作。我已经设置了许多线程的测试,这些线程真的很重要,而且效果很好(为了清楚起见,我没有显示一些线程保护)。有谁知道's 怎么匹配,但内容不一致?object_id
class Aggregator
def initialize
@q = {}
@timer = nil
end
def start
@timer = Thread.new do
loop do
sleep(10)
flush_q
end
end
end
def flush_q
logger.debug "flush: q.object_id = #{@q.object_id}" # matches what I get below
logger.debug "flush: q.length = #{@q.length}" # always zero!
@q.each_pair do |k,v|
# pack it up and send it
end
@q.clear
end
def add(item)
logger.debug "add: q.object_id = #{@q.object_id}" # matches what I get above
@q[item.name] ||= item
logger.debug "add: q.length = #{@q.length}" # increases with each add
# not actually that simple, but not relevant
end
end