func (rl *RateLimiter) LimitedGo(f process.ProcessFunc) {

	<-rl.limiter
	p := rl.Go(f)

	// this <-closed() is here because the child may have spawned
	// children of its own, and our rate limiter should capture that.
	go func() {
		<-p.Closed()
		rl.limiter <- struct{}{}
	}()
}
func (rl *RateLimiter) LimitedGo(f process.ProcessFunc) {

	<-rl.limiter
	p := rl.Go(f)

	
	
	go func() {
		<-p.Closed()
		rl.limiter <- struct{}{}
	}()
}
func ( rl * RateLimiter ) LimitedGo ( f process . ProcessFunc ) { <- rl . limiter p := rl . Go ( f ) // this <-closed() is here because the child may have spawned // children of its own, and our rate limiter should capture that. go func ( ) { <- p . Closed ( ) rl . limiter <- struct { } { } } ( ) }
// LimitedGo creates a new process, adds it as a child, and spawns the
// ProcessFunc f in its own goroutine, but may block according to the
// internal rate limit. It is equivalent to:
//
//   func(f process.ProcessFunc) {
//      <-limitch
//      p.Go(func (child process.Process) {
//        f(child)
//        f.Close() // make sure its children close too!
//        limitch<- struct{}{}
//      })
///  }
//
// It is useful to construct simple asynchronous workers, children of p,
// and rate limit their creation, to avoid spinning up too many, too fast.
// This is great for providing backpressure to producers.
LimitedGo creates a new process adds it as a child and spawns the ProcessFunc f in its own goroutine but may block according to the internal rate limit . It is equivalent to : func ( f process . ProcessFunc ) { < - limitch p . Go ( func ( child process . Process ) { f ( child ) f . Close () // make sure its children close too! limitch< - struct {} {} } ) / } It is useful to construct simple asynchronous workers children of p and rate limit their creation to avoid spinning up too many too fast . This is great for providing backpressure to producers .