mirror of
https://github.com/haiwen/seafile-server.git
synced 2025-06-29 16:36:52 +00:00
66 lines
1.1 KiB
Go
66 lines
1.1 KiB
Go
package workerpool
|
|
|
|
import (
|
|
"runtime/debug"
|
|
|
|
"github.com/dgraph-io/ristretto/z"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type WorkPool struct {
|
|
jobs chan Job
|
|
jobCB JobCB
|
|
closer *z.Closer
|
|
}
|
|
|
|
// Job is the job object of workpool.
|
|
type Job struct {
|
|
callback JobCB
|
|
args []interface{}
|
|
}
|
|
|
|
type JobCB func(args ...interface{}) error
|
|
|
|
func CreateWorkerPool(jobCB JobCB, n int) *WorkPool {
|
|
pool := new(WorkPool)
|
|
pool.jobCB = jobCB
|
|
pool.jobs = make(chan Job, 100)
|
|
pool.closer = z.NewCloser(n)
|
|
for i := 0; i < n; i++ {
|
|
go pool.run(pool.jobs)
|
|
}
|
|
return pool
|
|
}
|
|
|
|
func (pool *WorkPool) AddTask(args ...interface{}) {
|
|
job := Job{pool.jobCB, args}
|
|
pool.jobs <- job
|
|
}
|
|
|
|
func (pool *WorkPool) run(jobs chan Job) {
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
log.Printf("panic: %v\n%s", err, debug.Stack())
|
|
}
|
|
}()
|
|
defer pool.closer.Done()
|
|
|
|
for {
|
|
select {
|
|
case job := <-pool.jobs:
|
|
if job.callback != nil {
|
|
err := job.callback(job.args...)
|
|
if err != nil {
|
|
log.Printf("failed to call jobs: %v.\n", err)
|
|
}
|
|
}
|
|
case <-pool.closer.HasBeenClosed():
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (pool *WorkPool) Shutdown() {
|
|
pool.closer.SignalAndWait()
|
|
}
|