【发布时间】:2014-12-28 01:55:35
【问题描述】:
我们有一个相对标准的 Ruby on Rails 项目,它有不少在 Resque 下运行的后台作业(以 Redis 作为后端。)
问题是,我们很少会突然看到 Resque 出现大量异常(可能每月一次,也可能更少)。例外情况如下:
undefined method `find_by_id` for User():Class
undefined method `find_by_name` for CustomerAccount():Class
undefined method `find_by_id` for Job():Class
似乎突然间,所有 ActiveRecord::Base 模型都失去了整个线程的 find_by_* 方法。重新启动工作器可以解决问题。
我知道,一般来说,答案必须是“某人,某处——可能在一个 gem 中——正在以某种方式破坏 method_missing。”或者也许,不知何故,常量被重新分配给不同的类。但在我开始真正彻底的调查之前,我想检查一下是否有人遇到过这个问题并已经解决了。
这个项目正在运行 Ruby 2.1.1p76、Rails 3.2.17、Resque 1.25.1。
【问题讨论】:
-
我知道这些查找器在 Rails 4.0 中已被弃用,并且有一个可以让它们恢复的宝石 (github.com/rails/activerecord-deprecated_finders),但您似乎没有使用类似的东西...
-
你能用
where(...).first替换那些方法吗?无论如何,它们都会消失,因此您迟早必须更换它们。您还可以将find_by(x)(如where(x).first)修补到ActiveRecord 中并使用它,find_by随Rails4 一起提供,因此您的代码将与未来兼容,您只需要记住在执行时杀死猴子补丁升级。 -
@D-side rails 4.0 没有贬低
find_by_xxx。 See Here。他们确实贬低了许多动态查找器,但这些不在列表中。虽然这似乎是一种误解,并已传播到许多开发人员。 -
@engineersmnky 知道了。无论如何,这是 Rails 3。所以我的第一条评论总体上是无用的。不过,它可能会阻止一些人朝那个方向徘徊。
-
find_by_*方法通过method_missing/respond_to?实现。respond_to?检查是否存在具有特定名称的列。我想,如果您与数据库的连接由于某种原因在某个时候失败,您就会开始收到这些错误,因为您的应用程序已知的列集是空的。您可以检查您的日志以了解工作人员中失败/关闭的连接的痕迹吗?
标签: ruby-on-rails ruby activerecord resque