如何原子地从Rails缓存中读取

时间:2016-06-28 14:17:20

标签: ruby-on-rails caching

我有2个进程在运行。基本上执行此操作的用户操作:

      Rails.cache.fetch("items/#{self.id}/default_as_json") do
        super(root: false,
              :only => get_only_show,
              :methods => get_include_methods
        )
      end

页面加载

然后我有另一个不经常运行的进程。也许每两周一次,但它会运行几个小时 这个过程正在进行大量的数据处理,经过大量的测试后,我提出的最佳选择就是在每一步之后清除整个缓存。因此,该网站提供了最新的信息。这个性能成本不是问题 我本质上是在页面加载时遇到竞争条件。它似乎找到了密钥的存在,但是当它读取密钥时,文件已被删除 这是我发现的堆栈跟踪:

ActionView::Template::Error (No such file or directory @ rb_sysopen - [CACHE_LOCATION]/A95/DD0/.permissions_check.70057658850120.4451.366289):
    43:       <% if object_type == "Item" %>
    44:         <%= render(
    45:           partial: 'items/no_table_row',
    46:           locals: {object: this_object.as_json,
    47:                   singlesearch: true}
    48:         ) %>
    49:       <% elsif object_type == "Ability" %>
  app/models/item.rb:202:in `serializable_hash'
  app/views/poly_single_searches/_search_list.html.erb:46:in `block in _app_views_poly_single_searches__search_list_html_erb__1164541304050581354_70057643074520'
  app/views/poly_single_searches/_search_list.html.erb:35:in `_app_views_poly_single_searches__search_list_html_erb__1164541304050581354_70057643074520'
  app/views/poly_single_searches/fetch_search.html.erb:1:in `_app_views_poly_single_searches_fetch_search_html_erb___2217227932112086773_70057643107440'
  app/controllers/poly_single_searches_controller.rb:14:in `fetch_search'


  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb (0.8ms)
  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb (1.0ms)
  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb (7.5ms)
  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb (0.6ms)
  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.5ms)
  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.7ms)
  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.5ms)
  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (11.0ms)
  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb within layouts/javascript (0.3ms)
  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.4ms)
  Rendered /home/jon/.rvm/gems/ruby-2.1.2/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (26.0ms)

当其他进程未运行时,一切正常。我有一个任务是找出一种更好的方法来清除缓存,现在不是在每个步骤都不是一个选项后清除缓存。
我有一个解决方案是将Rails.cache.fetch包装在救援中,但这可能会一直失败,直到它设法运行得足够快。

1 个答案:

答案 0 :(得分:0)

我将回答我自己的问题,但是https://stackoverflow.com/users/2116518/nic-nilov值得赞扬 在测试中切换到使用Redis而不是内置的Ruby解决方案修复了我的问题。看起来请求的工作方式不同而且不那么脆弱 到目前为止,我还不需要实现http://redis.io/topics/distlock,因为到目前为止只是切换到Redis已经解决了我的测试问题。