如果条件失败,我正在寻找一种简单有效的方法来取消ERB视图中命名片段的缓存写入。
我目前正在这样做:
<% cache("header_#{$I18n.locale}", expires_in: 1.day) do %>
<% begin %>
<%= raw open("https://mywebsite.org/remote/fragment", :read_timeout => 10).read %>
<% rescue OpenURI::HTTPError => e %>
Error Loading Remote File: <%= e.message %>
<% end %>
<% end %>
显然,其中一些只是为了证明我的问题,而不是展示生产代码的最佳实践。
以下是问题:以上内容将缓存错误消息并显示1天,而不是在下次加载时重试服务器。
(通常情况下这不会发生在视图中,但在这种情况下我会为更大的rails应用程序编写插件并且无法修改控制器,只能修改视图。)
这就是我想要做的事情:
<% cache("header_#{$I18n.locale}", expires_in: 1.day) do %>
<% begin %>
<%= raw open("https://mywebsite.org/remote/fragment", :read_timeout => 10).read %>
<% rescue OpenURI::HTTPError => e %>
--> Some command to cancel the cache action started above
--> Show a backup something to the user (I'll provide)
<% end %>
<% end %>
有没有人建议如何做到这一点?
答案 0 :(得分:0)
由于您不希望在出现异常时缓存结果,因此应将异常处理代码放在cache
块之外:
<% begin %>
<% cache("header_#{$I18n.locale}", expires_in: 1.day) do %>
<%= raw open("https://mywebsite.org/remote/fragment", :read_timeout => 10).read %>
<% end %>
<% rescue OpenURI::HTTPError => e %>
Error Loading Remote File: <%= e.message %>
<% end %>
这样,当在缓存块内引发异常时,该块将在完成之前退出,并且不会发生缓存。
答案 1 :(得分:-1)
计算机科学存在两个难题:命名事物,缓存失效和逐个错误。
欢迎来到第二个难题。
尝试使用Rails.cache
代替cache
- 我不是百分之百的差异,或者是否有一个,但Rails.cache
为您提供了一些更明显的缓存方法操作
Rails.cache.fetch
有三个选项:缓存键,选项哈希和块。如果指定的密钥存在于缓存中且未过期,则它将返回缓存的内容;否则,它将执行该块并将其结果存储在缓存中。
<% Rails.cache.fetch "header_#{$I18n.locale}", :expires_in => 1.day do %>
<% begin %>
<%= raw open("https://mywebsite.org/remote/fragment", :read_timeout => 10).read %>
<% rescue OpenURI::HTTPError => e %>
<% Rails.cache.delete "header_#{$I18n.locale}" # removes the cache entry %>
<!-- Show your backup here -->
<% end %>
<% end %>
如果这不起作用,则可能是缓存操作完成的顺序 - 可能是条目在rescue
块中被删除,但是当整个块已经删除时重新添加完成执行。在这种情况下,试试这个:
<% remove_cache_entry = false %>
<% Rails.cache.fetch "header_#{$I18n.locale}", :expires_in => 1.day do %>
<% begin %>
<%= raw open("https://mywebsite.org/remote/fragment", :read_timeout => 10).read %>
<% rescue OpenURI::HTTPError => e %>
<% remove_cache_entry = true %>
<!-- Show your backup here -->
<% end %>
<% end %>
<% Rails.cache.delete "header_#{$I18n.locale}" if remove_cache_entry %>