todocounter

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 26, 2019 License: MIT Imports: 1 Imported by: 26

README

go-todocounter

standard-readme compliant

A threadsafe counter

Documenation

See https://godoc.org/github.com/ipfs/go-todocounter.

Contribute

Feel free to join in. All welcome. Open an issue!

This repository falls under the IPFS Code of Conduct.

Want to hack on IPFS?

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Counter

type Counter interface {
	// Incrememnt adds a number of todos to track.
	// If the counter is **below** zero, it panics.
	Increment(i uint32)

	// Decrement removes a number of todos to track.
	// If the count drops to zero, signals done and destroys the counter.
	// If the count drops **below** zero, panics. It means you have tried to remove
	// more things than you added, i.e. sync issues.
	Decrement(i uint32)

	// Done returns a channel to wait upon. Use it in selects:
	//
	//  select {
	//  case <-ctr.Done():
	//    // done processing all items
	//  }
	//
	Done() <-chan struct{}

	Remaining() int32
}

Counter records things remaining to process. It is needed for complicated cases where multiple goroutines are spawned to process items, and they may generate more items to process. For example, say a query over a set of nodes may yield either a result value, or more nodes to query. Signaling is subtly complicated, because the queue may be empty while items are being processed, that will end up adding more items to the queue.

Use Counter like this:

todos := make(chan int, 10)
ctr := todoctr.NewCounter()

process := func(item int) {
  fmt.Println("processing %d\n...", item)

  // this task may randomly generate more tasks
  if rand.Intn(5) == 0 {
    todos<- item + 1
    ctr.Increment(1) // increment counter for new task.
  }

  ctr.Decrement(1) // decrement one to signal the task being done.
}

// add some tasks.
todos<- 1
todos<- 2
todos<- 3
todos<- 4
ctr.Increment(4)

for {
  select {
  case item := <- todos:
    go process(item)
  case <-ctr.Done():
    fmt.Println("done processing everything.")
    close(todos)
  }
}

func NewSyncCounter

func NewSyncCounter() Counter

NewSyncCounter constructs a new counter

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL