我试图在 Rails 启动时创建一个线程,该线程将在应用程序的整个生命周期中运行。奇怪的是,我已经将其与我正在运行的另一个线程一起使用了。我复制了该(工作)代码并将其用作新线程的新代码的样板。但线程不会启动。
- 代码位于配置/初始化程序中(这是正确的位置吗?)。
- 文件以“z_...”开头命名,以确保它最后运行。
- 导轨3.2.6
这是代码的一般结构:
class Blah
def self.the_thread
The_Model.transaction do
# do some database stuff
# ...
end
TheThread = Thread.new do
while true do
the_thread
sleep 5.seconds
end
end
end
打开 Rails 控制台并检查 Blah::TheThread 会发现一个似乎从未运行过的死线程。类的声明中似乎没有任何错误,方法中也没有任何错误,因为当我打开 Rails 控制台时,我可以运行该方法并且它工作得很好。另外,如果我手动在 Rails 控制台中输入上面生成线程的确切代码(TheThread = Thread new do ...),它就可以正常工作(每 5 秒唤醒一次,执行其操作,然后再次休眠)。
同样,奇怪的是,这个在 Rails 中生成简单线程的样板文件以前在这个完全相同的应用程序中为我工作过。
如果有人对我认为奇怪的问题有一些可能的见解,我会洗耳恭听。
Thanks.
编辑:新信息 - 我刚刚注释掉了事务调用(和匹配结束),它工作正常。我不知道交易会干扰什么。我删除了其他自定义初始化脚本,目录中唯一的其他脚本要么是默认脚本,要么是属于设计的脚本。我仔细阅读了它们,没有看到任何交易正在进行。
更多新信息。我在线程代码末尾添加了“TheThread.abort_on_exception = true”。当我启动 Rails 时,我现在收到异常“ArgumentError:在关闭的数据库上调用准备:回滚事务(ActiveRecord::StatementInvalid)”。错误发生在 sqlite3 gem 中。我有 sqlite3 gem 版本 1.3.6 和 sqlite-ruby gem 版本 1.3.3。我用谷歌搜索了这个错误,发现有几个帖子抱怨同样的错误,但没有看到任何解决方案。
我不再认为这是一个线程问题,而是一个数据库问题,但为时已晚更改这篇文章的标题。
这只是:我在线程代码的顶部放置了一个“睡眠 15.秒”(就在进入 while 循环之前),这解决了问题。但我仍然想知道是什么导致了这个问题,以及“非黑客”解决方案是什么。由于某种原因,此代码运行时数据库尚未准备好。我的初始化代码是否放置在错误的位置?