I'm trying to find the memory leak and I've zeroed it down to this portion of code but I can't find where the memory leak is or how to fix it, when I had some people look into it they suggested it has to do with "tickers" as mentioned here: https://golang.org/src/time/tick.go it "leaks". Any ideas on fixes?
Thanks! :)
package main
import (
"bufio"
"encoding/csv"
"fmt"
"log"
"os"
"time"
)
// Records information about a transfer window: the total amount of data
// transferred in a fixed time period in a particular direction (clientbound or
// serverbound) in a session.
type DataLoggerRecord struct {
// Number of bytes transferred in this transfer window.
Bytes uint
}
var DataLoggerRecords = make(chan *DataLoggerRecord, 64)
// The channel returned should be used to send the number of bytes transferred
// whenever a transfer is done.
func measureBandwidth() (bandwidthChan chan uint) {
bandwidthChan = make(chan uint, 64)
timer := time.NewTicker(config.DL.FlushInterval * time.Second)
go func() {
for _ = range timer.C {
drainchan(bandwidthChan)
}
}()
go func() {
var count uint
ticker := time.Tick(config.DL.Interval)
for {
select {
case n := <-bandwidthChan:
count += n
case <-ticker:
DataLoggerRecords <- &DataLoggerRecord{
Bytes: count,
}
count = 0
}
}
}()
return bandwidthChan
}
func drainchan(bandwidthChan chan uint) {
for {
select {
case e := <-bandwidthChan:
fmt.Printf("%s\n", e)
default:
return
}
}
}
func runDataLogger() {
f, err := os.OpenFile(dataloc, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalf("[DL] Could not open %s", err.Error())
}
bw := bufio.NewWriter(f)
defer func() {
bw.Flush()
f.Close()
}()
go func() {
for {
time.Sleep(time.Second)
bw.Flush()
}
}()
w := csv.NewWriter(bw)
for record := range DataLoggerRecords {
if record.Bytes != 0 {
err = w.Write([]string{
fmt.Sprintf("%d", record.Bytes),
})
w.Flush()
} else {
continue
}
}
if err != nil {
if err.Error() != "short write" {
log.Printf("[DL] Failed to write record: %s", err.Error())
} else {
w.Flush()
}
}
}
measureBandwidthcreates 2 tickers that are never stopped, and starts 2 goroutines which never return. If you call that repeatedly you'll be "leaking" those resources.