func (p *BaseWorkerPool) Dispose() {
	p.deletionLock.Lock()
	defer p.deletionLock.Unlock()
	select {
	case <-p.disposed:
		return
	default:
		close(p.disposed)
	}
}
Dispose the pool, closing down the workers and releasing any shared resources.
package pool
import (
	"sync"
	"time"
)
type Work func()
type Factory func(maxSize int) (WorkerPool, error)
type WorkerPool interface {
	Submit(w Work)
	Dispose()
	spawnWorkers(sendSize int)
	reserve() bool
	release()
	age() time.Duration
}
type BaseWorkerPool struct {
	workerCount int
	maxSize     int
	sends       chan Work
	deletionLock *sync.RWMutex
	disposed     chan bool
	creationTime time.Time
}
func NewWorkerPool(maxSize int) (WorkerPool, error) {
	return &BaseWorkerPool{
		sends:        make(chan Work, maxSize),
		maxSize:      maxSize,
		deletionLock: &sync.RWMutex{},
		disposed:     make(chan bool),
		workerCount:  0,
		creationTime: time.Now(),
	}, nil
}
func min(x int, y int) int {
	if x < y {
		return x
	}
	return y
}
func (p *BaseWorkerPool) Submit(w Work) {
	p.sends <- w
}
func (p *BaseWorkerPool) spawnWorkers(sendSize int) {
	newWorkers := min(sendSize, p.maxSize-p.workerCount)
	if newWorkers > 0 {
		p.workerCount += newWorkers
		for i := 0; i < newWorkers; i++ {
			go func() {
				for {
					select {
					case send := <-p.sends:
						send()
					case <-p.disposed:
						return
					}
				}
			}()
		}
	}
}
func (p *BaseWorkerPool) reserve() bool {
	p.deletionLock.RLock()
	select {
	case <-p.disposed:
		p.deletionLock.RUnlock()
		return false
	default:
		return true
	}
}
func (p *BaseWorkerPool) release() {
	p.deletionLock.RUnlock()
}
func (p *BaseWorkerPool) age() time.Duration {
	return time.Since(p.creationTime)
}