Hi,
I’m student and I practice golang since 3 weeks. I have a problem with my code here
Can you help me ?
I have to create graph with node and looking for the leader at the end (the max ID)
indent preformatted text by 4 spaces
package main
import (
"container/list"
"fmt"
"sync"
"time"
)
func Max(x, y int) int {
if x < y {
return y
}
return x
}
type Message struct {
Id int
IsLeader bool
}
type GraphNode struct {
edges *list.List
localId int
leaderId int
synChannel <-chan int
}
type bidirectionalEdge struct {
inChannel <-chan Message
outChannel chan<- Message
fromId int
toId int
}
var wg sync.WaitGroup
func NewGraphNode(id int, synChannel <-chan int) *GraphNode {
return &GraphNode{list.New(), id, -3, synChannel}
}
func (node *GraphNode) addEdge(edge bidirectionalEdge) {
node.edges.PushBack(edge)
}
func (edge bidirectionalEdge) listen(result *int) {
fmt.Println("### Listening ", edge.fromId, ">", edge.toId)
last_max := -1
for receivedMessage := range edge.inChannel {
fmt.Println("<<<", edge.fromId, "- Received:", receivedMessage.Id, receivedMessage.IsLeader)
max := Max(edge.fromId, receivedMessage.Id)
if max > last_max {
last_max = max
edge.outChannel <- Message{max, false}
fmt.Println(">>>", edge.fromId, "- Sent (", max, ") To", edge.toId)
}
}
if last_max > *result {
*result = last_max
}
return
}
// Main code for all nodes
func (n *GraphNode) Run(wg *sync.WaitGroup) {
// Done will be executed once the for loop is over, i.e., the inChannels is closed
defer wg.Done()
synCode := <-n.synChannel
fmt.Println("*", n.localId, "- Step #", synCode, "Initialization")
// Inialisation: every node sends its id to the next node on the ring
for e := n.edges.Front(); e != nil; e = e.Next() {
e.Value.(bidirectionalEdge).outChannel <- Message{n.localId, false}
fmt.Println(">>>", e.Value.(bidirectionalEdge).fromId, "- Sent (", n.localId, ") To", e.Value.(bidirectionalEdge).toId)
}
time.Sleep(time.Second)
synCode = <-n.synChannel
fmt.Println("*", n.localId, "- Step #", synCode, "Listening")
result := -2
for e := n.edges.Front(); e != nil; e = e.Next() {
go e.Value.(bidirectionalEdge).listen(&result)
}
time.Sleep(time.Second)
synCode = <-n.synChannel
fmt.Println("*", n.localId, "- Step #", synCode, "Closing channels")
for e := n.edges.Front(); e != nil; e = e.Next() {
close(e.Value.(bidirectionalEdge).outChannel)
}
time.Sleep(time.Second)
synCode = <-n.synChannel
fmt.Println("*", n.localId, "- Step #", synCode, "Publishing results")
n.leaderId = result
if n.localId == n.leaderId {
fmt.Println("###", n.localId, "- I AM THE LEADER!")
} else {
fmt.Println("###", n.localId, "- Leader elected:", n.leaderId)
}
return
}
func main() {
n := 5
synChan := make(chan int, 1)
lis_nodes := list.New()
for i := 1; i <= n; i++ {
lis_nodes.PushBack(NewGraphNode(i, synChan))
}
for e1 := lis_nodes.Front(); e1 != nil; e1 = e1.Next() {
for e2 := lis_nodes.Front(); e2 != nil; e2 = e2.Next() {
if e1 != e2 {
c1_2 := make(chan Message, 1)
c2_1 := make(chan Message, 1)
e1.Value.(*GraphNode).addEdge(bidirectionalEdge{c2_1, c1_2, e1.Value.(*GraphNode).localId, e2.Value.(*GraphNode).localId})
e2.Value.(*GraphNode).addEdge(bidirectionalEdge{c1_2, c2_1, e2.Value.(*GraphNode).localId, e1.Value.(*GraphNode).localId})
}
}
}
wg.Add(n)
for e := lis_nodes.Front(); e != nil; e = e.Next() {
fmt.Println("### Starting Node", e.Value.(*GraphNode).localId)
go e.Value.(*GraphNode).Run(&wg)
}
for i := 1; i <= n; i++ {
synChan <- 1
}
for i := 1; i <= n; i++ {
synChan <- 2
}
for i := 1; i <= n; i++ {
synChan <- 3
}
for i := 1; i <= n; i++ {
synChan <- 4
}
for i := 1; i <= n; i++ {
synChan <- 5
}
wg.Wait()
}
indent preformatted text by 4 spaces