Files
news.gitea.happylizard.me/bin/gems/facets-3.1.0/lib/standard/facets/timer.rb
T
pizza2d1 4cee170d66
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 9s
Add bin and edit workflow
2026-09-16 13:11:16 -06:00

209 lines
3.7 KiB
Ruby

require 'timeout' # for Timeout::Error
# = Timer
#
# Provides a strightforward means for controlling time critical execution.
# Can be used as a "stop watch" timer or as a "time bomb" timer:
#
# t = Timer.new(10) { raise Timeout::Error, "timeout!" }
# t.start
# : # done within 10sec timeout
# t.stop
# t.start
# :
# if condition then
# t.reset #--> restart timer
# end
#
# A class method is also provided for easily timing the exectuion of a block.
#
# Timer.time do |timer|
# timer.total_time.round #=> 0
#
# sleep 1
# timer.total_time.round #=> 1
#
# timer.stop
# timer.total_time.round #=> 1
#
# sleep 1
# timer.total_time.round #=> 1
#
# timer.start
# timer.total_time.round #=> 1
#
# sleep 1
# timer.total_time.round #=> 2
# end
#
# Thanks to Paul Brannan for TimeLimit and Minero Aoki for Timer.
# These two libraries served as models for building this class.
class Timer
#
def initialize(time_limit=nil, &block)
# standard timer
@start_time = nil
@end_time = nil
@total_time = 0
@runnning = nil
# for using time limit
@time_limit = time_limit
@on_timeout = block
@current_thread = nil
@timer_thread = nil
end
#
attr_accessor :time_limit
#
def start_time
@start_time
end
#
def end_time
@end_time
end
#
def on_timeout( &block )
if block then
@on_timeout = block
true
else
false
end
end
# Start the timer.
def start
@running = true
@start_time = Time.now
limit if @time_limit
self
##if block_given? then
## begin
## yield( self )
## ensure
## stop
## end
##else
## @time_limit
##end
end
# Establish a time limit on execution.
def limit( time_limit=nil )
if @time_limit || time_limit
@current_thread = Thread.current
@timer_thread = Thread.fork {
sleep @time_limit
if @on_timeout then
@on_timeout.call @time_limit
else
@current_thread.raise Timeout::Error, "#{@time_limit} seconds past"
end
}
end
end
# Kill time limit thread, if any.
def defuse
if @timer_thread
#Thread.kill @timer_thread
@timer_thread.kill
@timer_thread = nil
end
end
# Stops timer and returns total time.
# If timer was not running returns false.
def stop
if @running
defuse
# record running time
@end_time = Time.now
@running = false
@total_time += (@end_time - @start_time)
else
nil
end
end
# Stops and resets the timer. If the timer was running
# returns the total time. If not returns 0.
def reset
if running?
r = stop
else
r = 0
end
@total_time = 0
return r
end
# Resets the time limit. Same as:
#
# t.stop
# t.start
#
def reset_limit
#stop
#start
defuse
limit
end
# Queries whether the timer is still running.
def running?
return @running
end
# Queries whether the timer is still not running.
def stopped?
return !@running
end
# Queries total recorded time of timer.
def total_time
if running? then
return @total_time + (Time.now - @start_time)
else
return @total_time
end
end
# Takes a block and returns the total time it took to execute.
def self.time
yield( timer = Timer.new.start )
return timer.total_time
end
# Timer::Dummy - Dummy Timer (i.e. no real time limit)
#--
# TODO: Timer::Dummy needs some work.
#++
class Dummy < self
def start
if block_given? then
yield
else
time_limit()
end
end
def stop
false
end
end #class Dummy
end #class Timer
# Copyright (c) 2004 Rubyworks