feat: disk usage add cache

This commit is contained in:
Samuel N Cui
2023-09-28 01:38:14 +08:00
parent 786cd32f8d
commit 44b54705fc
4 changed files with 67 additions and 15 deletions

4
acp.go
View File

@@ -12,6 +12,7 @@ type Copyer struct {
running sync.WaitGroup
eventCh chan Event
getDevice func(in string) string
getDiskUsageCache func(mountPoint string) *diskUsageCache
}
func New(ctx context.Context, opts ...Option) (*Copyer, error) {
@@ -35,6 +36,9 @@ func New(ctx context.Context, opts ...Option) (*Copyer, error) {
option: opt,
eventCh: make(chan Event, 128),
getDevice: getDevice,
getDiskUsageCache: Cache(func(mountPoint string) *diskUsageCache {
return newDiskUsageCache(mountPoint, defaultDiskUsageFreshInterval)
}),
}
c.running.Add(1)

View File

@@ -1,8 +1,8 @@
package acp
func Cache[i comparable, o any](f func(in i) o) func(in i) o {
cache := make(map[i]o, 0)
return func(in i) o {
func Cache[K comparable, V any](f func(in K) V) func(in K) V {
cache := make(map[K]V, 0)
return func(in K) V {
cached, has := cache[in]
if has {
return cached

13
copy.go
View File

@@ -16,7 +16,6 @@ import (
mapset "github.com/deckarep/golang-set/v2"
sha256 "github.com/minio/sha256-simd"
"github.com/samber/lo"
"github.com/samuelncui/godf"
)
const (
@@ -117,14 +116,12 @@ func (c *Copyer) write(ctx context.Context, job *writeJob, ch chan<- *baseJob, c
continue
}
diskUsage, err := godf.NewDiskUsage(dev)
if err != nil {
job.fail(target, fmt.Errorf("read disk usage fail, dev= '%s', %w", dev, err))
continue
}
if int64(diskUsage.Free()) < job.size {
if err := c.getDiskUsageCache(dev).check(job.size); err != nil {
if errors.Is(err, ErrTargetNoSpace) {
noSpaceDevices.Add(dev)
job.fail(target, fmt.Errorf("%w, want= %d have= %d", ErrTargetNoSpace, job.size, diskUsage.Free()))
}
job.fail(target, fmt.Errorf("check disk usage have error, %w", err))
continue
}

51
disk_usage.go Normal file
View File

@@ -0,0 +1,51 @@
package acp
import (
"fmt"
"sync"
"github.com/samuelncui/godf"
)
const (
defaultDiskUsageFreshInterval = 1024 * 1024 * 1024 * 2
)
type diskUsageCache struct {
mountPoint string
freshInterval int64
lock sync.Mutex
freeSpace int64
used int64
}
func newDiskUsageCache(mountPoint string, freshInterval int64) *diskUsageCache {
return &diskUsageCache{
mountPoint: mountPoint,
freshInterval: freshInterval,
}
}
func (m *diskUsageCache) check(need int64) error {
m.lock.Lock()
defer m.lock.Unlock()
m.used += need
if m.used <= m.freeSpace && m.used < m.freshInterval {
return nil
}
usage, err := godf.NewDiskUsage(m.mountPoint)
if err != nil {
return fmt.Errorf("get disk usage fail, mount_point= %s", m.mountPoint)
}
m.freeSpace = int64(usage.Available())
m.used = need
if m.used > m.freeSpace {
return fmt.Errorf("%w, want= %d have= %d", ErrTargetNoSpace, m.used, m.freeSpace)
}
return nil
}