Skip to content

Instantly share code, notes, and snippets.

@A-725-K
Created July 19, 2023 07:56
Show Gist options
  • Save A-725-K/df73293638a2ea1a89c5b8b383c09d70 to your computer and use it in GitHub Desktop.
Save A-725-K/df73293638a2ea1a89c5b8b383c09d70 to your computer and use it in GitHub Desktop.
eureka-about-golang-channels
package main
import (
"fmt"
"math/rand"
"time"
"flag"
)
const (
N = 5
T_MIN = 1
T_MAX = 5
)
var P int
type Res struct {
id int
timestamp time.Time
}
func worker(numCh chan int, standingCh chan Res, workerIdx int) {
for {
randN := rand.Intn(100)
numCh <- randN
if randN <= P {
break
}
t := time.Duration(rand.Intn(T_MAX - T_MIN + 1) + T_MIN)
time.Sleep(t * time.Second)
}
standingCh <- Res{workerIdx, time.Now()}
close(numCh)
}
func printCh(chIdx, randN int) {
var msg string
if randN <= P {
msg = fmt.Sprintf("Channel %d: OK ==> [%d] ----------", chIdx, randN)
} else {
msg = fmt.Sprintf("Channel %d: continue (%d)...", chIdx, randN)
}
fmt.Println(msg)
}
func main() {
rand.Seed(time.Now().UnixNano())
flag.IntVar(&P, "p", 20, "Probability of success")
flag.Parse()
standingCh := make(chan Res, N)
numChs := []chan int{}
for i := 0; i < N; i++ {
numChs = append(numChs, make(chan int))
}
fmt.Printf("Spawning %d workers with p=%d...\n\n", N, P)
for i := 0; i < N; i++ {
go worker(numChs[i], standingCh, i)
}
var n0, n1, n2, n3, n4 int
ok0, ok1, ok2, ok3, ok4 := true, true, true, true, true
var standing []string
for len(standing) != N || ok0 || ok1 || ok2 || ok3 || ok4 {
select {
case n0, ok0 = <-numChs[0]:
if ok0 {
printCh(0, n0)
}
case n1, ok1 = <-numChs[1]:
if ok1 {
printCh(1, n1)
}
case n2, ok2 = <-numChs[2]:
if ok2 {
printCh(2, n2)
}
case n3, ok3 = <-numChs[3]:
if ok3 {
printCh(3, n3)
}
case n4, ok4 = <-numChs[4]:
if ok4 {
printCh(4, n4)
}
case r := <-standingCh:
standing = append(standing, fmt.Sprintf("%d -- %v", r.id, r.timestamp))
}
}
allDone := !ok0 && !ok1 && !ok2 && !ok3 && !ok4
fmt.Printf("\nEnd of program!\n\n")
if allDone {
fmt.Println("SUCCESS!")
for idx, result := range standing {
fmt.Printf("%d) %s\n", idx+1, result)
}
// For DEBUG purpose
// } else {
// fmt.Println("FAIL :(")
// fmt.Println("n0 =", n0, "n1 =", n1, "n2 =", n2, "n3 =", n3, "n4 =", n4)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment