Help working with communication between channels

I’m doing my first steps with go channels, and tried to write the below code, where I want to do the following with goroutine that is reading from a given csv file, emit the read record to another channel which is adding the same record to another csv file:

package main

import (
	"encoding/csv"
	"encoding/json"
	"fmt"
	"log"
	"os"
)

func failOnError(err error) {
	if err != nil {
		log.Fatal("Error:", err)
		panic(err)
	}
}
func main() {
	read := make(chan Data)
	go func(input_file string) {
		var data Data

		fr, err := os.Open(input_file)
		failOnError(err)
		defer fr.Close()
		r := csv.NewReader(fr)
		rows, err := r.ReadAll()
		failOnError(err)
		data.header = rows[0]
		for _, row := range rows[1:] {
			data.lines = append(data.lines, Person{
				Firstname: row[0],
				Lastname:  row[1],
				Address: &Address{
					City:  row[2],
					State: row[3],
				},
			})
		}

		peopleJson, _ := json.Marshal(data.lines)
		fmt.Println(string(peopleJson))   // This is working smoothly

		read <- data
	}("people.csv")

	csvOut, err := os.Create("resultsfile.csv")
	if err != nil {
		log.Fatal("Unable to open output")
	}

	out := make(chan int)
	select {
	case data := <-read:
		go func(data Data) {
			println("data received")     // <-- Not show up
			w := csv.NewWriter(csvOut)
			defer csvOut.Close()
			// handle header
			data.header = append(data.header, "score")
			if err = w.Write(data.header); err != nil {
				log.Fatal(err)
			}
			/*
				hanlde data
			*/
			w.Flush()
			out <- 0
		}(data)
	case _ = <-out:
		println("done")
	}

}

type Person struct {
	Firstname string   `json:"firstname"` // JSON annotation will allow for easy printing to JSON after it had been loaded
	Lastname  string   `json:"lastname"`
	Address   *Address `json:"address,omitempty"`
}

type Address struct {
	City  string `json:"city"`
	State string `json:"state"`
}

type Data struct {
	header []string
	lines  []Person
}

my code failed, with no error and did not show the data received note.

Note: The code worked with me by dropping second goroutine, and replace it by this:

	data := <-read
	w := csv.NewWriter(csvOut)
	defer csvOut.Close()
	// handle header
	data.header = append(data.header, "score")
	if err = w.Write(data.header); err != nil {
		log.Fatal(err)
	}
	w.Flush()

But I want to do it with goroutine to understand goroutine better.

I found the solution as below:

package main

import (
	"encoding/csv"
	"encoding/json"
	"fmt"
	"log"
	"os"
)

func failOnError(err error) {
	if err != nil {
		log.Fatal("Error:", err)
		panic(err)
	}
}
func main() {
	read := make(chan Data)
	go func(input_file string) {
		var data Data

		fr, err := os.Open(input_file)
		failOnError(err)
		defer fr.Close()
		r := csv.NewReader(fr)
		rows, err := r.ReadAll()
		failOnError(err)
		data.header = rows[0]
		for _, row := range rows[1:] {
			data.lines = append(data.lines, Person{
				Firstname: row[0],
				Lastname:  row[1],
				Address: &Address{
					City:  row[2],
					State: row[3],
				},
			})
		}

		peopleJson, _ := json.Marshal(data.lines)
		fmt.Println(string(peopleJson))   // This is working smoothly

		read <- data
	}("people.csv")

	csvOut, err := os.Create("resultsfile.csv")
	if err != nil {
		log.Fatal("Unable to open output")
	}

	out := make(chan int)

	data := <-read
	go func(data Data, outputfile *os.File) {
		w := csv.NewWriter(outputfile)
		defer outputfile.Close()
		// handle header
		data.header = append(data.header, "score")
		if err = w.Write(data.header); err != nil {
			log.Fatal(err)
		}
		/*
			hanlde data
		*/
		w.Flush()
		out <- 0
	}(data, csvOut)

	<-out
}

type Person struct {
	Firstname string   `json:"firstname"` // JSON annotation will allow for easy printing to JSON after it had been loaded
	Lastname  string   `json:"lastname"`
	Address   *Address `json:"address,omitempty"`
}

type Address struct {
	City  string `json:"city"`
	State string `json:"state"`
}

type Data struct {
	header []string
	lines  []Person
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.