I was trying to insert documents in the mongoDB using go-client (mgo). I create a new mongo session, and two channels for communcaition b/w go-routines, channel is used to sync b/w readFile and main, while other is to pass data read from file in readFile to db write routine insertTxn.
type Txn struct {
Date time.Time
Amt float64
}
func main() {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
channel := make(chan bool)
txnChannel := make(chan Txn, 1e4)
go readFile(txnChannel, channel)
go insertTxn(session, txnChannel)
<-channel
time.Sleep(time.Second * 10) // waiting for insertTxn to finish
defer func() {
if r := recover(); r != nil {
fmt.Println(r)
}
}()
}
Then, goroutine readFile is started which starts reading from an input file, and writing the data to txnChannel channel. After completion, it marks the completion by writing to channel channel.
func readFile(txnChannel chan<- Txn, channel chan<- bool) { // write only channel
txnFile, err := os.Open("path/to/dir/txns.txt")
if err != nil {
panic(err)
}
txnReader := bufio.NewReader(txnFile)
defer func() {
txnFile.Close()
channel <- true
}()
var data []string
var txn Txn
var dur int
var str string
for i := 0; i < 25*1e2; i++ {
str, err = txnReader.ReadString('
')
str = strings.TrimSuffix(str, "
")
if err != nil {
panic(err)
}
data = strings.Split(str, " ")
txn.Amt, err = strconv.ParseFloat(data[1], 64)
if err != nil {
panic(err)
}
if err != nil {
panic(err)
}
dur, err = strconv.Atoi(data[0])
if err != nil {
panic(err)
}
txn.Date = time.Now().Add(-time.Second * time.Duration(dur))
txnChannel <- txn
}
}
The other goroutine insertTxn, creates a reference to txn collection, and keep listening on the txnChannel channel, and writes the data it receives to the mongo collection.
func insertTxn(session *mgo.Session, txnChannel <-chan Txn) {
txnColl := session.DB("happay").C("txns")
for {
select {
case txn := <-txnChannel:
if err := txnColl.Insert(txn).Error; err != nil {
panic(err)
}
}
}
}
Now, the program panics with following reason:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1151f27]
I believe the issue might be that I am using the same struct again and again, but as I read that writing to a channel does copy by value, rather than by reference. So, it should work. Any help would be highly appreciated.