module BetterUUID::StateFile

Constants

FILENAME

Public Instance Methods

update(clock = nil, mac_addr = nil) click to toggle source
# File lib/better-uuid/state_file.rb, line 12
def update(clock = nil, mac_addr = nil)
  result = change_state(clock, mac_addr)
  start_background_writer
  result
end

Private Instance Methods

background_write() click to toggle source
# File lib/better-uuid/state_file.rb, line 23
def background_write
  if $_better_uuid_background_writer_state_dirty
    open(filename, 'wb') { |fp|
      fp.flock IO::LOCK_EX
      write fp
    }
    $_better_uuid_background_writer_state_dirty = false
  end
rescue Errno::EACCES, Errno::ENOENT, Errno::ENOSPC
end
background_writer() click to toggle source
# File lib/better-uuid/state_file.rb, line 34
def background_writer
  $_better_uuid_background_writer_state_dirty ||= false
  at_exit { background_write }
  loop do
    background_write
    sleep 3
  end
end
change_state(clock, mac_addr) click to toggle source
# File lib/better-uuid/state_file.rb, line 90
def change_state(clock, mac_addr)
  @c, @m = if instance_variable_defined?(:@_better_uuid_initialized)
    next_state(clock, mac_addr)
  else
    @_better_uuid_initialized = true
    initial_state
  end
end
default_initial_state() click to toggle source
# File lib/better-uuid/state_file.rb, line 67
def default_initial_state
  [ rand(0x40000), pseudo_mac ]
end
filename() click to toggle source
# File lib/better-uuid/state_file.rb, line 103
def filename
  File.join(Dir.tmpdir, FILENAME)
end
initial_state() click to toggle source
# File lib/better-uuid/state_file.rb, line 71
def initial_state
  begin
    open(filename, 'rb') { |fp|
      fp.flock IO::LOCK_EX
      read fp
    }
  rescue Errno::EACCES, Errno::ENOENT, ArgumentError
    default_initial_state
  end
end
next_state(clock = nil, mac_addr = nil) click to toggle source
# File lib/better-uuid/state_file.rb, line 82
def next_state(clock = nil, mac_addr = nil)
  $_better_uuid_background_writer_state_dirty = true
  c = clock ? (clock % 0x4000) : @c
  m = mac_addr ? mac_addr : @m
  c = c.succ
  [ c, m ]
end
pseudo_mac() click to toggle source
# File lib/better-uuid/state_file.rb, line 43
def pseudo_mac
  # Generate a pseudo MAC address because we have no pure-ruby way
  # to know  the MAC  address of the  NIC this system  uses.  Note
  # that cheating  with pseudo arresses here  is completely legal:
  # see Section 4.5 of RFC4122 for details.
  sha1 = Digest::SHA1.new
  256.times do
    r = [rand(0x100000000)].pack 'N'
    sha1.update r
  end
  str = sha1.digest
  r = rand 14 # 20-6
  node = str[r, 6] || str
  if RUBY_VERSION >= '1.9.0'
    nnode = node.bytes.to_a
    nnode[0] |= 0x01
    node = ''
    nnode.each { |s| node << s.chr }
  else
    node[0] |= 0x01 # multicast bit
  end
  node
end
start_background_writer() click to toggle source
# File lib/better-uuid/state_file.rb, line 19
def start_background_writer
  $_better_uuid_background_writer ||= Thread.new { background_writer }
end