Class: RandomPort::Pool
- Inherits:
-
Object
- Object
- RandomPort::Pool
- Defined in:
- lib/random-port/pool.rb
Overview
Pool of TCP ports.
Use it like this:
RandomPort::Pool.new.acquire do |port|
# Use the TCP port. It will be returned back
# to the pool afterwards.
end
You can specify the maximum number of ports to acquire using limit. If more acquisition requests arrive, an exception will be raised.
The class is thread-safe by default. You can configure it to be non-thread-safe using the optional sync argument of the constructor, passing FALSE.
- Author
-
Yegor Bugayenko ([email protected])
- Copyright
-
Copyright © 2018-2026 Yegor Bugayenko
- License
-
MIT
Defined Under Namespace
Classes: Timeout
Constant Summary collapse
- SINGLETON =
Application-wide singleton pool of ports.
RandomPort::Pool.new
Instance Attribute Summary collapse
-
#limit ⇒ Integer
readonly
The maximum number of ports that can be acquired from this pool.
Instance Method Summary collapse
-
#acquire(total = 1, timeout: 4) {|Integer|Array<Integer>| ... } ⇒ Integer|Array<Integer>
Acquires one or more available TCP ports from the pool.
-
#count ⇒ Integer
(also: #size)
Returns the number of ports currently acquired from the pool.
-
#empty? ⇒ Boolean
Checks if the pool is empty (no ports are currently acquired).
-
#initialize(sync: true, limit: 65_536, start: 1025) ⇒ Pool
constructor
Constructor.
-
#release(port) ⇒ nil
Releases one or more ports back to the pool.
Constructor Details
#initialize(sync: true, limit: 65_536, start: 1025) ⇒ Pool
Constructor.
41 42 43 44 45 46 47 |
# File 'lib/random-port/pool.rb', line 41 def initialize(sync: true, limit: 65_536, start: 1025) @ports = [] @sync = sync @monitor = Monitor.new @limit = limit @next = start end |
Instance Attribute Details
#limit ⇒ Integer (readonly)
Returns The maximum number of ports that can be acquired from this pool.
35 36 37 |
# File 'lib/random-port/pool.rb', line 35 def limit @limit end |
Instance Method Details
#acquire(total = 1, timeout: 4) {|Integer|Array<Integer>| ... } ⇒ Integer|Array<Integer>
Acquires one or more available TCP ports from the pool.
You can specify the number of ports to acquire. If it’s more than one, an array will be returned. If a block is given, the port(s) will be automatically released after the block execution.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/random-port/pool.rb', line 76 def acquire(total = 1, timeout: 4) start = Time.now attempt = 0 loop do if Time.now > start + timeout raise \ Timeout, "Can't find a place in the pool of #{@limit} ports " \ "(#{@ports.size} already occupied) " \ "for #{total} port(s), after #{attempt} attempts in #{start.ago}" end attempt += 1 opts = safe { group(total) } if opts.nil? @next += 1 else @next = opts.max + 1 end @next = 0 if @next > 65_535 next if opts.nil? opts = opts[0] if total == 1 return opts unless block_given? begin return yield opts ensure release(opts) end end end |
#count ⇒ Integer Also known as: size
Returns the number of ports currently acquired from the pool.
54 55 56 |
# File 'lib/random-port/pool.rb', line 54 def count @ports.count end |
#empty? ⇒ Boolean
Checks if the pool is empty (no ports are currently acquired).
61 62 63 |
# File 'lib/random-port/pool.rb', line 61 def empty? @ports.empty? end |
#release(port) ⇒ nil
Releases one or more ports back to the pool.
109 110 111 112 113 114 115 116 117 |
# File 'lib/random-port/pool.rb', line 109 def release(port) safe do if port.is_a?(Array) port.each { |p| @ports.delete(p) } else @ports.delete(port) end end end |