【问题标题】:How to use timeout limit in threads如何在线程中使用超时限制
【发布时间】:2018-12-19 13:17:24
【问题描述】:

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

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

【问题讨论】:

  • "如何在线程中使用超时限制" – 超时限制是否在Thread.new { ... } 之外起作用?如果不是,则问题是一般问题,与线程无关。

标签: ruby thread-safety connection-pooling sequel


【解决方案1】:

_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 的东西,它具有超时功能并会为您进行连接池。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-17
    • 2015-10-04
    • 2020-04-09
    • 2016-06-03
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    相关资源
    最近更新 更多