Rails.cache在不同的线程中不缓存?

时间:2015-11-14 00:46:54

标签: ruby-on-rails ruby multithreading caching

我在rails项目中遇到缓存方法结果的问题。

我来到这个模拟两个不同请求的代码:

[  
   Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }, 
   Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } 
]

尝试在rails控制台中执行它。 如果我尝试在控制台中运行它作为输出我得到不同的数字。怎么可能?

但是例如这段代码(带睡眠)按预期工作:

[  
  Thread.new { sleep(1); puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }, 
  Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } 
]

2 个答案:

答案 0 :(得分:1)

在第一段代码中

[  
  Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }, 
  Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } 
]

我认为您的rails配置正在使用文件进行缓存(为了确保这一点,请检查rails应用程序中的文件夹/ tmp / cache)。

因为' Rails.cache'需要从文件中执行读取缓存,这非常耗时,并且操作提取'在2个主题中大多数是同时运行的,所以' a'价值不存在或已经过期。

在第二段代码中

[  
  Thread.new { sleep(1); puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }, 
  Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } 
]

当第一个帖子尝试获取' a' a' a'已经在缓存文件中。这就是它运作的原因。

让我们进行另一次模拟,而不是使用' Rails.cache',我们将使用这样的MemoryStore缓存:

cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
[
  Thread.new { puts cache.fetch('a', expires_in: 2.seconds) { rand } },
  Thread.new { puts cache.fetch('a', expires_in: 2.seconds) { rand } }
]

它也符合我们的期望!

答案 1 :(得分:0)

您可以使用互斥锁来防止同时运行某些代码:

mutex = Mutex.new
[  Thread.new { puts mutex.synchronize { Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } }, Thread.new { puts mutex.synchronize { Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } } ]