예제 #1
0
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()
		}
	})
}
예제 #2
0
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)
	}
}