模块 Timeout
Timeout
用于长时间运行的代码块
概要¶ ↑
require 'timeout' status = Timeout.timeout(5) { # Something that should be interrupted if it takes more than 5 seconds... }
描述¶ ↑
Timeout
提供了一种方法,可以在操作在固定时间内未完成时自动终止潜在的长时间运行操作。
版权¶ ↑
- 版权
-
© 2000 Network Applied Communication Laboratory, Inc.
- 版权
-
© 2000 Information-technology Promotion Agency, Japan
常量
- VERSION
-
版本
公共类方法
源码
# File lib/timeout.rb, line 167 def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+ return yield(sec) if sec == nil or sec.zero? raise ArgumentError, "Timeout sec must be a non-negative number" if 0 > sec message ||= "execution expired" if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after) return scheduler.timeout_after(sec, klass || Error, message, &block) end Timeout.ensure_timeout_thread_created perform = Proc.new do |exc| request = Request.new(Thread.current, sec, exc, message) QUEUE_MUTEX.synchronize do QUEUE << request CONDVAR.signal end begin return yield(sec) ensure request.finished end end if klass perform.call(klass) else Error.handle_timeout(message, &perform) end end
在代码块中执行操作,如果耗时超过 sec
秒完成,则抛出错误。
sec
-
等待代码块终止的秒数。可以使用任何非负数或 nil,包括浮点数来指定小数秒。值为 0 或
nil
将在不设置任何超时的情况下执行代码块。任何负数都会抛出ArgumentError
。 klass
-
如果代码块在
sec
秒内未能终止,则抛出的Exception
Class
。省略将使用默认值Timeout::Error
message
-
与
Exception
Class
一起抛出的Error
消息。省略将使用默认值 “execution expired”(执行已过期)
如果代码块在 sec
秒之前完成,则返回代码块的结果,否则根据 klass
的值抛出异常。
除非明确给出 klass
,否则在代码块内部无法捕获为终止给定代码块而抛出的异常。但是,代码块可以使用 ensure 来防止处理该异常。因此,不能依赖此方法来强制执行不可信代码块的超时。
如果定义了调度器,它将通过调用 Scheduler#timeout_after 来处理超时。
请注意,这既是模块 Timeout
的一个方法,因此您可以将 include Timeout
放入您的类中,使它们具有 timeout
方法,也是一个模块方法,因此您可以直接将其作为 Timeout.timeout()
调用。
私有实例方法
源码
# File lib/timeout.rb, line 167 def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+ return yield(sec) if sec == nil or sec.zero? raise ArgumentError, "Timeout sec must be a non-negative number" if 0 > sec message ||= "execution expired" if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after) return scheduler.timeout_after(sec, klass || Error, message, &block) end Timeout.ensure_timeout_thread_created perform = Proc.new do |exc| request = Request.new(Thread.current, sec, exc, message) QUEUE_MUTEX.synchronize do QUEUE << request CONDVAR.signal end begin return yield(sec) ensure request.finished end end if klass perform.call(klass) else Error.handle_timeout(message, &perform) end end
在代码块中执行操作,如果耗时超过 sec
秒完成,则抛出错误。
sec
-
等待代码块终止的秒数。可以使用任何非负数或 nil,包括浮点数来指定小数秒。值为 0 或
nil
将在不设置任何超时的情况下执行代码块。任何负数都会抛出ArgumentError
。 klass
-
如果代码块在
sec
秒内未能终止,则抛出的Exception
Class
。省略将使用默认值Timeout::Error
message
-
与
Exception
Class
一起抛出的Error
消息。省略将使用默认值 “execution expired”(执行已过期)
如果代码块在 sec
秒之前完成,则返回代码块的结果,否则根据 klass
的值抛出异常。
除非明确给出 klass
,否则在代码块内部无法捕获为终止给定代码块而抛出的异常。但是,代码块可以使用 ensure 来防止处理该异常。因此,不能依赖此方法来强制执行不可信代码块的超时。
如果定义了调度器,它将通过调用 Scheduler#timeout_after 来处理超时。
请注意,这既是模块 Timeout
的一个方法,因此您可以将 include Timeout
放入您的类中,使它们具有 timeout
方法,也是一个模块方法,因此您可以直接将其作为 Timeout.timeout()
调用。