AirHelp / rabbit-amazon-forwarder

RabbitMQ forwader to Amazon services

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

INFO: What is the rationale behind setupExchangesAndQueues

zabullet opened this issue · comments

setupExchangesAndQueues makes a lot of assumptions about the setup of the queues and naming conventions.

For instance that a queue has a a dead-letter exchange or queue and that it is exactly named -dead-letter.

	// regular queue
	if _, err = ch.QueueDeclare(c.QueueName, true, false, false, false,
		amqp.Table{
			"x-dead-letter-exchange": deadLetterExchangeName,
		}); err != nil {
		return failOnError(err, "Failed to declare a queue:"+c.QueueName)
	}

Assuming an existing queue with a dead letter exchange other than -dead-letter (for instance mine is already called -dlx)...the above will fail.

I might be missing something, but couldn't this rather be done via config?

zb.

@zabullet yes, you are right, we made some assumptions for two reasons (at least):

  1. We needed conventions as we have build huge part of the company on eventbus pattern with multiple languages and technologies and managing different naming conventions would be harder to maintain.
  2. We initially had made this project internally and when we had found out that it can bring some value to the community, we open sourced it. So any PRs making it more generic and more configurable are more than welcome :)

@filiphaftek

I'm making an attempt to make it more configurable in terms of topology, but I have a question.

The explicit mapping of config.RabbitEntry to rabbitmq.Consumer seems unnecessary given the benefit you gain (slightly looser coupling, perhaps?).

My proposal is to extend RabbitEntry to the following


// RabbitArgumentsPair describes a rabbitMQ bind or declare argument
type RabbitArgumentsPair struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

// RabbitTopographyItem describes an element of the rabbit topography to set up
type RabbitTopographyItem struct {
	Name      string                 `json:"name"`
	Action    string                 `json:"action"`
	Type      string                 `json:"type"`
	Kind      string                 `json:"kind"`
	Routekey  string                 `json:"routekey"`
	To        string                 `json:"to"`
	Arguments *[]RabbitArgumentsPair `json:"args"`
}

// RabbitEntry RabbitMQ mapping entry
type RabbitEntry struct {
	Type             string                  `json:"type"`
	Name             string                  `json:"name"`
	ConnectionURL    string                  `json:"connection"`
	ExchangeName     string                  `json:"topic"`
	QueueName        string                  `json:"queue"`
	RoutingKey       string                  `json:"routing"`
	RabbitTopography *[]RabbitTopographyItem `json:"rabbittopography"`
}

This is starting to be quite a complex structure which I don't see the benifit of duplicating in the RabbitMQ namespace.

How averse would you be if we did something like this?

// Consumer implementation or RabbitMQ consumer
type Consumer struct {
	config config.RabbitEntry
}

// parameters for starting consumer
type workerParams struct {
	forwarder forwarder.Client
	msgs      <-chan amqp.Delivery
	check     chan bool
	stop      chan bool
	conn      *amqp.Connection
	ch        *amqp.Channel
}

// CreateConsumer creates consumer from string map
func CreateConsumer(entry config.RabbitEntry) consumer.Client {
	return Consumer{entry}
}

// Name consumer name
func (c Consumer) Name() string {
	return c.config.Name
}

It doesn't appear to be a 1-way door or am I missing something?

Additionally, what about defining the config and mapping more generally and having the concrete types handle the unmarshalling?

// Entry Generic config structure
type Entry struct {
	Type   string          `json:"type"`
	Name   string          `json:"name"`
	Config json.RawMessage `json:"config"`
}

with pair defined as

type pair struct {
	Source      config.Entry `json:"source"`
	Destination config.Entry `json:"destination"`
}

I'll play around a bit here and do a spike for you to comment on

I'm going to close this. I've added a development branch on my fork.