如何在线程中使用超时限制

时间:2018-12-19 13:17:24

标签: ruby thread-safety connection-pooling sequel

我想在新线程中运行某人的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) |

如何更改代码以获得预期的结果?

1 个答案:

答案 0 :(得分:0)

_timeout参数用于客户端使用的TCPSocket,并且不为查询结果设置最大等待时间。

您可以使用ruby stdlib中的Timeout

t = Thread.new do
  Timeout.timeout(10) do
    Sequel.connect(CONF)['select sleep(100)'].all
  end
end

注意:Timeout确实存在众所周知的问题,如here所示。

您还可以考虑使用connection_pool gem之类的功能,该功能具有超时功能,可以为您完成连接池。