In my application, I listen to nats and the output I get is a map with data. I need to generate a daily csv file using the data from the map. Now the data from the map is written to the file continuously. How can I write data to the file only at the end of each day?
type Hits struct {
HitMap map[string]map[SearchRequestKey]uint32
Mu sync.RWMutex
Log zerolog.Logger
TimeStart time.Time
MinHits int
WasDelete map[string]int64
Cnt1 float32
Version int
QQMap map[string]struct{}
GitlabToken string
}
type SearchRequestKey struct {
Query string
Date string
}
func FileAdd(hits *models.Hits) {
file, err := os.OpenFile("query-hits.csv", os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
fmt.Println(err)
}
writer := csv.NewWriter(file)
writer.Comma = '|'
for key, value := range hits.HitMap {
for query, shard := range value {
err := writer.Write([]string{query.Query, key, strconv.Itoa(int(shard))})
if err != nil {
fmt.Println(err)
}
}
}
}
CodePudding user response:
In order to create a .csv file daily, you need to run the code in a loop and make the current time as the starting point. After 24 hours the function will generate the file again. Finally the way with time.AfterFunc() helped. Don't forget to use mutex.
type Hits struct {
HitMap map[string]map[SearchRequestKey]uint32
Mu sync.RWMutex
Log zerolog.Logger
TimeStart time.Time
MinHits int
WasDelete map[string]int64
Cnt1 float32
Version int
QQMap map[string]struct{}
GitlabToken string
}
type SearchRequestKey struct {
Query string
Date string
}
func FileAdd(hits *models.Hits) {
hits.Mu.Lock()
defer hits.Mu.Unlock()
for {
year, month, day := time.Now().Date()
file := strconv.Itoa(year) month.String() strconv.Itoa(day)
fileName, err := os.Create(file)
if err != nil {
fmt.Println(err)
}
writer := csv.NewWriter(fileName)
writer.Comma = '|'
for key, value := range hits.HitMap {
for query, shard := range value {
err := writer.Write([]string{query.Query, key, strconv.Itoa(int(shard))})
if err != nil {
fmt.Println(err)
}
}
}
time.Sleep(24 * time.Hour) //only after 24 hours
}
}
func FuncThatStart (hits *models.Hits) {
hits.Mu.Lock()
defer hits.Mu.Unlock()
// generate for one day
today := time.Now()
tomorrow := today.Add(24 * time.Hour) // same time as in time.Sleep()
time.AfterFunc(time.Until(tomorrow), func() {
go storage.FileAdd(hits) //goroutine handle one time per day
})
}
Thanks for comments