AppController/djinn.rb
# Finds the lowest numbered port that is free to serve a new process.
#
# Callers should make sure to store the port returned by this process in
# @app_info_map, preferably within the use of the APPS_LOCK (so that a
# different caller doesn't get the same value).
#
# Args:
#   starting_port: we look for ports starting from this port.
#   ending_port:   we look up to this port, if 0, we keep going.
#   appid:         if ports are used by this app, we ignore them, if
#                  nil we check all the applications ports.
#
# Returns:
#   A Fixnum corresponding to the port number that a new process can be bound
#   to.
Finds the lowest numbered port that is free to serve a new process.
Callers should make sure to store the port returned by this process in
Finds the lowest numbered port that is free to serve a new process . Callers should make sure to store the port returned by this process in
def find_lowest_free_port(starting_port, ending_port=0, appid="")
    possibly_free_port = starting_port
    loop {
      break if ending_port > 0 and possibly_free_port > ending_port
      in_use = false
      @app_info_map.each { |app, info|
        next if app == appid
        %w(nginx nginx_https haproxy).each{ |key|
          next unless info[key]
          begin
            in_use = true if possibly_free_port == Integer(info[key])
          rescue ArgumentError
            next
          end
        }
        if info['appengine']
          info['appengine'].each { |location|
            host, port = location.split(":")
            in_use = true if possibly_free_port == Integer(port)
          }
        end
        break if in_use
      }
      unless in_use
        actually_available = Djinn.log_run("lsof -i:#{possibly_free_port} -sTCP:LISTEN")
        if actually_available.empty?
          Djinn.log_debug("Port #{possibly_free_port} is available for use.")
          return possibly_free_port
        end
      end
      Djinn.log_debug("Port #{possibly_free_port} is in use, so skipping it.")
      possibly_free_port += 1
    }
    return -1
  end
def find_lowest_free_port ( starting_port , ending_port = 0 , appid = "" ) possibly_free_port = starting_port loop { break if ending_port > 0 and possibly_free_port > ending_port in_use = false @app_info_map . each { | app , info | next if app == appid %w( nginx nginx_https haproxy ) . each { | key | next unless info [ key ] begin in_use = true if possibly_free_port == Integer ( info [ key ] ) rescue ArgumentError next end } if info [ 'appengine' ] info [ 'appengine' ] . each { | location | host , port = location . split ( ":" ) in_use = true if possibly_free_port == Integer ( port ) } end break if in_use } unless in_use actually_available = Djinn . log_run ( "lsof -i:#{possibly_free_port} -sTCP:LISTEN" ) if actually_available . empty? Djinn . log_debug ( "Port #{possibly_free_port} is available for use." ) return possibly_free_port end end Djinn . log_debug ( "Port #{possibly_free_port} is in use, so skipping it." ) possibly_free_port += 1 } return - 1 end
Finds the lowest numbered port that is free to serve a new process.
Finds the lowest numbered port that is free to serve a new process .
# If we have ending_port, we need to check the upper limit too. # Make sure the port is not already allocated to any application. # This is important when applications start at the same time since # there can be a race condition allocating ports. # If appid is defined, let's ignore its ports. # Make sure we have the variables to look into: if we catch an app # early on, it may not have them. # These ports are allocated on the AppServers nodes. # Check if the port is really available. # Let's try the next available port.
starting_port
<not_specific>
ending_port
<not_specific>
appid
<not_specific>
app_info_map,
preferably within the use of the APPS_LOCK (so that a different caller doesn't get the same value). Args: starting_port: we look for ports starting from this port. ending_port: we look up to this port, if 0, we keep going. appid: if ports are used by this app, we ignore them, if nil we check all the applications ports. Returns: A Fixnum corresponding to the port number that a new process can be bound to.
preferably within the use of the APPS_LOCK ( so that a different caller doesn ' t get the same value ) . Args : starting_port : we look for ports starting from this port . ending_port : we look up to this port if 0 we keep going . appid : if ports are used by this app we ignore them if nil we check all the applications ports . Returns : A Fixnum corresponding to the port number that a new process can be bound to .