AppController/djinn.rb
# Instructs Nginx and HAProxy to begin routing traffic for the named
# application to a new AppServer.
#
# This method should be called at the AppController running the login role,
# as it is the node that receives application traffic from the outside.
#
# Args:
#   app_id: A String that identifies the application that runs the new
#     AppServer.
#   ip: A String that identifies the private IP address where the new
#     AppServer runs.
#   port: A Fixnum that identifies the port where the new AppServer runs at
#     ip.
#   secret: A String that is used to authenticate the caller.
#
# Returns:
#   "OK" if the addition was successful. In case of failures, the following
#   Strings may be returned:
#   - BAD_SECRET_MSG: If the caller cannot be authenticated.
#   - NO_HAPROXY_PRESENT: If this node does not run HAProxy (and thus cannot
#     add AppServers to HAProxy config files).
#   - NOT_READY: If this node runs HAProxy, but hasn't allocated ports for
#     it and nginx yet. Callers should retry at a later time.
Instructs Nginx and HAProxy to begin routing traffic for the named
application to a new AppServer.

This method should be called at the AppController running the login role,
as it is the node that receives application traffic from the outside.

A String that identifies the application that runs the new
AppServer.
ip: A String that identifies the private IP address where the new
AppServer runs.
port: A Fixnum that identifies the port where the new AppServer runs at
ip.
secret: A String that is used to authenticate the caller.

"OK" if the addition was successful. In case of failures, the following
Strings may be returned:
BAD_SECRET_MSG: If the caller cannot be authenticated.
NO_HAPROXY_PRESENT: If this node does not run HAProxy (and thus cannot
add AppServers to HAProxy config files).
NOT_READY: If this node runs HAProxy, but hasn't allocated ports for
it and nginx yet. Callers should retry at a later time.
Instructs Nginx and HAProxy to begin routing traffic for the named application to a new AppServer . This method should be called at the AppController running the login role as it is the node that receives application traffic from the outside . A String that identifies the application that runs the new AppServer . ip : A String that identifies the private IP address where the new AppServer runs . port : A Fixnum that identifies the port where the new AppServer runs at ip . secret : A String that is used to authenticate the caller . " OK " if the addition was successful . In case of failures the following Strings may be returned : BAD_SECRET_MSG : If the caller cannot be authenticated . NO_HAPROXY_PRESENT : If this node does not run HAProxy ( and thus cannot add AppServers to HAProxy config files ) . NOT_READY : If this node runs HAProxy but hasn ' t allocated ports for it and nginx yet . Callers should retry at a later time .
def add_routing_for_appserver(app_id, ip, port, secret)
    return BAD_SECRET_MSG unless valid_secret?(secret)
    unless my_node.is_shadow?
       Djinn.log_debug("Sending routing call for #{app_id} to shadow.")
       acc = AppControllerClient.new(get_shadow.private_ip, @@secret)
       begin
         return acc.add_routing_for_appserver(app_id, ip, port)
       rescue FailedNodeException => except
         Djinn.log_warn("Failed to forward routing call to shadow (#{get_shadow}).")
         return NOT_READY
       end
    end
    APPS_LOCK.synchronize {
      if @app_info_map[app_id].nil? or @app_info_map[app_id]['appengine'].nil?
        return NOT_READY
      elsif @app_info_map[app_id]['appengine'].include?("#{ip}:#{port}")
        Djinn.log_warn("Already registered AppServer for app #{app_id} at #{ip}:#{port}.")
        return INVALID_REQUEST
      end
      Djinn.log_debug("Adding AppServer for app #{app_id} at #{ip}:#{port}.")
      match = @app_info_map[app_id]['appengine'].index("#{ip}:-1")
      if match
        @app_info_map[app_id]['appengine'].delete_at(match)
      else
        Djinn.log_warn("Received a no matching request for: #{ip}:#{port}.")
      end
      @app_info_map[app_id]['appengine'] << "#{ip}:#{port}"
    }
    return "OK"
  end
def add_routing_for_appserver ( app_id , ip , port , secret ) return BAD_SECRET_MSG unless valid_secret? ( secret ) unless my_node . is_shadow? Djinn . log_debug ( "Sending routing call for #{app_id} to shadow." ) acc = AppControllerClient . new ( get_shadow . private_ip , @@secret ) begin return acc . add_routing_for_appserver ( app_id , ip , port ) rescue FailedNodeException => except Djinn . log_warn ( "Failed to forward routing call to shadow (#{get_shadow})." ) return NOT_READY end end APPS_LOCK . synchronize { if @app_info_map [ app_id ] . nil? or @app_info_map [ app_id ] [ 'appengine' ] . nil? return NOT_READY elsif @app_info_map [ app_id ] [ 'appengine' ] . include? ( "#{ip}:#{port}" ) Djinn . log_warn ( "Already registered AppServer for app #{app_id} at #{ip}:#{port}." ) return INVALID_REQUEST end Djinn . log_debug ( "Adding AppServer for app #{app_id} at #{ip}:#{port}." ) match = @app_info_map [ app_id ] [ 'appengine' ] . index ( "#{ip}:-1" ) if match @app_info_map [ app_id ] [ 'appengine' ] . delete_at ( match ) else Djinn . log_warn ( "Received a no matching request for: #{ip}:#{port}." ) end @app_info_map [ app_id ] [ 'appengine' ] << "#{ip}:#{port}" } return "OK" end
Instructs Nginx and HAProxy to begin routing traffic for the named
application to a new AppServer.
Instructs Nginx and HAProxy to begin routing traffic for the named application to a new AppServer .
# We need to send the call to the shadow. # Find and remove an entry for this AppServer node and app.
app_id
<not_specific>
ip
<not_specific>
port
<not_specific>
secret
<not_specific>