Module: JetstreamBridge::Duration

Defined in:
lib/jetstream_bridge/core/duration.rb

Overview

Utility for parsing human-friendly durations into milliseconds.

Uses auto-detection heuristic by default: integers <1000 are treated as seconds, >=1000 as milliseconds. Strings with unit suffixes are supported (e.g., “30s”, “500ms”, “1h”).

Examples:

Duration.to_millis(2)                         #=> 2000 (auto: seconds)
Duration.to_millis(1500)                      #=> 1500 (auto: milliseconds)
Duration.to_millis(30, default_unit: :s)      #=> 30000
Duration.to_millis("30s")                     #=> 30000
Duration.to_millis("500ms")                   #=> 500
Duration.to_millis("250us")                   #=> 0
Duration.to_millis("1h")                      #=> 3_600_000
Duration.to_millis(1_500_000_000, default_unit: :ns) #=> 1500

Also:

Duration.normalize_list_to_millis(%w[1s 5s 15s]) #=> [1000, 5000, 15000]

Constant Summary collapse

MULTIPLIER_MS =

multipliers to convert 1 unit into milliseconds

{
  'ns' => 1.0e-6,     # nanoseconds to ms
  'us' => 1.0e-3,     # microseconds to ms
  'µs' => 1.0e-3,     # alt microseconds symbol
  'ms' => 1,          # milliseconds to ms
  's' => 1_000,       # seconds to ms
  'm' => 60_000,      # minutes to ms
  'h' => 3_600_000,   # hours to ms
  'd' => 86_400_000   # days to ms
}.freeze
NUMBER_RE =
/\A\d[\d_]*\z/
TOKEN_RE =
/\A(\d[\d_]*(?:\.\d+)?)\s*(ns|us|µs|ms|s|m|h|d)\z/i

Class Method Summary collapse

Class Method Details

.coerce_numeric_to_ms(num, unit) ⇒ Object

Raises:

  • (ArgumentError)


91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/jetstream_bridge/core/duration.rb', line 91

def coerce_numeric_to_ms(num, unit)
  # Handle :auto unit with heuristic: <1000 => seconds, >=1000 => milliseconds
  if unit == :auto
    return (num < 1000 ? num * 1_000 : num).round
  end

  u = unit.to_s
  mult = MULTIPLIER_MS[u]
  raise ArgumentError, "invalid unit for default_unit: #{unit.inspect}" unless mult

  (num * mult).round
end

.float_to_ms(flt, default_unit:) ⇒ Object



73
74
75
# File 'lib/jetstream_bridge/core/duration.rb', line 73

def float_to_ms(flt, default_unit:)
  coerce_numeric_to_ms(flt, default_unit)
end

.int_to_ms(num, default_unit:) ⇒ Object

— internal helpers —



69
70
71
# File 'lib/jetstream_bridge/core/duration.rb', line 69

def int_to_ms(num, default_unit:)
  coerce_numeric_to_ms(num.to_f, default_unit)
end

.normalize_list_to_millis(values, default_unit: :auto) ⇒ Object

Normalize an array of durations into integer milliseconds.



60
61
62
63
64
65
# File 'lib/jetstream_bridge/core/duration.rb', line 60

def normalize_list_to_millis(values, default_unit: :auto)
  vals = Array(values)
  return [] if vals.empty?

  vals.map { |v| to_millis(v, default_unit: default_unit) }
end

.string_to_ms(str, default_unit:) ⇒ Object

Raises:

  • (ArgumentError)


77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/jetstream_bridge/core/duration.rb', line 77

def string_to_ms(str, default_unit:)
  s = str.strip
  # Plain number strings are treated like integers so the :auto
  # heuristic still applies (<1000 => seconds, >=1000 => ms).
  return int_to_ms(s.delete('_').to_i, default_unit: default_unit) if NUMBER_RE.match?(s)

  m = TOKEN_RE.match(s)
  raise ArgumentError, "invalid duration: #{str.inspect}" unless m

  num   = m[1].delete('_').to_f
  unit  = m[2].downcase
  (num * MULTIPLIER_MS.fetch(unit)).round
end

.to_millis(val, default_unit: :auto) ⇒ Object

default_unit:

:auto (default: heuristic - <1000 => seconds, >=1000 => milliseconds)
:ms (explicit milliseconds)
:ns, :us, :s, :m, :h, :d (explicit units)


46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/jetstream_bridge/core/duration.rb', line 46

def to_millis(val, default_unit: :auto)
  case val
  when Integer then int_to_ms(val, default_unit: default_unit)
  when Float   then float_to_ms(val, default_unit: default_unit)
  when String  then string_to_ms(val, default_unit: default_unit)
  else
    raise ArgumentError, "invalid duration type: #{val.class}" unless val.respond_to?(:to_f)

    float_to_ms(val.to_f, default_unit: default_unit)

  end
end