Class: Zold::SyncEntrance

Inherits:
Object
  • Object
show all
Defined in:
lib/zold/node/sync_entrance.rb

Overview

The entrance that makes sure only one thread works with a wallet

Instance Method Summary collapse

Constructor Details

#initialize(entrance, dir, timeout: 30, log: Log::Quiet.new) ⇒ SyncEntrance

Returns a new instance of SyncEntrance.



35
36
37
38
39
40
41
42
43
# File 'lib/zold/node/sync_entrance.rb', line 35

def initialize(entrance, dir, timeout: 30, log: Log::Quiet.new)
  raise 'Entrance can\'t be nil' if entrance.nil?
  @entrance = entrance
  raise 'Dir can\'t be nil' if dir.nil?
  @dir = dir
  @timeout = timeout
  raise 'Log can\'t be nil' if log.nil?
  @log = log
end

Instance Method Details

#push(id, body) ⇒ Object

Always returns an array with a single ID of the pushed wallet



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/zold/node/sync_entrance.rb', line 56

def push(id, body)
  f = File.join(@dir, "#{id}.lock")
  FileUtils.mkdir_p(File.dirname(f))
  File.open(f, File::RDWR | File::CREAT) do |lock|
    start = Time.now
    cycles = 0
    loop do
      break if lock.flock(File::LOCK_EX | File::LOCK_NB)
      sleep 0.1
      cycles += 1
      delay = Time.now - start
      if delay > @timeout
        raise "##{Process.pid}/#{Thread.current.name} can't get exclusive access to the wallet #{id}/e \
because of the lock at #{lock.path}: #{File.read(lock)}"
      end
      if (cycles % 20).zero? && delay > 10
        @log.info("##{Process.pid}/#{Thread.current.name} still waiting for \
exclusive access to #{id}/e, #{delay.round}s already")
      end
    end
    File.write(lock, "##{Process.pid}/#{Thread.current.name}/#{Time.now.utc.iso8601}")
    @entrance.push(id, body)
  end
end

#startObject



49
50
51
52
53
# File 'lib/zold/node/sync_entrance.rb', line 49

def start
  @entrance.start do
    yield(self)
  end
end

#to_jsonObject



45
46
47
# File 'lib/zold/node/sync_entrance.rb', line 45

def to_json
  @entrance.to_json
end