package client import ( "context" "log" "time" "codeberg.org/snonux/gorum/internal/config" "codeberg.org/snonux/gorum/internal/vote" ) func Start(ctx context.Context, conf config.Config, myVoteCh <-chan vote.Vote) { log.Println("client: starting") fanOut := make([]chan vote.Vote, len(conf.Nodes)) nodeNum := 0 for _, node := range conf.Nodes { fanOut[nodeNum] = startConnection(ctx, node.Address()) nodeNum++ } go func() { defer func() { for _, ch := range fanOut { close(ch) } }() for { select { case myVote := <-myVoteCh: log.Printf("client: notifying live nodes %v to all partner nodes", myVote) for _, ch := range fanOut { // First, clear previous element of the channel, if any select { case <-ch: default: } // Now, update channel with the new live nodes. ch <- myVote } case <-ctx.Done(): return } } }() } func startConnection(ctx context.Context, address string) chan vote.Vote { ch := make(chan vote.Vote, 1) go func() { for { log.Println("client: starting connection", address) if err := tcpClientRun(ctx, address, ch); err != nil { log.Println("client: not connected to address", address, "anymore:", err) } select { case <-time.After(time.Second * 10): case <-ctx.Done(): return } } }() return ch }