package main import ( "log" "sync" "time" ) var ( isMaster bool masterNode string masterNodeMux sync.RWMutex ) const ( heartbeatInterval = 5 * time.Second heartbeatTimeout = 15 * time.Second electionTimeout = 10 * time.Second ) func sendHeartbeats() { for { if !isMaster { return } for _, node := range peers { msg := Message{ ID: hostID, Type: "heartbeat", Content: authCode, } err := sendMessage(node, msg) if err != nil { log.Printf("Error sending heartbeat to %s: %v", node, err) } } time.Sleep(heartbeatInterval) } } func checkMasterHeartbeat() { for { time.Sleep(heartbeatTimeout) masterNodeMux.RLock() if masterNode == authCode || masterNode == "" { masterNodeMux.RUnlock() continue } masterNodeMux.RUnlock() masterNodeMux.Lock() masterNode = "" masterNodeMux.Unlock() startElection() } } func startElection() { masterNodeMux.Lock() defer masterNodeMux.Unlock() for _, node := range peers { msg := Message{ ID: hostID, Type: "election", Content: authCode, } err := sendMessage(node, msg) if err != nil { log.Printf("Error sending election message to %s: %v", node, err) } } isMaster = true go sendHeartbeats() } func handleHeartbeat(content string) { masterNodeMux.Lock() defer masterNodeMux.Unlock() masterNode = content } func handleElection(content string) { masterNodeMux.Lock() defer masterNodeMux.Unlock() if content < authCode { masterNode = content } }