Module: Portless::FreePort

Defined in:
lib/portless/free_port.rb

Overview

Picks a free backend port for an app (4000-4999). Random-first to keep the check→bind race window small, skipping the WHATWG bad-port set so browsers never refuse the URL. Mirrors portless's findFreePort.

Constant Summary collapse

RANDOM_ATTEMPTS =
50

Class Method Summary collapse

Class Method Details

.available?(port) ⇒ Boolean

Truly free = we can bind it right now on loopback. (TOCTOU inherent, same as portless; random-first mitigates.)

Returns:

  • (Boolean)


31
32
33
34
35
36
37
# File 'lib/portless/free_port.rb', line 31

def available?(port)
  server = TCPServer.new("127.0.0.1", port)
  server.close
  true
rescue Errno::EADDRINUSE, Errno::EACCES
  false
end

.findObject

Raises:



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/portless/free_port.rb', line 14

def find
  RANDOM_ATTEMPTS.times do
    port = rand(Constants::MIN_APP_PORT..Constants::MAX_APP_PORT)
    next if Constants::BLOCKED_PORTS.include?(port)
    return port if available?(port)
  end

  (Constants::MIN_APP_PORT..Constants::MAX_APP_PORT).each do |port|
    next if Constants::BLOCKED_PORTS.include?(port)
    return port if available?(port)
  end

  raise Error, "no free port available in #{Constants::MIN_APP_PORT}-#{Constants::MAX_APP_PORT}"
end