package main import ( "fmt" "sync" ) // An interface which represents a job to be done by the pool type Job interface { Run() // Start the job Abort() // Abort any work that needs to be completed and close the DoneChannel DoneChannel() chan struct{} // Returns a channel that is closed when the job is done } // An interface which represents a pool of workers doing jobs type JobPool struct { MaxThreads int jobQueue chan Job jobQueueDone chan struct{} jobQueueAborted chan struct{} jobQueueShutDown chan struct{} } func NewJobPool(maxThreads int) (*JobPool) { q := JobPool { MaxThreads: maxThreads, jobQueue: make(chan Job), jobQueueDone: make(chan struct{}), // Closing will shut down workers and reject any incoming work jobQueueAborted: make(chan struct{}), // Closing tells workers to abort jobQueueShutDown: make(chan struct{}), // Closed when all workers are shut down } return &q } func (q *JobPool) RunJob(j Job) error { select { case <-q.jobQueueDone: return fmt.Errorf("job queue closed") default: } q.jobQueue <- j return nil } func (q *JobPool) Run() { if q.MaxThreads > 0 { // Create pool of routines that read from the queue and run jobs var w sync.WaitGroup for i:=0; i