func (w *worker) run(pool *pools.ResourcePool, job *job, workerFunc workerFunc) { var err error defer func() { resource, poolErr := pool.Get() if poolErr != nil { logger.Criticalf("Error on getting connection in worker %v", w) } else { conn := resource.(*redisConn) w.finish(conn, job, err) pool.Put(conn) } }() defer func() { if r := recover(); r != nil { err = errors.New(fmt.Sprint(r)) } }() resource, err := pool.Get() if err != nil { logger.Criticalf("Error on getting connection in worker %v", w) } else { conn := resource.(*redisConn) w.start(conn, job) pool.Put(conn) } err = workerFunc(job.Queue, job.Payload.Args...) }
func (w *worker) work(pool *pools.ResourcePool, jobs <-chan *job, monitor *sync.WaitGroup) { resource, err := pool.Get() if err != nil { logger.Criticalf("Error on getting connection in worker %v", w) } else { conn := resource.(*redisConn) w.open(conn) pool.Put(conn) } monitor.Add(1) go func() { defer func() { resource, err := pool.Get() if err != nil { logger.Criticalf("Error on getting connection in worker %v", w) } else { conn := resource.(*redisConn) w.close(conn) pool.Put(conn) } monitor.Done() }() for job := range jobs { if workerFunc, ok := workers[job.Payload.Class]; ok { w.run(pool, job, workerFunc) logger.Debugf("done: (Job{%s} | %s | %v)", job.Queue, job.Payload.Class, job.Payload.Args) } else { errorLog := fmt.Sprintf("No worker for %s in queue %s with args %v", job.Payload.Class, job.Queue, job.Payload.Args) logger.Critical(errorLog) resource, err := pool.Get() if err != nil { logger.Criticalf("Error on getting connection in worker %v", w) } else { conn := resource.(*redisConn) w.finish(conn, job, errors.New(errorLog)) pool.Put(conn) } } } }() }
func (p *poller) poll(pool *pools.ResourcePool, interval time.Duration, quit <-chan bool) <-chan *job { jobs := make(chan *job) resource, err := pool.Get() if err != nil { logger.Criticalf("Error on getting connection in poller %s", p) } else { conn := resource.(*redisConn) p.open(conn) p.start(conn) pool.Put(conn) } go func() { defer func() { close(jobs) resource, err := pool.Get() if err != nil { logger.Criticalf("Error on getting connection in poller %s", p) } else { conn := resource.(*redisConn) p.finish(conn) p.close(conn) pool.Put(conn) } }() for { select { case <-quit: return default: resource, err := pool.Get() if err != nil { logger.Criticalf("Error on getting connection in poller %s", p) return } else { conn := resource.(*redisConn) job, err := p.getJob(conn) if err != nil { logger.Errorf("Error on %v getting job from %v: %v", p, p.Queues, err) } if job != nil { conn.Send("INCR", fmt.Sprintf("%sstat:processed:%v", namespace, p)) conn.Flush() pool.Put(conn) select { case jobs <- job: case <-quit: buf, err := json.Marshal(job.Payload) if err != nil { logger.Criticalf("Error requeueing %v: %v", job, err) return } resource, err := pool.Get() if err != nil { logger.Criticalf("Error on getting connection in poller %s", p) } conn := resource.(*redisConn) conn.Send("LPUSH", fmt.Sprintf("%squeue:%s", namespace, job.Queue), buf) conn.Flush() return } } else { pool.Put(conn) if exitOnComplete { return } else { logger.Debugf("Sleeping for %v", interval) logger.Debugf("Waiting for %v", p.Queues) timeout := time.After(interval) select { case <-quit: return case <-timeout: } } } } } } }() return jobs }