File: clock.rb

package info (click to toggle)
ruby-async 2.36.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 400 kB
  • sloc: ruby: 1,938; makefile: 4
file content (94 lines) | stat: -rw-r--r-- 1,968 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2018-2025, by Samuel Williams.

module Async
	# A convenient wrapper around the internal monotonic clock.
	# @public Since *Async v1*.
	class Clock
		# Get the current elapsed monotonic time.
		def self.now
			::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
		end
		
		# Measure the execution of a block of code.
		# @yields {...} The block to execute.
		# @returns [Numeric] The total execution time.
		def self.measure
			start_time = self.now
			
			yield
			
			return self.now - start_time
		end
		
		# Start measuring elapsed time from now.
		# @returns [Clock]
		def self.start
			self.new.tap(&:start!)
		end
		
		# Create a new clock with the initial total time.
		# @parameter total [Numeric] The initial clock duration.
		def initialize(total = 0)
			@total = total
			@started = nil
		end
		
		# @returns [Numeric | Nil] The time when the clock was started, or nil if not started.
		attr :started
		
		# Start measuring a duration.
		def start!
			@started ||= Clock.now
		end
		
		# Stop measuring a duration and append the duration to the current total.
		def stop!
			if @started
				@total += (Clock.now - @started)
				@started = nil
			end
			
			return @total
		end
		
		# The total elapsed time including any current duration.
		def total
			total = @total
			
			if @started
				total += (Clock.now - @started)
			end
			
			return total
		end
		
		# Reset the total elapsed time. If the clock is currently running, reset the start time to now.
		def reset!
			@total = 0
			
			if @started
				@started = Clock.now
			end
		end
		
		# Convert the clock to a JSON-compatible hash.
		#
		# @returns [Hash] The JSON-compatible hash.
		def as_json(...)
			{
				started: self.started,
				total: self.total,
			}
		end
		
		# Convert the clock to a JSON string.
		#
		# @returns [String] The JSON string.
		def to_json(...)
			self.as_json.to_json(...)
		end
	end
end