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.