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

10
acp.go
View File

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

View File

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

15
copy.go
View File

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