每次rake任务运行后Rails.cache都会丢弃

时间:2017-07-24 10:18:40

标签: ruby-on-rails ruby

我很容易被问到: 让我的佣金任务是:

namespace :common do
  desc 'check rails cache'
  task easy_task: :environment do
    l = -> (test_param) do
      puts "cache value isn't found, reload..."
      'this is result'
    end
    result = Rails.cache.fetch('test_task', expires_in: 1.hour) do
      l.call(1)
    end
  end
end

我的期望 - 输出短语"缓存值未找到,重新加载......"将仅输出rake common:easy_task的第一次运行,但每次运行都会输出。

另外,我试试:

rake common:easy_task
rails common:easy_task
bundle exec spring rake common:easy_task
bundle exec spring rails common:easy_task

也不是这些帮助。

Rails缓存不在rake任务中工作,但在控制台和App中工作。为什么呢?

1 个答案:

答案 0 :(得分:1)

如果在控制台中有效但在rake任务中没有,你可能正在使用ActiveSupport::Cache::MemoryStore(这是 config / environments / development.rb 中的默认值,如果你有临时文件来启用缓存,否则它使用ActiveSupport::Cache::NullStore,由于显而易见的原因无法在任何地方工作),它将事物存储在进程内存中:

  

缓存存储实现,它在同一进程中将所有内容存储到内存中。

Rails.configuration.cache_store # => :memory_store
l = -> (test_param) do
  puts "cache value isn't found, reload..."
  'this is result'
end
Rails.cache.fetch('test_task', expires_in: 1.hour) do
  l.call(1)
end
# cache value isn't found, reload...
# => "this is result"
Rails.cache.fetch('test_task', expires_in: 1.hour) do
  l.call(1)
end
# => "this is result"

但是在rake任务中也不会起作用,每次使用一个单独的进程

$ rake common:easy_task
# [:memory_store, "pid = 26230"]
# cache value isn't found, reload...
$ rake common:easy_task
# [:memory_store, "pid = 26253"]
# cache value isn't found, reload...

即使使用弹簧,每次运行的过程都是不同的

$ bin/rake common:easy_task
# Running via Spring preloader in process 26283
# [:memory_store, "pid = 26283"]
# cache value isn't found, reload...
$ bin/rake common:easy_task
# Running via Spring preloader in process 26297
# [:memory_store, "pid = 26297"]
# cache value isn't found, reload...

要解决这个问题,我们需要使用不同的内存存储(我将在此示例中使用ActiveSupport::Cache::FileStore,但请使用您喜欢的其他内容)

config.cache_store = :file_store, Rails.root.join('tmp/cache_store')

然后rake任务按预期工作:

$ bin/rake common:easy_task
# Running via Spring preloader in process 26400
# [:file_store, #<Pathname:.../tmp/cache_store>, "pid = 26400"]
# cache value isn't found, reload...
$ bin/rake common:easy_task
# Running via Spring preloader in process 26414
# [:file_store, #<Pathname:.../tmp/cache_store>, "pid = 26414"]
$ bin/rails c
# Running via Spring preloader in process 26430
result = Rails.cache.fetch('test_task', expires_in: 1.hour) do
  l.call(1)
end
# => "this is result"