2

我有一个需要在服务器上连续运行的 ruby​​ 脚本。我已经使用 daemon gem 对其进行了守护,并且在我的脚本中我让它在无限循环中运行,因为 daemon gem 处理启动我的脚本的进程的启动和停止。在我的脚本中,我首先使用 Sequel gem 和 tiny_tds 设置我的数据库实例。像这样:

DB = Sequel.connect(adapter: 'tinytds', host: MSSQLHost, database: MSSQLDatabase, user: MSSQLUser, password: MSSQLPassword)

然后我有一个loop do就是我的无限循环。在里面,我测试看看我是否有一个连接DB.test_connection,然后我每隔一秒左右查询一次数据库,以检查是否有新的内容使用如下查询:

DB['SELECT * FROM dbo.[MyTable]'].all do |row|
    # MY logic here
    # As part of my logic I test to see if I need to delete this row in the table and if so I use
    DB.run('DELETE FROM dbo.[MyTable] WHERE some condition')
end

然后在我的逻辑结束时,就在我再次循环之前,我这样做:

sleep 1
DB.disconnect

所有这一切都很好用了大约一个小时到一个半小时,一切检查表,执行逻辑,删除行等,然后它死了并给了我这个错误消息TinyTds::Error: Adaptive Server connection timed out

我的问题,为什么会这样?我需要以不同的方式重新格式化我的代码吗?为什么 DB.test_connection 不做它宣传的事情?上面的文档说它检查连接池中的连接,如果找到它就使用它,否则创建一个新连接。

任何帮助将非常感激

4

2 回答 2

1

DB.test_connection只是从连接池中获取连接,它不会检查连接是否仍然有效(它必须在某一时刻有效,否则它不会在池中)。如果没有实际发送查询,连接就不可能仍然有效。connection_validator如果您想自动执行此操作,可以使用 Sequel 附带的扩展。

如果在分叉之前加载 Sequel,则需要确保DB.disconnect在分叉之前调用,否则最终可能会导致多个分叉进程共享同一连接,这可能会导致许多不同的问题。

于 2014-04-07T15:11:42.397 回答
1

最后我最终只是在其中放置了一条救援语句来捕获这个问题,然后重新运行我的代码行来创建数据库实例,是的,它在我的日志中发出了关于已经设置该实例的警告,但我想我可以让它不是一个常数,它会消失。无论如何,它现在似乎正在工作,并且它确实超时的时间,我正在从这些中优雅地恢复。我只是希望我能弄清楚为什么它会像现在这样断开连接。

于 2014-04-10T20:15:17.267 回答