func (pool *WorkerPool) Expand(n int, timeout time.Duration, quit <-chan struct{}) bool {
	if pool.stopped() {
		return false
	}
	for i := 0; i < n; i++ {
		var builder workerBuilder
		w := builder.
			withPool(pool.pool).
			withPoolQuit(pool.quit).
			withTimeout(timeout).
			withQuit(pool.quit).
			build()
		w.initWorker(&pool.wg)
	}
	return true
}
Expand is for putting more 'Worker's into work. If there is'nt any job to do,
and a timeout is set, they will simply get timed-out.
Default behavior is they will timeout in a sliding manner.
A quit channel can be used too, to explicitly stop extra workers.

One firend noted that there might be a *temporary* goroutine leak, when expanding
the worker pool, using timeouts. Actually is's not a goroutine leak because
it's always bound to the size of pool and has a deterministic behavior.
Assuming we have a worker pool of size 10, and we expand it with a 1000 extra workers,
that would timeout after 100 mili-seconds, we may see (after some 100 mili-second)
there remains twice the initial size of the pool (10 * 2) number of goroutines - which
of-cource would get timedout after doing some extra jobs and the pool will shrink
to it's initial size. The reason for this temporary expanded lives of some extra
workers is, the initial workers may fail to register before those extra workers.
So we will have 10 registered extra workers, plus 10 unregistered initial workers.
And the rest of extra workers will get timedout because they fail to register.
So we have 20 goroutines in the pool at max, in this very specific situation,
which will evantually get timed out. That's not a goroutine leak (it described
as *temporary* in the first place) but it was entertaining to find out why and
how that happens! A test named `TestTimeoutNoGoroutineLeak(...)` is added to
descibe this in code.
package workerpool
import (
	"runtime"
	"sync"
	"time"
)
type WorkerPool struct {
	pool chan chan func()
	jobs chan func()
	quit     chan struct{}
	quitOnce sync.Once
	wg       sync.WaitGroup
}
func New(workerCount, jobQueueSize int) *WorkerPool {
	if jobQueueSize < 0 {
		jobQueueSize = 0
	}
	if workerCount < 0 {
		workerCount = runtime.NumCPU()
	}
	pool := WorkerPool{
		pool: make(chan chan func(), workerCount),
		jobs: make(chan func(), jobQueueSize),
		quit: make(chan struct{}),
		wg:   sync.WaitGroup{},
	}
	for i := 0; i < workerCount; i++ {
		var builder workerBuilder
		w := builder.
			withPool(pool.pool).
			withPoolQuit(pool.quit).
			withTimeout(0).
			withQuit(pool.quit).
			build()
		w.initWorker(&pool.wg)
	}
	go pool.dispatch()
	return &pool
}
func (pool *WorkerPool) Queue(job func(), timeout time.Duration) bool {
	if pool.stopped() {
		return false
	}
	var t <-chan time.Time
	if timeout > 0 {
		t = time.After(timeout)
	}
	select {
	case pool.jobs <- job:
	case <-t:
		return false
	case <-pool.quit:
		return false
	}
	return true
}
func (pool *WorkerPool) Stop() {
	pool.quitOnce.Do(func() { close(pool.quit) })
	pool.wg.Wait()
}