func (channel *Channel) basicConsume(method *amqp.BasicConsume) *amqp.AMQPError {
	var classId, methodId = method.MethodIdentifier()
	// Check queue
	if len(method.Queue) == 0 {
		if len(channel.lastQueueName) == 0 {
			return amqp.NewSoftError(404, "Queue not found", classId, methodId)
		} else {
			method.Queue = channel.lastQueueName
		}
	}
	// TODO: do not directly access channel.conn.server.queues
	var queue, found = channel.conn.server.queues[method.Queue]
	if !found {
		// Spec doesn't say, but seems like a 404?
		return amqp.NewSoftError(404, "Queue not found", classId, methodId)
	}
	if len(method.ConsumerTag) == 0 {
		method.ConsumerTag = util.RandomId()
	}
	amqpErr := channel.addConsumer(queue, method)
	if amqpErr != nil {
		return amqpErr
	}
	if !method.NoWait {
		channel.SendMethod(&amqp.BasicConsumeOk{method.ConsumerTag})
	}

	return nil
}
Exemple #2
0
func (channel *Channel) addConsumer(q *queue.Queue, method *amqp.BasicConsume) *amqp.AMQPError {
	var classId, methodId = method.MethodIdentifier()
	// Create consumer
	var consumer = consumer.NewConsumer(
		channel.server.msgStore,
		method.Arguments,
		channel,
		method.ConsumerTag,
		method.Exclusive,
		method.NoAck,
		method.NoLocal,
		q,
		q.Name,
		channel.defaultPrefetchSize,
		channel.defaultPrefetchCount,
		channel.conn.id,
	)

	channel.consumerLock.Lock()
	defer channel.consumerLock.Unlock()
	// Make sure the doesn't exist on this channel
	_, found := channel.consumers[consumer.ConsumerTag]
	if found {
		return amqp.NewHardError(
			530,
			fmt.Sprintf("Consumer tag already exists: %s", consumer.ConsumerTag),
			classId,
			methodId,
		)
	}

	// Add the consumer to the queue, then channel
	code, err := q.AddConsumer(consumer, method.Exclusive)
	if err != nil {
		return amqp.NewSoftError(code, err.Error(), classId, methodId)
	}

	channel.consumers[consumer.ConsumerTag] = consumer
	consumer.Start()
	return nil
}