/* wait for incoming messages from the UI */ func PyBridgeReceiver() { for { message := bridges.ReceiveFromPyBridge() switch message.Kind { case defs.MSG_MYNAME: localNameChannel <- message.Content case defs.MSG_GAME_TYPE: gameTypeChannel <- message.Content case defs.MSG_CON_REQ: valueType := strings.Split(message.Content, "|")[0] consensus.Propose(message.Content, valueType) case defs.MSG_CON_REPLY: valueType := strings.Split(message.Content, "|")[0] propCheckMutex.Lock() propCheck := propChecksMap[valueType] (*propCheck.Callback)(message.Content) delete(propChecksMap, valueType) propCheckMutex.Unlock() case defs.MSG_EXIT: // echo back to UI bridges.SendToPyBridge(message) // exit multegula exitChannel <- true default: go putMessageIntoSendChannel(message) } } }
/* * sets the orientation of the players to alphabetical */ func uiSetCompetitorLocation(myName string, peers *[]messagePasser.Node) { var toSend messagePasser.Message var nodeNames = []string{} // loop through all nodes and pull out names for _, node := range *peers { nodeNames = append(nodeNames, node.Name) } // sort and get length sort.Strings(nodeNames) length := len(nodeNames) // create content of message content := fmt.Sprintf("%d", length) for _, name := range nodeNames { content = fmt.Sprintf("%v%v%v", content, defs.PAYLOAD_DELIMITER, name) } // create message and send message toSend.Source = myName toSend.Destination = myName toSend.Kind = defs.MSG_PLAYER_LOC toSend.Content = content bridges.SendToPyBridge(toSend) }
/* * Routine to commit proposals that have reached consensus */ func ConsensusReachedRoutine() { for { proposal := consensus.ProposalToCommit() commitMessage := messagePasser.Message{ Source: messagePasser.LocalNode.Name, Destination: messagePasser.LocalNode.Name, Kind: defs.MSG_CON_COMMIT, Content: proposal.Value, } bridges.SendToPyBridge(commitMessage) } }
/* * Routine to check proposals for a local value and respond */ func ConsensusCheckReceiverRoutine() { for { propCheck := consensus.ProposalCheck() propCheckMutex.Lock() propChecksMap[propCheck.Prop.Type] = propCheck propCheckMutex.Unlock() bridges.SendToPyBridge(messagePasser.Message{ Source: messagePasser.LocalNode.Name, Destination: messagePasser.LocalNode.Name, Kind: defs.MSG_CON_CHECK, Content: propCheck.Prop.Value, }) } }
/* receive message from messagePasser and route to correct location */ func inboundDispatcher() { for { // get message from MessagePasser message := messagePasser.Receive() // Based on the type of message, determine where it needs routed switch message.Kind { // UI Messages case defs.MSG_BALL_DEFLECTED: fallthrough case defs.MSG_BALL_MISSED: fallthrough case defs.MSG_BLOCK_BROKEN: fallthrough case defs.MSG_CON_CHECK: fallthrough case defs.MSG_CON_COMMIT: fallthrough case defs.MSG_DEAD_NODE: fallthrough case defs.MSG_DEAD_UNICORN: fallthrough case defs.MSG_FORCE_COMMIT: fallthrough case defs.MSG_KILL_NODE: fallthrough case defs.MSG_PADDLE_DIR: fallthrough case defs.MSG_PAUSE_UPDATE: fallthrough case defs.MSG_REJOIN_ACK: fallthrough case defs.MSG_REJOIN_REQ: fallthrough case defs.MSG_START_PLAY: fallthrough case defs.MSG_SYNC_ERROR: bridges.SendToPyBridge(message) case defs.MSG_UNICORN: initConsensus(message) bridges.SendToPyBridge(message) // election messages case defs.MSG_BULLY_ELECTION: fallthrough case defs.MSG_BULLY_ANSWER: fallthrough case defs.MSG_BULLY_ARE_YOU_ALIVE: fallthrough case defs.MSG_BULLY_IAM_ALIVE: bullySelection.PutMessageToReceiveChannel(message) case defs.MSG_BULLY_UNICORN: initConsensus(message) bullySelection.PutMessageToReceiveChannel(message) // consensus messages case defs.CONSENSUS_ACCEPT_KIND: fallthrough case defs.CONSENSUS_REJECT_KIND: fallthrough case defs.CONSENSUS_PROPOSE_KIND: fallthrough case defs.CONSENSUS_COMMIT_KIND: consensus.ReceiveMessage(message) default: fmt.Printf("inboundDispatcher couldn't recognize message: %+v\n", message) } } }