diff --git a/main.go b/main.go index d162de8..3c1d20c 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,8 @@ package main // import "git.sangeeth.dev/gobyexample/waitgroups" // import "git.sangeeth.dev/gobyexample/ratelimiting" // import "git.sangeeth.dev/gobyexample/atomics" -import "git.sangeeth.dev/gobyexample/mutex" +// import "git.sangeeth.dev/gobyexample/mutex" +import "git.sangeeth.dev/gobyexample/statefulgoroutines" func main() { // runes.Runes() @@ -35,5 +36,6 @@ func main() { // waitgroups.WaitGroups() // ratelimiting.RateLimiting() // atomics.Atomics() - mutex.Mutex() + // mutex.Mutex() + statefulgoroutines.StatefulGoroutines() } diff --git a/statefulgoroutines/statefulgoroutines.go b/statefulgoroutines/statefulgoroutines.go new file mode 100644 index 0000000..80679da --- /dev/null +++ b/statefulgoroutines/statefulgoroutines.go @@ -0,0 +1,78 @@ +package statefulgoroutines + +import ( + "fmt" + "math/rand" + "sync/atomic" + "time" +) + +type readOp struct { + key int + resp chan int +} + +type writeOp struct { + key int + value int + resp chan int +} + +func StatefulGoroutines() { + var readCounts, writeCounts atomic.Uint64 + + reads := make(chan readOp) + writes := make(chan writeOp) + + go func() { + state := map[int]int{} + + for { + select { + case r := <-reads: + r.resp <- state[r.key] + case w := <-writes: + state[w.key] = w.value + w.resp <- state[w.key] + } + } + }() + + // Spawn goroutines to do reads + for range 100 { + go func() { + for { + r := readOp{ + key: rand.Intn(5), + resp: make(chan int), + } + reads <- r + <-r.resp + readCounts.Add(1) + time.Sleep(time.Millisecond) + } + }() + } + + // Spawn goroutines to do writes + for range 10 { + go func() { + for { + w := writeOp{ + key: rand.Intn(5), + value: rand.Intn(100), + resp: make(chan int), + } + writes <- w + <-w.resp + writeCounts.Add(1) + time.Sleep(time.Millisecond) + } + }() + } + + time.Sleep(time.Second) + + fmt.Printf("# of reads => %d\n", readCounts.Load()) + fmt.Printf("# of writes => %d\n", writeCounts.Load()) +}