// StartConsuming enters a loop and waits for incoming messages func (amqpBroker *AMQPBroker) StartConsuming(consumerTag string, taskProcessor TaskProcessor) (bool, error) { if amqpBroker.retryFunc == nil { amqpBroker.retryFunc = utils.RetryClosure() } _, channel, queue, _, err := amqpBroker.open() defer channel.Close() if err != nil { amqpBroker.retryFunc() return amqpBroker.retry, err // retry true } amqpBroker.retryFunc = utils.RetryClosure() amqpBroker.stopChan = make(chan int) if err := channel.Qos( 3, // prefetch count 0, // prefetch size false, // global ); err != nil { return amqpBroker.retry, fmt.Errorf("Channel Qos: %s", err) } deliveries, err := channel.Consume( queue.Name, // queue consumerTag, // consumer tag false, // auto-ack false, // exclusive false, // no-local false, // no-wait nil, // arguments ) if err != nil { return amqpBroker.retry, fmt.Errorf("Queue Consume: %s", err) } log.Print("[*] Waiting for messages. To exit press CTRL+C") if err := amqpBroker.consume(deliveries, taskProcessor); err != nil { return amqpBroker.retry, err // retry true } return amqpBroker.retry, nil }
// StartConsuming enters a loop and waits for incoming messages func (redisBroker *RedisBroker) StartConsuming(consumerTag string, taskProcessor TaskProcessor) (bool, error) { if redisBroker.retryFunc == nil { redisBroker.retryFunc = utils.RetryClosure() } redisBroker.pool = redisBroker.newPool() defer redisBroker.pool.Close() _, err := redisBroker.pool.Get().Do("PING") if err != nil { redisBroker.retryFunc() return redisBroker.retry, err // retry true } redisBroker.retryFunc = utils.RetryClosure() redisBroker.stopChan = make(chan int) redisBroker.stopReceivingChan = make(chan int) redisBroker.errorsChan = make(chan error) deliveries := make(chan []byte) redisBroker.wg.Add(1) go func() { defer redisBroker.wg.Done() log.Print("[*] Waiting for messages. To exit press CTRL+C") consumerSleep := time.Duration(1000 * time.Millisecond) if redisBroker.config.RedisConsumerSleep != 0 { consumerSleep = time.Duration(time.Duration(redisBroker.config.RedisConsumerSleep) * time.Millisecond) } conn := redisBroker.pool.Get() for { select { // A way to stop this goroutine from redisBroker.StopConsuming case <-redisBroker.stopReceivingChan: return default: itemBytes, err := conn.Do("LPOP", redisBroker.config.DefaultQueue) if err != nil { redisBroker.errorsChan <- err return } // Unline BLPOP, LPOP is non blocking so nil means we can keep iterating if itemBytes == nil { time.Sleep(consumerSleep) continue } item, err := redis.Bytes(itemBytes, nil) if err != nil { redisBroker.errorsChan <- err return } signature := signatures.TaskSignature{} if err := json.Unmarshal(item, &signature); err != nil { redisBroker.errorsChan <- err return } // If the task is not registered, we requeue it, // there might be different workers for processing specific tasks if !redisBroker.IsTaskRegistered(signature.Name) { _, err := conn.Do("RPUSH", redisBroker.config.DefaultQueue, item) if err != nil { redisBroker.errorsChan <- err return } continue } deliveries <- item } } }() if err := redisBroker.consume(deliveries, taskProcessor); err != nil { return redisBroker.retry, err // retry true } return redisBroker.retry, nil }