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.



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

def initialize
  super
  @last = nil
end

Instance Attribute Details

#lastULID?

Returns:



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

def last
  @last
end

Instance Method Details

#encode(moment: Utils.current_milliseconds) ⇒ String

Just providing similar api as ‘ULID.generate` and `ULID.encode` relation. No performance benefit exists in monotonic generator’s one.

Parameters:

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

Returns:

  • (String)

See Also:



80
81
82
# File 'lib/ulid/monotonic_generator.rb', line 80

def encode(moment: Utils.current_milliseconds)
  generate(moment:).encode
end

#freezevoid

This method returns an undefined value.

Raises:

  • (TypeError)

    always raises exception and does not freeze self



88
89
90
# File 'lib/ulid/monotonic_generator.rb', line 88

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

#generate(moment: Utils.current_milliseconds) ⇒ ULID

Parameters:

  • moment (Time, Integer) (defaults to: Utils.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.



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

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

    milliseconds = Utils.milliseconds_from_moment(moment)

    ulid = (
      if prev.milliseconds < milliseconds
        ULID.generate(moment: milliseconds)
      else
        ULID.generate(moment: 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

    @last = ulid
    ulid
  end
end

#inspectString Also known as: to_s

Returns:

  • (String)


28
29
30
# File 'lib/ulid/monotonic_generator.rb', line 28

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