func (p *Pool) Start() (context.CancelFunc, error) {
	p.mu.Lock()
	defer p.mu.Unlock()
	if p.running {
		return nil, ErrPoolAlreadyRunning
	}
	if p.sleepTime == nil {
		return nil, ErrPoolHasNilSleepTimeFunc
	}
	p.monitorPoolSize = true
	var cancel context.CancelFunc
	p.ctx, cancel = context.WithCancel(p.ctx)
	p.running = true
	p.doneChan = make(chan struct{})
	wrappedCancel := getWrappedContextCancelFunc(p, cancel)
	p.cancel = wrappedCancel
	go monitorPool(p)
	return wrappedCancel, nil
}
Start initiates the pool monitor
package gopool
import (
	"sync"
	"context"
)
type WorkerCountFunc func() uint64
func NewPool(id string, work WorkFunc, desiredWorkerCount WorkerCountFunc, sleepTime SleepTimeFunc, ctx context.Context) *Pool {
	p := new(Pool)
	p.id = id
	p.work = work
	p.workers = make([]poolWorker, 0)
	p.desiredWorkerCount = desiredWorkerCount
	p.sleepTime = sleepTime
	p.ctx = ctx
	p.ctx = context.WithValue(p.ctx, "poolId", p.id)
	p.monitorPoolSize = true
	return p
}
type poolWorker struct {
	cancel context.CancelFunc
	worker *Worker
}
type Pool struct {
	mu                 sync.Mutex
	id                 string
	work               WorkFunc
	workers            []poolWorker
	desiredWorkerCount WorkerCountFunc
	sleepTime          SleepTimeFunc
	ctx                context.Context
	cancel             context.CancelFunc
	monitorPoolSize    bool
	running            bool
	doneChan           chan struct{}
}
func (p *Pool) ID() string {
	p.mu.Lock()
	defer p.mu.Unlock()
	return p.id
}
func (p *Pool) Context() context.Context {
	p.mu.Lock()
	defer p.mu.Unlock()
	return p.ctx
}