Class: ULID::MonotonicGenerator

Inherits:
Object
  • Object
show all
Includes:
MonitorMixin
Defined in:
lib/ulid/monotonic_generator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMonotonicGenerator

Returns a new instance of MonotonicGenerator.



15
16
17
18
# File 'lib/ulid/monotonic_generator.rb', line 15

def initialize
  super()
  @prev = nil
end

Instance Attribute Details

#prevULID? (readonly)

Returns:



11
12
13
# File 'lib/ulid/monotonic_generator.rb', line 11

def prev
  @prev
end

Instance Method Details

#freezevoid

This method returns an undefined value.

Raises:

  • (TypeError)

    always raises exception and does not freeze self



70
71
72
# File 'lib/ulid/monotonic_generator.rb', line 70

def freeze
  raise TypeError, "cannot freeze #{self.class}"
end

#generate(moment: ULID.current_milliseconds) ⇒ ULID

Parameters:

  • moment (Time, Integer) (defaults to: ULID.current_milliseconds)

Returns:

Raises:

  • (OverflowError)

    if the entropy part is larger than the ULID limit in same milliseconds

  • (UnexpectedError)

    if the generated ULID is an invalid value in monotonicity spec. Basically will not happen. Just means this feature prefers error rather than invalid value.



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
# File 'lib/ulid/monotonic_generator.rb', line 31

def generate(moment: ULID.current_milliseconds)
  synchronize do
    unless @prev
      @prev = ULID.generate(moment: moment)
      return @prev
    end

    milliseconds = ULID.milliseconds_from_moment(moment)

    ulid = (
      if @prev.milliseconds < milliseconds
        ULID.generate(moment: milliseconds)
      else
        ULID.from_milliseconds_and_entropy(milliseconds: @prev.milliseconds, entropy: @prev.entropy.succ)
      end
    )

    unless ulid > @prev
      base_message = "monotonicity broken from unexpected reasons # generated: #{ulid.inspect}, prev: #{@prev.inspect}"
      additional_information = (
        if Thread.list == [Thread.main]
          '# NOTE: looks single thread only exist'
        else
          '# NOTE: ran on multi threads, so this might from concurrency issue'
        end
      )

      raise UnexpectedError, base_message + additional_information
    end

    @prev = ulid
    ulid
  end
end

#inspectString Also known as: to_s

Returns:

  • (String)


21
22
23
# File 'lib/ulid/monotonic_generator.rb', line 21

def inspect
  "ULID::MonotonicGenerator(prev: #{@prev.inspect})"
end