Class: TrustedSandbox::UidPool
- Inherits:
-
Object
- Object
- TrustedSandbox::UidPool
- Defined in:
- lib/trusted_sandbox/uid_pool.rb
Overview
Offers intra-server inter-process pool of Uids. In other words:
- Every server has its own pool. Since Docker containers live within a server, this is what we want.
- Processes within the same server share the pool.
Usage:
The following will behave the same when different processes try to perform #lock and #release.
pool = UidPool.new 100, 101
pool.lock
# => 100
pool.lock
# => 101
pool.lock
# => RuntimeError: No available UIDs in the pool. Please try again later.
pool.release(100)
# => 100
pool.lock
# => 100
pool.release_all
Instance Attribute Summary collapse
-
#delay ⇒ Object
readonly
Returns the value of attribute delay.
-
#lock_dir ⇒ Object
readonly
Returns the value of attribute lock_dir.
-
#lower ⇒ Object
readonly
Returns the value of attribute lower.
-
#master_lock_file ⇒ Object
readonly
Returns the value of attribute master_lock_file.
-
#retries ⇒ Object
readonly
Returns the value of attribute retries.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
-
#upper ⇒ Object
readonly
Returns the value of attribute upper.
Instance Method Summary collapse
-
#available ⇒ Integer
Number of availabld UIDs.
-
#available_uids ⇒ Array<Integer>
All non taken uids.
-
#initialize(lock_dir, lower, upper, options = {}) ⇒ UidPool
constructor
A new instance of UidPool.
- #inspect ⇒ Object
-
#lock ⇒ Integer
Locks one UID from the pool, in a cross-process atomic manner.
-
#release(uid) ⇒ Integer
Releases one UID.
-
#release_all ⇒ UidPool
Releases all UIDs.
-
#used ⇒ Integer
Number of used UIDs.
-
#used_uids ⇒ Array<Integer>
All taken uids.
Constructor Details
#initialize(lock_dir, lower, upper, options = {}) ⇒ UidPool
Returns a new instance of UidPool.
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 37 def initialize(lock_dir, lower, upper, ={}) @lock_dir = lock_dir FileUtils.mkdir_p(lock_dir) @master_lock_file = lock_file_path_for('master') @lower = lower @upper = upper @timeout = [:timeout] || ['timeout'] || 3 @retries = [:retries] || ['retries'] || 5 @delay = [:delay] || ['delay'] || 0.5 end |
Instance Attribute Details
#delay ⇒ Object (readonly)
Returns the value of attribute delay.
30 31 32 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 30 def delay @delay end |
#lock_dir ⇒ Object (readonly)
Returns the value of attribute lock_dir.
30 31 32 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 30 def lock_dir @lock_dir end |
#lower ⇒ Object (readonly)
Returns the value of attribute lower.
30 31 32 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 30 def lower @lower end |
#master_lock_file ⇒ Object (readonly)
Returns the value of attribute master_lock_file.
30 31 32 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 30 def master_lock_file @master_lock_file end |
#retries ⇒ Object (readonly)
Returns the value of attribute retries.
30 31 32 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 30 def retries @retries end |
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
30 31 32 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 30 def timeout @timeout end |
#upper ⇒ Object (readonly)
Returns the value of attribute upper.
30 31 32 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 30 def upper @upper end |
Instance Method Details
#available ⇒ Integer
Returns number of availabld UIDs.
94 95 96 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 94 def available available_uids.length end |
#available_uids ⇒ Array<Integer>
Returns all non taken uids.
105 106 107 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 105 def available_uids all_uids - used_uids end |
#inspect ⇒ Object
49 50 51 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 49 def inspect "#<TrustedSandbox::UidPool used: #{used}, available: #{available}, used_uids: #{used_uids}>" end |
#lock ⇒ Integer
Locks one UID from the pool, in a cross-process atomic manner
56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 56 def lock retries.times do atomically(timeout) do uid = available_uid if uid lock_uid uid return uid.to_i end end sleep(delay) end raise PoolTimeoutError.new('No available UIDs in the pool. Please try again later.') end |
#release(uid) ⇒ Integer
Releases one UID
82 83 84 85 86 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 82 def release(uid) atomically(timeout) do release_uid uid end end |
#release_all ⇒ UidPool
Releases all UIDs
72 73 74 75 76 77 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 72 def release_all all_uids.each do |uid| release uid end self end |
#used ⇒ Integer
Returns number of used UIDs.
89 90 91 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 89 def used used_uids.length end |
#used_uids ⇒ Array<Integer>
Returns all taken uids.
99 100 101 102 |
# File 'lib/trusted_sandbox/uid_pool.rb', line 99 def used_uids uids = Dir.entries(lock_dir) - %w(. .. master) uids.map(&:to_i) end |