ruby - 如何在线程中使用超时限制
问题描述
我想在新线程上运行某人的 sql 请求:
#!/usr/bin/env ruby
require 'mysql2'
require 'sequel'
CONF = {
adapter: 'mysql2',
encoding: 'utf8',
username: 'ruby',
password: 'ruby',
host: 'localhost',
port: 3306,
pool: 4,
read_timeout: 10,
write_timeout: 10,
connect_timeout: 10,
pool_timeout: 10,
database: 'demo',
max_conns: 7
}
conn = Sequel.connect(CONF)
t = Thread.new { conn['select sleep(100)'].all }
sleep 2
t.kill
sleep 15
当我运行此代码时,我预计请求将在 10 秒后停止,但事实并非如此。当查看 mysql 进程列表时:
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep'
我明白了 - 它仍在处理中(41 秒):
| TIME | QUERY |
|------|-------------------|
| 41 | select sleep(100) |
如何更改我的代码以获得预期的结果?
解决方案
这些_timeout
参数是针对客户端使用的 TCPSocket 的,没有设置查询结果的最大等待时间。
您可以使用Timeout
from ruby stdlib:
t = Thread.new do
Timeout.timeout(10) do
Sequel.connect(CONF)['select sleep(100)'].all
end
end
注意:Timeout
确实存在众所周知的问题,如此处所示。
您还可以考虑类似connection_pool gem的东西,它具有超时功能并会为您进行连接池。
推荐阅读
- concurrent-ruby - 如何取消其他期货?
- bash - 在 repl.it 中运行的 Bash 脚本在 git 别名中出现语法错误
- vba - 如何从 Outlook 加载项禁用 VBA 宏?
- node.js - 来自多个文档的 MongoDB 聚合分组
- sql-server - 如何将数据库中声明为 varchar 的列转换为 SQL Server 中的时间
- java - 如何使用 java 来使用 jButtongroup 选择单选按钮
- javascript - React.js 与 html 合并
- reactjs - 为什么单击带有反应路由器的链接不显示内容?我真的很感激任何建议
- c# - WCF 响应不是映射总是返回 null
- next.js - NextJS 极慢