谨防 ActiveSupport::Cache::Store 缓存 nil 值

本文讲述了在使用 Rails 的 ActiveSupport::Cache::Store 缓存时遇到的问题,即 nil 值被缓存导致线上错误。通过阅读源码,作者发现 fetch 方法会缓存 nil,并提出了解决方案——通过添加 option 支持不缓存 nil 值,优化了代码的简洁性。
摘要由CSDN通过智能技术生成

Rails 中的 active_support 组件主要基于 Rails 需要提供了很多非常有用的基础工具以及对 Ruby 内置类进行扩展。其中的 cache 模块主要提供了 Rails 中底层缓存的定义以及简单实现。今天要跟大家探讨的是之前在使用此模块所遇到的一个坑,有兴趣学习其基本用法的可以点击以下两个链接:

从 ActiveSupport::Cache::Store#fetch 聊起

之前在实现一个需要从外部服务请求数据的功能时,处于性能考虑,我在代码中使用了缓存,并且设置缓存失效时间为 7 天,示例代码如下:

def read_external_service(params)
  # 这段代码稍微解释下:
  #   当缓存命中时,则直接读取缓存,如果无期待缓存,则通过 HTTP 向外请求结果,并且将结果
  #   缓存下来,这样子,当下次继续调用时,则可直接返回缓存内容,而无需重复向外请求
  #
  Rails.cache.fetch 'example_cache_key_here', expires_in: 7.days do
    response = HTTParty.get 'https://example.com/example/request/path'
    JSON.parse(response.body)["data"]
  end
end

上面的代码其实不复杂,核心代码就是使用了 ActiveSupport::Cache::Store#fetch 方法。

一切都很正常地运行着,直到有一天,线上系统不断报警,出错原因就是这段代码总是返回 nil ,而调用者又因为没有判断 nil 值,就会出现 undefined method 'xxx' for nil:NilClass 错误。在 debug 时,我尝试了直接调用外部服务接口,发现请求都有正确返回数据,不可能返回 nil 啊,难道是缓存了 nil 值?下面就直接通过代码验证一下!

[1] pry(main)> require 'active_support'
=> true
[2] pry(main)> cache = ActiveSupport::Cache::MemoryStore.new
=> <#ActiveSupport::Cache::MemoryStore ent
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值