code: func (g *GoroutinePool) Schedule(job, onCanceled func()) {
  	g.wg.Add(1)
  	// Note: We could save a bit of memory by preallocating maxConcurrentJobs
  	// goroutines instead of one goroutine per item.
  	go func() {
  		defer g.wg.Done()
  		if g.sema.wait(g.ctx) == nil {
  			defer g.sema.signal()
  			job()
  		} else if onCanceled != nil {
  			onCanceled()
  		}
  	}()
  }
docs: // Schedule adds a new job for execution as a separate goroutine.
  //
  // If the GoroutinePool context is canceled, onCanceled is called instead. It
  // is fine to pass nil as onCanceled.