diff options
author | Luke Shumaker <lukeshu@beefcake.parabola.nu> | 2018-05-19 02:20:59 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@beefcake.parabola.nu> | 2018-05-19 02:20:59 -0400 |
commit | 383e075a62ca4e4250c1d652913c4de375a03bc5 (patch) | |
tree | 9f3e788076c18e2a11c6ff8c9b9c9f84bede1308 | |
parent | 86201baa1bf72f9717fc4643cd0a00554a23bd72 (diff) |
async status line
-rw-r--r-- | go/src/cow-dedupe/dedupe.go | 7 | ||||
-rw-r--r-- | go/src/lib/statusline/async.go | 45 |
2 files changed, 49 insertions, 3 deletions
diff --git a/go/src/cow-dedupe/dedupe.go b/go/src/cow-dedupe/dedupe.go index 9fee970..62fd85d 100644 --- a/go/src/cow-dedupe/dedupe.go +++ b/go/src/cow-dedupe/dedupe.go @@ -10,6 +10,7 @@ import ( "runtime" "strconv" "strings" + "time" "lib/statusline" ) @@ -34,7 +35,7 @@ func getFiemaps(paths []string) map[string][]string { ret := map[string][]string{} - sl := statusline.NewStatusLine(os.Stderr) + sl := statusline.NewAsyncStatusLine(os.Stderr, time.Second/2) cnt := 0 sl.Put("Mapping extents...") @@ -77,7 +78,7 @@ func getFiemaps(paths []string) map[string][]string { func getChecksums(paths []string) map[string][]string { ret := map[string][]string{} - sl := statusline.NewStatusLine(os.Stderr) + sl := statusline.NewAsyncStatusLine(os.Stderr, time.Second/2) cnt := 0 sl.Put(fmt.Sprintf("Generating checksums for files... %d/%d\n", cnt, len(paths))) @@ -128,7 +129,7 @@ func getChecksums(paths []string) map[string][]string { func main() { // we have low parallelism, don't let syscalls fan-out weird // on many-core systems - runtime.GOMAXPROCS(1) + runtime.GOMAXPROCS(2) fiemap2filenames := getFiemaps(os.Args[1:]) diff --git a/go/src/lib/statusline/async.go b/go/src/lib/statusline/async.go new file mode 100644 index 0000000..32c9a2b --- /dev/null +++ b/go/src/lib/statusline/async.go @@ -0,0 +1,45 @@ +package statusline + +import ( + "io" + "time" +) + +type AsyncStatusLine struct { + lines chan string + end chan struct{} +} + +func NewAsyncStatusLine(out io.Writer, d time.Duration) *AsyncStatusLine { + ret := &AsyncStatusLine{ + lines: make(chan string), + end: make(chan struct{}), + } + go func() { + sl := NewStatusLine(out) + ticker := time.NewTicker(d) + var line string + for { + select { + case <-ticker.C: + sl.Put(line) + case l := <-ret.lines: + line = l + case <-ret.end: + sl.End() + ticker.Stop() + } + } + }() + return ret +} + +func (sl *AsyncStatusLine) Put(line string) { + sl.lines <- line +} + +func (sl *AsyncStatusLine) End() { + sl.end <- struct{}{} + close(sl.lines) + close(sl.end) +} |