diff --git a/1-producer-consumer/main.go b/1-producer-consumer/main.go index 215909c..d67e45c 100644 --- a/1-producer-consumer/main.go +++ b/1-producer-consumer/main.go @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////// // -// Given is a producer-consumer szenario, where a producer reads in +// Given is a producer-consumer scenario, where a producer reads in // tweets from a mockstream and a consumer is processing the // data. Your task is to change the code so that the producer as well // as the consumer can run concurrently @@ -10,22 +10,27 @@ package main import ( "fmt" + "sync" "time" ) -func producer(stream Stream) (tweets []*Tweet) { +func producer(wg *sync.WaitGroup, stream Stream, tweets chan *Tweet) { + defer wg.Done() + for { tweet, err := stream.Next() if err == ErrEOF { - return tweets + return } - tweets = append(tweets, tweet) + tweets <- tweet } } -func consumer(tweets []*Tweet) { - for _, t := range tweets { +func consumer(wg *sync.WaitGroup, tweets <-chan *Tweet) { + defer wg.Done() + + for t := range tweets { if t.IsTalkingAboutGo() { fmt.Println(t.Username, "\ttweets about golang") } else { @@ -35,14 +40,29 @@ func consumer(tweets []*Tweet) { } func main() { + + // This also works without making consumer a go func + // but I thought I'd practice with wait groups. + // Both functions are running concurrently, however, + // consumer only finishes after producer does (as it's dependant on it), + // making the wait at the end a bit unnecessary. + wg := new(sync.WaitGroup) + + // Two go funcs hence the number two here and two "defer wg.Done()" + wg.Add(2) + start := time.Now() stream := GetMockStream() // Producer - tweets := producer(stream) + tweets := make(chan *Tweet) + go producer(wg, stream, tweets) // Consumer - consumer(tweets) + go consumer(wg, tweets) + + // wait for the go routines to finish + wg.Wait() fmt.Printf("Process took %s\n", time.Since(start)) }