[fix]: 解决定时器同步数据到热存储中的数据竞争问题 https://github.com/eatmoreapple/openwech… (#219)
This commit is contained in:
parent
6be6359e34
commit
76bd0a5648
11
stroage.go
11
stroage.go
@ -3,6 +3,7 @@ package openwechat
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,9 +30,12 @@ type HotReloadStorage io.ReadWriter
|
|||||||
type jsonFileHotReloadStorage struct {
|
type jsonFileHotReloadStorage struct {
|
||||||
filename string
|
filename string
|
||||||
file *os.File
|
file *os.File
|
||||||
|
lock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *jsonFileHotReloadStorage) Read(p []byte) (n int, err error) {
|
func (j *jsonFileHotReloadStorage) Read(p []byte) (n int, err error) {
|
||||||
|
j.lock.Lock()
|
||||||
|
defer j.lock.Unlock()
|
||||||
if j.file == nil {
|
if j.file == nil {
|
||||||
j.file, err = os.OpenFile(j.filename, os.O_RDWR, 0600)
|
j.file, err = os.OpenFile(j.filename, os.O_RDWR, 0600)
|
||||||
if os.IsNotExist(err) {
|
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) {
|
func (j *jsonFileHotReloadStorage) Write(p []byte) (n int, err error) {
|
||||||
|
j.lock.Lock()
|
||||||
|
defer j.lock.Unlock()
|
||||||
if j.file == nil {
|
if j.file == nil {
|
||||||
j.file, err = os.Create(j.filename)
|
j.file, err = os.Create(j.filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 为什么这里要对文件进行Truncate操作呢?
|
// reset offset and truncate file
|
||||||
// 这是为了方便每次Dump的时候对文件进行重新写入, 而不是追加
|
|
||||||
// json序列化写入只会调用一次Write方法, 所以不要把这个方法当成io.Writer的Write方法
|
|
||||||
if _, err = j.file.Seek(0, io.SeekStart); err != nil {
|
if _, err = j.file.Seek(0, io.SeekStart); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = j.file.Truncate(0); err != nil {
|
if err = j.file.Truncate(0); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// json decode only write once
|
||||||
return j.file.Write(p)
|
return j.file.Write(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user