我正在尝试 memcache 一个 ActiveRecord 结果数组,我根据一些复杂的业务规则手动过滤了它。今天升级后,我收到了一个令人讨厌的错误,基于 Dalli 尝试序列化阵列并失败并出现以下错误:
关键 'workcases/index/1570/true/c1...:md5:64db5952f959c45126399dd4cb113f86' 的编组错误:无法转储 UNIXSocket
在 .../gems/dalli-2.6.4/lib/dalli/server.rb:397:in `dump'
在从 Ruby 1.9.3 升级到 Ruby 2.0.0 以及将 Passenger 升级到 4.0.7(之前的 4.0.5)之前,这种情况不会发生。
环境:
- 红宝石 2.0.0-p247
- 导轨 3.2.13
- 达利宝石 2.6.4
- 乘客 4.0.7
一段代码,去掉了很多与这个问题无关的复杂性
# The query and filter
def do_query
workcases = Workcase.all(:select=>"#{straight_join} distinct
workcases.id, workcases.caseId, workcases.subject
service_case_types.primary_level, service_case_types.hide_in_result_list #{extra_fields}",
:conditions => conditions, :joins=>joins, :order=>order )
for workcase in workcases
if user.can_view_workcase?(workcase, options)
workcases_filtered << workcase
res_count+=1
end
break if limit && res_count >= limit
end
workcases_filtered
end
# In the Controller
def index
...
@workcases = Rails.cache.fetch(cid, :expires_in=>expires) do
Rails.logger.info "Populating cache for workcases in search"
ActiveRecord::Base.uncached do
Workcase.do_query(@user, in_summary_list, order, nil, true, !@show_deleted_items, condition_ary, @list_limit, {:service_id=>service_id, :case_type_id=>case_type_id})
end
end
...
end
将完整的查询结果集推送到缓存中的原因是运行用于过滤数据库结果的业务逻辑以处理复杂的用户安全/访问控制要求所需的时间。所以,我知道这可能不是 Rails 中缓存的首选用途,但直到昨天它还像梦一样工作。我真的不是在寻找像“只缓存主键”这样的答案,因为我根本不会打扰缓存。
额外说明:
我尝试回滚到 Ruby 1.9.3(使用 RVM,并重新捆绑了应用程序),但错误并没有消失。在我的开发环境中,使用 Webrick 和其他等效的 ruby 和 gem 版本我没有看到这个错误。
我想知道:
- UNIXSocket 来自哪里?
- 任何如何调试的线索(我已经查看了正在缓存的实例,并且那里没有 procs
- Marshal 或 Dalli 中突然出现的关联或连接是否存在问题
- 乘客会影响 Dalli 和/或 Marshal 的运营吗?
事实上,在这一点上,任何想法都会受到赞赏。
编辑
我曾尝试回滚到乘客 gem 的早期版本,但这并没有帮助。我还用早期版本的 Ruby 1.9.3 尝试了 rvm,但也没有解决它。我不相信 Dalli gem 在更新之间发生了变化。
另请注意,其他查询正在成功写入内存缓存。