Timeout 模組
Timeout
長時間執行的區塊
概要¶ ↑
require 'timeout' status = Timeout::timeout(5) { # Something that should be interrupted if it takes more than 5 seconds... }
說明¶ ↑
Timeout
提供一種方式,如果潛在長時間執行的操作在固定的時間內尚未完成,則自動終止該操作。
先前版本沒有使用模組進行命名空間,但是 timeout
是為了向後相容性而提供的。您應該優先使用 Timeout.timeout
。
版權¶ ↑
- 版權
-
© 2000 Network Applied Communication Laboratory, Inc.
- 版權
-
© 2000 情報處理推進機構,日本
常數
- VERSION
公開類別方法
在區塊中執行操作,如果完成時間超過 sec
秒,則會引發錯誤。
sec
-
等待區塊終止的秒數。可以使用任何數字,包括浮點數來指定小數秒。值為 0 或
nil
將在沒有任何逾時的情況下執行區塊。 klass
-
Exception
Class
,如果區塊未能在sec
秒內終止,則會引發。省略將使用預設值Timeout::Error
message
如果區塊在 sec
秒之前完成,則傳回區塊的結果,否則會根據 klass
的值引發例外狀況。
除非明確給定 klass
,否則無法在區塊內救援引發以終止給定區塊的例外狀況。但是,區塊可以使用 ensure 來防止處理例外狀況。因此,無法依賴此方法來強制執行不受信任區塊的逾時。
如果定義了排程器,它將用於透過呼叫 Scheduler#timeout_after 來處理逾時。
請注意,這同時是 Timeout
模組的方法,因此您可以將 include Timeout
納入您的類別,以便它們具有 timeout
方法,以及模組方法,因此您可以直接呼叫它為 Timeout.timeout()
。
# File lib/timeout.rb, line 169 def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+ return yield(sec) if sec == nil or sec.zero? 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
-
等待區塊終止的秒數。可以使用任何數字,包括浮點數來指定小數秒。值為 0 或
nil
將在沒有任何逾時的情況下執行區塊。 klass
-
Exception
Class
,如果區塊未能在sec
秒內終止,則會引發。省略將使用預設值Timeout::Error
message
如果區塊在 sec
秒之前完成,則傳回區塊的結果,否則會根據 klass
的值引發例外狀況。
除非明確給定 klass
,否則無法在區塊內救援引發以終止給定區塊的例外狀況。但是,區塊可以使用 ensure 來防止處理例外狀況。因此,無法依賴此方法來強制執行不受信任區塊的逾時。
如果定義了排程器,它將用於透過呼叫 Scheduler#timeout_after 來處理逾時。
請注意,這同時是 Timeout
模組的方法,因此您可以將 include Timeout
納入您的類別,以便它們具有 timeout
方法,以及模組方法,因此您可以直接呼叫它為 Timeout.timeout()
。
# File lib/timeout.rb, line 169 def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+ return yield(sec) if sec == nil or sec.zero? 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