diff --git a/.gitignore b/.gitignore index c74eceb..80518b2 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,6 @@ # Dependency directories (remove the comment below to include it) # vendor/ -./go.sum +go.sum output/ +test.sh diff --git a/copy.go b/copy.go index df35f46..304ad0b 100644 --- a/copy.go +++ b/copy.go @@ -42,7 +42,6 @@ type Copyer struct { copyedFiles int64 totalFiles int64 - progressBarLock sync.Mutex updateProgressBar func(func(bar *progressbar.ProgressBar)) jobs []*Job @@ -69,6 +68,7 @@ func New(ctx context.Context, opts ...Option) (*Copyer, error) { c := &Copyer{ option: opt, + stage: StageIndex, writePipe: make(chan *writeJob, 32), metaPipe: make(chan *metaJob, 8), updateProgressBar: func(f func(bar *progressbar.ProgressBar)) {}, @@ -118,6 +118,11 @@ func (c *Copyer) index(ctx context.Context) { for _, s := range c.src { c.walk(s.base, s.path) } + + c.updateProgressBar(func(bar *progressbar.ProgressBar) { + bar.ChangeMax64(atomic.LoadInt64(&c.totalBytes)) + bar.Describe(fmt.Sprintf("[0/%d] index finished...", atomic.LoadInt64(&c.totalFiles))) + }) } func (c *Copyer) copy(ctx context.Context) { diff --git a/go.sum b/go.sum deleted file mode 100644 index 70d3968..0000000 --- a/go.sum +++ /dev/null @@ -1,40 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= -github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= -github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= -github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/schollz/progressbar/v3 v3.10.1 h1:6A8v8TIcCJL4yemlUJS9gdcpZ++Gy6toOh1JzKQkz+U= -github.com/schollz/progressbar/v3 v3.10.1/go.mod h1:R2djRgv58sn00AGysc4fN0ip4piOGd3z88K+zVBjczs= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY= -golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/progress_bar.go b/progress_bar.go index a8b2742..c0bb7e1 100644 --- a/progress_bar.go +++ b/progress_bar.go @@ -3,17 +3,39 @@ package acp import ( "context" "fmt" + "os" + "sync" "sync/atomic" "time" "github.com/schollz/progressbar/v3" ) +const ( + barUpdateInterval = time.Nanosecond * 255002861 +) + func (c *Copyer) startProgressBar(ctx context.Context) { - progressBar := progressbar.DefaultBytes(0, "[0/0] indexing...") + var lock sync.Mutex + + // progressBar := progressbar.DefaultBytes(1, "[0/0] indexing...") + progressBar := progressbar.NewOptions64( + 1, + progressbar.OptionSetDescription("[0/0] indexing..."), + progressbar.OptionSetWriter(os.Stderr), + progressbar.OptionShowBytes(true), + progressbar.OptionSetWidth(10), + progressbar.OptionThrottle(65*time.Millisecond), + progressbar.OptionShowCount(), + progressbar.OptionOnCompletion(func() {}), + progressbar.OptionSpinnerType(14), + progressbar.OptionFullWidth(), + progressbar.OptionSetRenderBlankState(true), + ) + c.updateProgressBar = func(f func(bar *progressbar.ProgressBar)) { - c.progressBarLock.Lock() - defer c.progressBarLock.Unlock() + lock.Lock() + defer lock.Unlock() if progressBar == nil { return @@ -22,14 +44,12 @@ func (c *Copyer) startProgressBar(ctx context.Context) { } go func() { - ticker := time.NewTicker(time.Nanosecond * 255002861) // around 255ms, avoid conflict with progress bar fresh by second + ticker := time.NewTicker(barUpdateInterval) // around 255ms, avoid conflict with progress bar fresh by second defer ticker.Stop() var lastCopyedBytes int64 for range ticker.C { - c.progressBarLock.Lock() - - switch c.stage { + switch atomic.LoadInt64(&c.stage) { case StageIndex: go c.updateProgressBar(func(bar *progressbar.ProgressBar) { bar.ChangeMax64(atomic.LoadInt64(&c.totalBytes)) @@ -37,11 +57,11 @@ func (c *Copyer) startProgressBar(ctx context.Context) { }) case StageCopy: currentCopyedBytes := atomic.LoadInt64(&c.copyedBytes) - diff := int(currentCopyedBytes - lastCopyedBytes) + diff := currentCopyedBytes - lastCopyedBytes lastCopyedBytes = currentCopyedBytes go c.updateProgressBar(func(bar *progressbar.ProgressBar) { - bar.Add(diff) + bar.Add64(diff) }) case StageFinished: currentCopyedBytes := atomic.LoadInt64(&c.copyedBytes) @@ -49,7 +69,6 @@ func (c *Copyer) startProgressBar(ctx context.Context) { lastCopyedBytes = currentCopyedBytes copyedFiles, totalFiles := atomic.LoadInt64(&c.copyedFiles), atomic.LoadInt64(&c.totalFiles) - c.updateProgressBar(func(bar *progressbar.ProgressBar) { bar.Add(diff) bar.Describe(fmt.Sprintf("[%d/%d] finished!", copyedFiles, totalFiles)) @@ -58,6 +77,7 @@ func (c *Copyer) startProgressBar(ctx context.Context) { select { case <-ctx.Done(): + time.Sleep(barUpdateInterval) c.updateProgressBar(func(bar *progressbar.ProgressBar) { bar.Close() progressBar = nil @@ -65,8 +85,6 @@ func (c *Copyer) startProgressBar(ctx context.Context) { return default: } - - c.progressBarLock.Unlock() } }() }