Files
acp/progress_bar.go
T
Samuel Cui ac02c71d3f feat!: stream caller-owned items and own the result queue
Reshape the public API around one push engine and restore the af05f05c
surface as a compatibility shell over it.

- NewStream takes caller-owned items (Source/Targets), reports every accepted
  item through one results callback, and Wait returns the run's terminal error.
  Run, BatchSource and the item callbacks are gone.
- The engine owns the result path: WithResultBuffer is the depth of the result
  queue, WithResultBatch is how many results one delivery carries, and
  WithResultFlushInterval is how long a successful result may wait. A result
  that carries any error is delivered immediately as its own batch.
- Restore the af05f05c API byte-compatibly in the same package: New, Copyer,
  Wait/WaitErr, AccurateJob, WildcardJob, the report events and the JSON report
  round-trip through encoding/json alone.
- One descriptor serves a whole item; the stored hash is read through the
  descriptor that reads the content and the computed hash is published through
  it before it closes.
- Make every handoff escapable by a hard stop: the read buffer, a chunk send,
  an event send and the result buffer.
- Fix the recorded sweep findings: report indent and round-trip, cmd/acp exit
  status, acp-rewrite final paths, mmap EOF/close/slice, disk-usage
  reservations, ErrTargetIO identity, the fatal-panic safety net, option
  validation, and the FreeBSD/Windows build paths.
- Cover the contract with semantic tests, add Makefile check/race/vet/cross
  targets, and document the withdrawn v0.1.0/v0.2.0 migration in README.
2026-09-19 15:18:13 +08:00

53 lines
1.4 KiB
Go

package acp
import (
"fmt"
"os"
"time"
"github.com/schollz/progressbar/v3"
)
func NewProgressBar() EventHandler {
// progressBar := progressbar.DefaultBytes(1, "[0/0] indexing...")
bar := 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),
)
// totalFiles is handler state without a lock. ACP calls one registered handler from one
// goroutine at a time and never concurrently, so the count event and the progress events
// below cannot race; see EventHandler for the contract this relies on.
var totalFiles int64
return func(ev Event) {
switch e := ev.(type) {
case *EventUpdateCount:
totalFiles = e.Files
bar.Describe(fmt.Sprintf("[0/%d] indexing...", totalFiles))
bar.ChangeMax64(e.Bytes)
return
case *EventUpdateProgress:
bar.Set64(e.Bytes)
if !e.Finished {
bar.Describe(fmt.Sprintf("[%d/%d] copying...", e.Files, totalFiles))
return
}
bar.Describe(fmt.Sprintf("[%d/%d] finishing...", e.Files, totalFiles))
return
default:
return
}
}
}