func add_order_to_best_elev(rcvList map[rcvOrder][]rcvCost, newOrder rcvOrder) { if this_elevator_has_the_lowest_cost(rcvList[newOrder]) { //fmt.Printf("%sNew order added to floor = %d with cost = %d\n%s",def.ColB,helpFunc.Order_dir(newOrder.floor,newOrder.button),Cost(queue.Get_Orders(),helpFunc.Order_dir(newOrder.floor,newOrder.button)),def.ColN) queue.Set_Orders(queue.Update_orderlist(queue.Get_Orders(), queue.Order_direction(newOrder.floor, newOrder.button))) //fmt.Printf("%sUpdated orders = %v\n%s\n",def.ColB,queue.Get_Orders(),def.ColN) queue.Save_backup_to_file() } }
func Handle_msg(incomingMsg, outgoingMsg, costMsg, orderCompleted chan def.Message) { for { msg := <-incomingMsg const aliveTimeout = 6 * time.Second switch msg.Category { case def.Alive: //if connection exists if connection, exist := onlineElevs[msg.Addr]; exist { connection.Timer.Reset(aliveTimeout) } else { add_new_connection(msg.Addr, aliveTimeout) } case def.NewOrder: //fmt.Printf("%sNew external order recieved to floor %d %s \n", def.ColM, helpFunc.Order_dir(msg.Floor, msg.Button), def.ColN) driver.Set_button_lamp(msg.Button, msg.Floor, 1) costMsg := def.Message{Category: def.Cost, Floor: msg.Floor, Button: msg.Button, Cost: handleOrders.Cost(queue.Get_Orders(), queue.Order_direction(msg.Floor, msg.Button))} outgoingMsg <- costMsg case def.CompleteOrder: driver.Set_button_lamp(msg.Button, msg.Floor, 0) orderCompleted <- msg case def.Cost: //see handleOrders.assign_external_order costMsg <- msg } } }
func assign_external_order(costMsg, outgoingMsg, orderCompleted chan def.Message) { rcvList := make(map[rcvOrder][]rcvCost) var notCompletedOrders []rcvOrder var overtime = make(chan rcvOrder) var orderNotCompleted = make(chan rcvOrder) const notHandledTimeout = 9 * def.NumFloors * time.Second const costTimeout = 1000 * time.Millisecond for { select { case msg := <-costMsg: order := rcvOrder{floor: msg.Floor, button: msg.Button} backupOrder := rcvOrder{floor: msg.Floor, button: msg.Button} newCost := rcvCost{cost: msg.Cost, elevAddr: msg.Addr[12:15]} // Checks if order allready is in rcvList // i.e. if we already have recieved an order of this kind for oldOrder := range rcvList { if equal_rcvOrders(oldOrder, order) { order = oldOrder } } // Maps the recieved cost to orders in rcvList if costList, exist := rcvList[order]; exist { if !cost_already_recieved(newCost, costList) { rcvList[order] = append(rcvList[order], newCost) } } else { //else: newCost is the first recieved cost for this order order.timer = time.NewTimer(costTimeout) rcvList[order] = []rcvCost{newCost} go cost_timer(order, overtime) } if all_costs_recieved(rcvList, order) { add_order_to_best_elev(rcvList, order) delete(rcvList, order) order.timer.Stop() //This if makes sure that all external orders are handled if !order_exist_in_list(notCompletedOrders, backupOrder) { backupOrder.timer = time.NewTimer(notHandledTimeout) notCompletedOrders = append(notCompletedOrders, backupOrder) go not_handled_timer(backupOrder, orderNotCompleted) } } case order := <-overtime: fmt.Printf("%sAssign order timeout: Did not recieve all replies before timeout%s\n", def.ColY, def.ColN) add_order_to_best_elev(rcvList, order) delete(rcvList, order) case order := <-orderNotCompleted: order.timer.Stop() if ImConnected { fmt.Printf("%sOrder %v was not handled in time and is now resent%s\n", def.ColY, queue.Order_direction(order.floor, order.button), def.ColN) msgs := def.Message{Category: def.NewOrder, Floor: order.floor, Button: order.button, Cost: -1} outgoingMsg <- msgs } case orderMsg := <-orderCompleted: for index, order := range notCompletedOrders { if orderMsg.Floor == order.floor && orderMsg.Button == order.button { order.timer.Stop() //Delete completed order notCompletedOrders = append(notCompletedOrders[:index], notCompletedOrders[(index+1):]...) } } } } }