github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/traverse/reporter.go (about)

     1  // Copyright 2018 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache 2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package traverse
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"sync"
    11  )
    12  
    13  // A Reporter receives events from an ongoing traversal. Reporters
    14  // can be passed as options into Traverse, and are used to monitor
    15  // progress of long-running traversals.
    16  type Reporter interface {
    17  	// Init is called when processing is about to begin. Parameter
    18  	// n indicates the number of tasks to be executed by the traversal.
    19  	Init(n int)
    20  	// Complete is called after the traversal has completed.
    21  	Complete()
    22  
    23  	// Begin is called when task i is begun.
    24  	Begin(i int)
    25  	// End is called when task i has completed.
    26  	End(i int)
    27  }
    28  
    29  // NewSimpleReporter returns a new reporter that prints the number
    30  // of queued, running, and completed tasks to stderr.
    31  func NewSimpleReporter(name string) Reporter {
    32  	return &simpleReporter{name: name}
    33  }
    34  
    35  type simpleReporter struct {
    36  	name                  string
    37  	mu                    sync.Mutex
    38  	queued, running, done int
    39  }
    40  
    41  func (r *simpleReporter) Init(n int) {
    42  	r.mu.Lock()
    43  	r.queued = n
    44  	r.update()
    45  	r.mu.Unlock()
    46  }
    47  
    48  func (r *simpleReporter) Complete() {
    49  	fmt.Fprintf(os.Stderr, "\n")
    50  }
    51  
    52  func (r *simpleReporter) Begin(i int) {
    53  	r.mu.Lock()
    54  	r.queued--
    55  	r.running++
    56  	r.update()
    57  	r.mu.Unlock()
    58  }
    59  
    60  func (r *simpleReporter) End(i int) {
    61  	r.mu.Lock()
    62  	r.running--
    63  	r.done++
    64  	r.update()
    65  	r.mu.Unlock()
    66  }
    67  
    68  func (r *simpleReporter) update() {
    69  	fmt.Fprintf(os.Stderr, "%s: (queued: %d -> running: %d -> done: %d) \r", r.name, r.queued, r.running, r.done)
    70  }