more async improvements and crypto bugfix
This commit is contained in:
parent
120464c0a5
commit
304135be2e
7 changed files with 161 additions and 79 deletions
|
|
@ -29,13 +29,14 @@ func now() int64 {
|
|||
}
|
||||
|
||||
type MetadataHandler struct {
|
||||
mu sync.RWMutex
|
||||
log logr.Logger
|
||||
md map[string]*Metadata
|
||||
fs *FS
|
||||
dst string
|
||||
f *os.File
|
||||
enc *json.Encoder
|
||||
mu sync.RWMutex
|
||||
done chan struct{}
|
||||
log logr.Logger
|
||||
md map[string]*Metadata
|
||||
fs *FS
|
||||
dst string
|
||||
f *os.File
|
||||
enc *json.Encoder
|
||||
}
|
||||
|
||||
func MetadataGenerator(file string, dst provider.FS, fstat, encrypted bool) error {
|
||||
|
|
@ -109,10 +110,11 @@ func NewMetadataHandler(ctx context.Context, fs *FS, file, dst string, log logr.
|
|||
return nil, errors.New("metadata path is not absolute")
|
||||
}
|
||||
mh = &MetadataHandler{
|
||||
log: log,
|
||||
md: make(map[string]*Metadata),
|
||||
fs: fs,
|
||||
dst: dst,
|
||||
log: log,
|
||||
done: make(chan struct{}),
|
||||
md: make(map[string]*Metadata),
|
||||
fs: fs,
|
||||
dst: dst,
|
||||
}
|
||||
mh.f, err = os.OpenFile(file, os.O_RDWR|os.O_CREATE, 0o640)
|
||||
if err != nil {
|
||||
|
|
@ -230,6 +232,7 @@ func (mh *MetadataHandler) flusher(ctx context.Context) {
|
|||
select {
|
||||
case <-ctx.Done():
|
||||
mh.close()
|
||||
close(mh.done)
|
||||
return
|
||||
case <-time.After(time.Minute * 5):
|
||||
}
|
||||
|
|
@ -302,6 +305,7 @@ func (mh *MetadataHandler) close() {
|
|||
mh.mu.Lock()
|
||||
for _, md := range mh.md {
|
||||
if md.f != nil {
|
||||
close(md.wc)
|
||||
md.f.Sync()
|
||||
md.f.Close()
|
||||
}
|
||||
|
|
@ -309,7 +313,10 @@ func (mh *MetadataHandler) close() {
|
|||
mh.mu.Unlock()
|
||||
mh.flush()
|
||||
mh.f.Close()
|
||||
close(mh.fs.done)
|
||||
}
|
||||
|
||||
func (mh *MetadataHandler) Done() <-chan struct{} {
|
||||
return mh.done
|
||||
}
|
||||
|
||||
type Error string
|
||||
|
|
@ -341,6 +348,8 @@ type Metadata struct {
|
|||
mu sync.RWMutex `json:"-"`
|
||||
fs *FS `json:"-"`
|
||||
f provider.File `json:"-"`
|
||||
wc chan writeAt `json:"-"`
|
||||
err error `json:"-"`
|
||||
name string `json:"-"`
|
||||
Size int64 `json:"s"`
|
||||
Atime int64 `json:"a"`
|
||||
|
|
@ -350,6 +359,7 @@ type Metadata struct {
|
|||
func (md *Metadata) Close() error {
|
||||
md.mu.Lock()
|
||||
defer md.mu.Unlock()
|
||||
close(md.wc)
|
||||
err := md.f.Close()
|
||||
md.f = nil
|
||||
return err
|
||||
|
|
@ -359,6 +369,7 @@ func (md *Metadata) Delete() error {
|
|||
md.mu.Lock()
|
||||
defer md.mu.Unlock()
|
||||
md.Chunks = chunk.Chunks{}
|
||||
close(md.wc)
|
||||
md.f.Close()
|
||||
md.f = nil
|
||||
atomic.StoreInt64(&md.Atime, now())
|
||||
|
|
@ -383,7 +394,7 @@ func (md *Metadata) ChunkSize() int64 {
|
|||
return md.Chunks.Size()
|
||||
}
|
||||
|
||||
func (md *Metadata) AddChunk(off int64, n int) {
|
||||
func (md *Metadata) addChunk(off int64, n int) {
|
||||
md.mu.Lock()
|
||||
defer md.mu.Unlock()
|
||||
md.Chunks.Add(off, n)
|
||||
|
|
@ -400,16 +411,39 @@ func (md *Metadata) AddChunk(off int64, n int) {
|
|||
// return md.f.ReadAt(p, pos)
|
||||
//}
|
||||
|
||||
type writeAt struct {
|
||||
pos int64
|
||||
data []byte
|
||||
}
|
||||
|
||||
func (md *Metadata) writer() {
|
||||
md.wc = make(chan writeAt, 10)
|
||||
go func() {
|
||||
for wa := range md.wc {
|
||||
atomic.StoreInt64(&md.Atime, now())
|
||||
n, err := md.f.WriteAt(wa.data, wa.pos)
|
||||
if err == nil {
|
||||
md.addChunk(wa.pos, n)
|
||||
md.fs.q.Add(n)
|
||||
} else {
|
||||
md.err = err
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (md *Metadata) WriteAt(data []byte, pos int64) (int, error) {
|
||||
if md.err != nil {
|
||||
return 0, md.err
|
||||
}
|
||||
if md.f == nil {
|
||||
err := md.openCacheFile()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
atomic.StoreInt64(&md.Atime, now())
|
||||
md.fs.q.Add(len(data))
|
||||
return md.f.WriteAt(data, pos)
|
||||
md.wc <- writeAt{pos, data}
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
func (md *Metadata) openCacheFile() error {
|
||||
|
|
@ -419,8 +453,12 @@ func (md *Metadata) openCacheFile() error {
|
|||
return nil
|
||||
}
|
||||
f, err := md.fs.openCacheFile(md.name, md.Size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
md.f = f
|
||||
return err
|
||||
md.writer()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (md *Metadata) Stat() (os.FileInfo, error) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue