导致 ActiveRecord 记录器 IOError 的 Ruby 守护进程
Posted
技术标签:
【中文标题】导致 ActiveRecord 记录器 IOError 的 Ruby 守护进程【英文标题】:Ruby Daemons causing ActiveRecord logger IOError 【发布时间】:2010-12-15 06:13:03 【问题描述】:我目前正在用 Ruby 编写一个项目,该项目利用 ActiveRecord gem 进行数据库交互,我正在尝试使用 ActiveRecord::Base.logger
属性和以下代码记录所有数据库活动
ActiveRecord::Base.logger = Logger.new(File.open('logs/database.log', 'a'))
这适用于迁移等(由于某种原因,这似乎需要启用日志记录,因为它在禁用时会给出 NilClass 错误)但是当我尝试运行包含调用 ActiveRecord 对象的线程守护程序的项目时脚本失败并出现以下错误
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/logger.rb:504:in `write': closed stream (IOError)
任何有关如何解决此问题的想法将不胜感激。目前我已经开始查看其他代码,看看人们是否有其他方式以更线程安全的方式实现 ActiveRecord 日志记录
谢谢
帕特里克
【问题讨论】:
【参考方案1】:事实证明,要使迁移工作,ActiveRecord::Base.logger
变量不能为零,这解释了问题的前半部分。尽管使用文件而不是 STDERR 时,我仍然无法修复 IOError。
【讨论】:
问题是否源于同步?你能改用 Rails 的 BufferedLogger,看看是否能解决问题? 我们最终使用 DRB 为我们的需要编写了一个简单的日志记录应用程序,它处理了我们所有线程的错误 我用Rails.logger = ActiveRecord::Base.logger = Logger.new(STDOUT)
修复【参考方案2】:
我遇到了同样的问题。您需要先进行守护进程,然后然后加载 Rails 环境。
【讨论】:
你能解释一下“守护然后加载 Rails env”是什么意思吗 Daemons.run_proc('your_daemon', daemon_options) 需要 File.expand_path(File.join(File.dirname(FILE), '..', 'config' , '环境')) # 做事 @LoganKoester 请注意,在您守护进程后,尝试获取__FILE__
上的目录信息将不起作用,因为该进程会丢失此信息。您必须在守护进程之前保存该路径。【参考方案3】:
delayed_job 使用了守护进程和 activerecord, 在daemonize之前,获取文件已经打开,然后在daemonize中重新打开
@files_to_reopen = []
ObjectSpace.each_object(File) do |file|
@files_to_reopen << file unless file.closed?
end
Daemons.run_proc("xxxxx_name",:dir=>pid_file,:dir_mode=>:normal) do
Dir.chdir(Rails.root)
# Re-open file handles
@files_to_reopen.each do |file|
begin
file.reopen file.path
file.sync = true
rescue ::Exception
end
end
end
【讨论】:
别忘了添加写权限。file.reopen file.path, "a"
以上是关于导致 ActiveRecord 记录器 IOError 的 Ruby 守护进程的主要内容,如果未能解决你的问题,请参考以下文章
转换为 ActiveRecord 查询(火鸟数据库)时导致错误的原始 SQL 查询
是啥导致了这个 ActiveRecord::ReadOnlyRecord 错误?
在更新操作中调用 ActiveRecord .reload 方法导致规范对象具有 nil id
Rails 4 - 生产资产:预编译导致 ActiveRecord::NoDatabaseError: FATAL: database does not exist