func (bs *BalancingService) SubscribeEvents() { tree_event.ON(tree_event.ON_DOCKER_INIT, func(e *tree_event.Event) { var err tree_lib.TreeError err.From = tree_lib.FROM_SUBSCRIBE_EVENTS if e.LocalVar == nil { tree_log.Info(err.From, "Containers list is nil during INIT event") return } for _, c := range e.LocalVar.([]docker.APIContainers) { if port, ok := bs.DockerImages[c.Image]; ok { var ci *docker.Container ci, err.Err = tree_docker.DockerClient.InspectContainer(c.ID) if !err.IsNull() { continue } cont_addr := Address{IP: ci.NetworkSettings.IPAddress, Port: port} err.Err = bs.AddDestination(cont_addr) if !err.IsNull() { return } containerAddressMap[c.ID] = cont_addr } } }) tree_event.ON(tree_event.ON_DOCKER_CONTAINER_START, func(e *tree_event.Event) { var err tree_lib.TreeError if e.LocalVar == nil { tree_log.Info(log_from_balancer, "Container Info is nil during container Start event") return } ci := e.LocalVar.(*tree_docker.ContainerInfo) if port, ok := bs.DockerImages[ci.Image]; ok { cont_addr := Address{IP: ci.InspectContainer.NetworkSettings.IPAddress, Port: port} err.Err = bs.AddDestination(cont_addr) if !err.IsNull() { return } containerAddressMap[ci.ID] = cont_addr } }) tree_event.ON(tree_event.ON_DOCKER_CONTAINER_STOP, func(e *tree_event.Event) { if e.LocalVar == nil { tree_log.Info(log_from_balancer, "Container ID is nil during container Stop event") return } cont_id := e.LocalVar.(string) if cont_addr, ok := containerAddressMap[cont_id]; ok { bs.DeleteDestination(cont_addr) delete(containerAddressMap, cont_id) bs.CheckForStopEvent() } }) }
func handle_api_or_parent_connection(conn *net.TCPConn) { defer conn.Close() // Connection should be closed, after return this function var ( err tree_lib.TreeError msg_data []byte info_data []byte conn_name string is_api = false conn_node_info node_info.NodeInfo api_val *big.Int ) err.From = tree_lib.FROM_HANDLE_API_OR_PARENT_CONNECTION // Making basic handshake to check the API validation // Connected Parent receiving name of the child(current node) and checking is it valid or not // if it is valid name then parent sending his name as an answer // otherwise it sending CLOSE_CONNECTION_MARK and closing connection info_data, err.Err = ffjson.Marshal(node_info.CurrentNodeInfo) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } _, err.Err = tree_lib.SendMessage(info_data, conn) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } info_data, err = tree_lib.ReadMessage(conn) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } conn_name = string(info_data) if conn_name == CLOSE_CONNECTION_MARK { tree_log.Info(err.From, "Connection closed by parent node. Bad tree network handshake ! ", "Parent Addr: ", conn.RemoteAddr().String()) return } err.Err = ffjson.Unmarshal(info_data, &conn_node_info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if strings.Contains(conn_node_info.Name, tree_api.API_NAME_PREFIX) { api_val = big.NewInt(conn_node_info.Value) api_connections[api_val] = conn is_api = true } else { // TODO: Think about conn_node_info if we need to more checking for parent node info parentConnection = conn } if is_api { tree_event.TriggerWithData(tree_event.ON_API_CONNECTED, info_data) } else { tree_event.TriggerWithData(tree_event.ON_PARENT_CONNECTED, info_data) } // Listening parent messages for { msg_data, err = tree_lib.ReadMessage(conn) if !err.IsNull() { tree_log.Error(err.From, " reading data from -> ", conn_name, " ", err.Error()) break } // Handling message events handle_message(is_api, true, msg_data) } if is_api { api_connections[api_val] = nil delete(api_connections, api_val) tree_event.TriggerWithData(tree_event.ON_API_DISCONNECTED, info_data) } else { parentConnection = nil tree_event.TriggerWithData(tree_event.ON_PARENT_DISCONNECTED, info_data) } }