// GetTaskResult listens to celery and returns the task result for given task func (manager *workerManager) GetTaskResult(task *Task) chan *TaskResult { ch := manager.broker.GetTaskResult(task.ID) tc := make(chan *TaskResult) go func() { // listen to queue message := <-ch serializer, _ := serializer.NewSerializer(message.ContentType) // convert message body to task var taskResult TaskResult if message.Body != nil { serializer.Deserialize(message.Body, &taskResult) } else { log.Errorf("Task result message is nil") } tc <- &taskResult }() return tc }
// Start worker runs the worker command func (manager *workerManager) Start(queues []string) { sigs := make(chan os.Signal, 1) done := make(chan bool, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { <-sigs // listen to signals manager.Stop() manager.Close() log.Info("gocelery stopped.") done <- true // send signals to done }() log.Debug("Worker is now running") // now loops to wait for messages manager.sendWorkerEvent(WorkerOnline) // start hearbeat manager.startHeartbeat() // start getting tasks taskChannels := make([]<-chan *broker.Message, 3) for _, queue := range queues { taskChannel := manager.broker.GetTasks(queue) taskChannels = append(taskChannels, taskChannel) } ch := merge(done, taskChannels...) for { select { case <-done: log.Debug("Received done signal") return case message := <-ch: log.Debug("Message type: ", message.ContentType, " body:", string(message.Body)) go func(message *broker.Message) { serializer, err := serializer.NewSerializer(message.ContentType) // convert message body to task if err == nil { var task Task err = serializer.Deserialize(message.Body, &task) if err == nil { task.ContentType = message.ContentType // stores the content type for the task // publish task received event taskEventPayload, _ := serializer.Serialize(NewTaskReceivedEvent(&task)) manager.broker.PublishTaskEvent(strings.Replace(TaskReceived.RoutingKey(), "-", ".", -1), &broker.Message{ Timestamp: time.Now(), ContentType: message.ContentType, Body: taskEventPayload, }) log.Debug("Processing task: ", task.Task, " ID:", task.ID) // check eta duration := time.Duration(0) if !task.Eta.IsZero() { duration = task.Eta.Sub(time.Now().UTC()) } if duration > 0 { timer := time.NewTimer(duration) // wait until ready go func() { <-timer.C manager.runTask(&task) }() } else { // execute the task in a worker immediately manager.runTask(&task) } } } else { // send errors to server log.Error("Cannot deserialize message:", err) } }(message) } } }