[fix]: 解决定时器同步数据到热存储中的数据竞争问题 https://github.com/eatmoreapple/openwech… (#219)

This commit is contained in:
多吃点苹果 2023-02-01 23:43:10 +08:00 committed by GitHub
parent 6be6359e34
commit 76bd0a5648
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,6 +3,7 @@ package openwechat
import (
"io"
"os"
"sync"
"time"
)
@ -29,9 +30,12 @@ type HotReloadStorage io.ReadWriter
type jsonFileHotReloadStorage struct {
filename string
file *os.File
lock sync.Mutex
}
func (j *jsonFileHotReloadStorage) Read(p []byte) (n int, err error) {
j.lock.Lock()
defer j.lock.Unlock()
if j.file == nil {
j.file, err = os.OpenFile(j.filename, os.O_RDWR, 0600)
if os.IsNotExist(err) {
@ -45,21 +49,22 @@ func (j *jsonFileHotReloadStorage) Read(p []byte) (n int, err error) {
}
func (j *jsonFileHotReloadStorage) Write(p []byte) (n int, err error) {
j.lock.Lock()
defer j.lock.Unlock()
if j.file == nil {
j.file, err = os.Create(j.filename)
if err != nil {
return 0, err
}
}
// 为什么这里要对文件进行Truncate操作呢?
// 这是为了方便每次Dump的时候对文件进行重新写入, 而不是追加
// json序列化写入只会调用一次Write方法, 所以不要把这个方法当成io.Writer的Write方法
// reset offset and truncate file
if _, err = j.file.Seek(0, io.SeekStart); err != nil {
return
}
if err = j.file.Truncate(0); err != nil {
return
}
// json decode only write once
return j.file.Write(p)
}