File: deadline.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 (71 lines) | stat: -rw-r--r-- 1,936 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
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2025, by Shopify Inc.
# Copyright, 2025, by Samuel Williams.

require_relative "clock"

# @namespace
module Async
	# Represents a deadline timeout with decrementing remaining time.
	# Includes an efficient representation for zero (non-blocking) timeouts.
	# @public Since *Async v2.31*.
	class Deadline
		# Singleton module for immediate timeouts (zero or negative).
		# Avoids object allocation for fast path (non-blocking) timeouts.
		module Zero
			# Check if the deadline has expired.
			# @returns [Boolean] Always returns true since zero timeouts are immediately expired.
			def self.expired?
				true
			end
			
			# Get the remaining time.
			# @returns [Integer] Always returns 0 since zero timeouts have no remaining time.
			def self.remaining
				0
			end
		end
		
		# Create a deadline for the given timeout.
		# @parameter timeout [Numeric | Nil] The timeout duration, or nil for no timeout.
		# @returns [Deadline | Nil] A deadline instance, Zero singleton, or nil.
		def self.start(timeout)
			if timeout.nil?
				nil
			elsif timeout <= 0
				Zero
			else
				self.new(timeout)
			end
		end
		
		# Create a new deadline with the specified remaining time.
		# @parameter remaining [Numeric] The initial remaining time.
		def initialize(remaining)
			@remaining = remaining
			@start = Clock.now
		end
		
		# Get the remaining time, updating internal state.
		# Each call to this method advances the internal clock and reduces
		# the remaining time by the elapsed duration since the last call.
		# @returns [Numeric] The remaining time (may be negative if expired).
		def remaining
			now = Clock.now
			delta = now - @start
			@start = now
			
			@remaining -= delta
			
			return @remaining
		end
		
		# Check if the deadline has expired.
		# @returns [Boolean] True if no time remains.
		def expired?
			self.remaining <= 0
		end
	end
end