модуль 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 Information-technology Promotion Agency, Japan
Константы
- VERSION
Методы публичного класса
# File lib/timeout.rb, line 83
def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
return yield(sec) if sec == nil or sec.zero?
message ||= "execution expired".freeze
if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after)
return scheduler.timeout_after(sec, klass || Error, message, &block)
end
from = "from #{caller_locations(1, 1)[0]}" if $DEBUG
e = Error
bl = proc do |exception|
begin
x = Thread.current
y = Thread.start {
Thread.current.name = from
begin
sleep sec
rescue => e
x.raise e
else
x.raise exception, message
end
}
return yield(sec)
ensure
if y
y.kill
y.join # make sure y is dead.
end
end
end
if klass
begin
bl.call(klass)
rescue klass => e
message = e.message
bt = e.backtrace
end
else
bt = Error.catch(message, &bl)
end
level = -caller(CALLER_OFFSET).size-2
while THIS_FILE =~ bt[level]
bt.delete_at(level)
end
raise(e, message, bt)
end Выполнить операцию в блоке, выбросив ошибку, если она занимает более sec секунд.
-
sec -
Количество секунд ожидания завершения блока. Можно использовать любое число, включая числа с плавающей точкой для указания долей секунды. Значение 0 или
nilвыполнит блок без таймаута. -
klass -
ExceptionClassдля выброса, если блок не завершится в течениеsecсекунд. Если пропустить, будет использоваться значение по умолчанию,Timeout::Error. -
message -
Сообщение
Errorдля выброса сExceptionClass. Если пропустить, будет использовано значение по умолчанию, «истечение времени выполнения»
Возвращает результат блока если блок завершился до sec секунд, в противном случае генерирует исключение на основе значения klass.
Исключение, сгенерированное для завершения данного блока, не может быть перехвачено внутри блока, если klass не указано явно. Однако блок может использовать ensure для предотвращения обработки исключения. По этой причине на этом методе нельзя полагаться для обеспечения таймаутов для недоверенных блоков.
Если определён планировщик, он будет использован для обработки таймаута путём вызова Scheduler#timeout_after.
Обратите внимание, что это метод модуля Timeout, поэтому вы можете include Timeout в свои классы, чтобы они имели метод timeout, а также метод модуля, чтобы вы могли вызвать его напрямую как Timeout.timeout().
Методы частного экземпляра
# File lib/timeout.rb, line 83
def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
return yield(sec) if sec == nil or sec.zero?
message ||= "execution expired".freeze
if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after)
return scheduler.timeout_after(sec, klass || Error, message, &block)
end
from = "from #{caller_locations(1, 1)[0]}" if $DEBUG
e = Error
bl = proc do |exception|
begin
x = Thread.current
y = Thread.start {
Thread.current.name = from
begin
sleep sec
rescue => e
x.raise e
else
x.raise exception, message
end
}
return yield(sec)
ensure
if y
y.kill
y.join # make sure y is dead.
end
end
end
if klass
begin
bl.call(klass)
rescue klass => e
message = e.message
bt = e.backtrace
end
else
bt = Error.catch(message, &bl)
end
level = -caller(CALLER_OFFSET).size-2
while THIS_FILE =~ bt[level]
bt.delete_at(level)
end
raise(e, message, bt)
end Выполнить операцию в блоке, выбросив ошибку, если она занимает более sec секунд.
-
sec -
Количество секунд ожидания завершения блока. Можно использовать любое число, включая числа с плавающей точкой для указания долей секунды. Значение 0 или
nilвыполнит блок без таймаута. -
klass -
ExceptionClassдля выброса, если блок не завершится в течениеsecсекунд. Если пропустить, будет использоваться значение по умолчанию,Timeout::Error. -
message -
Сообщение
Errorдля выброса сExceptionClass. Если пропустить, будет использовано значение по умолчанию, «истечение времени выполнения»
Возвращает результат блока если блок завершился до sec секунд, в противном случае генерирует исключение на основе значения klass.
Исключение, сгенерированное для завершения данного блока, не может быть перехвачено внутри блока, если klass не указано явно. Однако блок может использовать ensure для предотвращения обработки исключения. По этой причине на этом методе нельзя полагаться для обеспечения таймаутов для недоверенных блоков.
Если определён планировщик, он будет использован для обработки таймаута путём вызова Scheduler#timeout_after.
Обратите внимание, что это метод модуля Timeout, поэтому вы можете include Timeout в свои классы, чтобы они имели метод timeout, а также метод модуля, чтобы вы могли вызвать его напрямую как Timeout.timeout().
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.