more async improvements and crypto bugfix

This commit is contained in:
ston1th 2022-08-17 23:58:46 +02:00
commit 304135be2e
7 changed files with 161 additions and 79 deletions

View file

@ -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) {