1
\$\begingroup\$

I whipped this up as an example of how infinite loops can often be used to great effect in golang, and also to discuss closing channels and worker communications. It was strictly off the cuff, but I was curious if anybody would like to offer a critique. In particular, I feel as though inflight is a crude implementation detail. I've done it many times, and looking at wait group implementation, seems like it is a synchronized version of the same thing.

package main
import (
 "log"
)
func doStuff(datachan <-chan map[string]string, reschan chan<- int) {
 for {
 data, ok := <-datachan
 if !ok {
 log.Print("Channel closed.")
 break
 }
 log.Printf("Data had %d length: %+v", len(data), data)
 reschan<-len(data)
 }
 return
}
const workers = 3
func main() {
 var datachan = make(chan map[string]string)
 var reschan = make(chan int)
 var inflight = 0
 var inputs = []map[string]string {
 map[string]string{ "hi": "world" },
 map[string]string{ "bye": "space", "including": "moon" },
 map[string]string{ "bye": "space", "including": "moon" },
 map[string]string{ },
 map[string]string{ },
 }
 // an inline funciton definition can change inflight within main()'s scope
 processResults := func (res int) {
 log.Printf("Main function got result %d", res)
 inflight--
 }
 // start some workers
 for i := 0; i < workers; i++{
 go doStuff(datachan, reschan)
 }
 for _, data := range inputs {
 //Select allows reading from reschan if datachan is not available for
 // writing, thus freeing up a worker to read from datachan next loop
 written := false
 for written != true {
 select {
 case res := <-reschan:
 processResults(res)
 case datachan <- data:
 inflight++
 written = true
 }
 }
 }
 close(datachan)
 for inflight > 0 {
 processResults(<-reschan)
 }
}
asked Oct 31, 2020 at 20:22
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You wrote:

func doStuff(datachan <-chan map[string]string, reschan chan<- int) {
 for {
 data, ok := <-datachan
 if !ok {
 log.Print("Channel closed.")
 break
 }
 log.Printf("Data had %d length: %+v", len(data), data)
 reschan <- len(data)
 }
 return
}

I don't understand why you didn't write:

func doStuff(datachan <-chan map[string]string, reschan chan<- int) {
 for data := range datachan {
 log.Printf("Data had %d length: %+v", len(data), data)
 reschan <- len(data)
 }
 log.Print("Channel closed.")
}
answered Nov 1, 2020 at 8:31
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.