majek / puka

Puka - the opinionated RabbitMQ client
https://github.com/majek/puka
Other
182 stars 34 forks source link

Allow caller to specify consumer_tag #38

Closed Br3nda closed 11 years ago

Br3nda commented 11 years ago

This change allows the caller of the library to specify the "consumer_tag" on consume set-up, which then results in that same consumer tag being appear attached to messages received.

Needed if you're listening to > 1 routing key and you need to know which key caused you to receive a message.

majek commented 11 years ago

Do you think we could spare our users trouble and just manually assign consumer_tags? Maybe just setting it to an offset from the table passed to basic_consume_multi would be enough?

Ie make this behaviour a default:

        consume_promise = client.basic_consume_multi([
                {'queue': self.name1, 'consumer_tag': '0'},
                {'queue': self.name2, 'consumer_tag': '1'},
                ])
majek commented 11 years ago

Needed if you're listening to > 1 routing key and you need to know which key caused you to receive a message.

Well, every message received from rabbit already has routing_key set :) But yes, consumer_tag may be used to see to which queue message was delivered when consuming using consume_multi.

majek commented 11 years ago

@Br3nda is my amendment acceptable?

Br3nda commented 11 years ago

Could we only set it if it's not supplied? I need to map these in my app. Setting the consumer tag myself means I know what the tag will be long before I start consuming, setting my data structures before message arrive.

Messages have routing keys, but they're received because they match wildcards. The consumer tag lets me map to which wildcard it matched. On Feb 2, 2013 12:23 AM, "Marek Majkowski" notifications@github.com wrote:

@Br3nda https://github.com/Br3nda is my amendment acceptable?

— Reply to this email directly or view it on GitHubhttps://github.com/majek/puka/pull/38#issuecomment-12990344.

majek commented 11 years ago

I don't like to give users too many options unless necessary. If a user can screw up an API call, he will. In this case it's extremely likely to forget about rmq limitations and reuse consumer tags. This won't work.

We could do a compromise - attach user's consumer tag after the promise.consumer_no tuple, and format it like promise.consumer_no.users_tag but I see little practical value of this.

What do you think?

reedwade commented 11 years ago

Hi, (I work w/Br3nda)

Our essential requirement is to easily map a received message to the subcomponent in our app which asked for it. These subcomponents are pretty fluid and we don't know anything about them at start up time other than what routing keys they like. As B noted, reversing the routing key matches would be a pain.

We've been doing this with Pika by setting the consumer tag to some value we map back to the correct subcomponent when we get a message.

I'm unclear if the compromise you suggest allows that -- the foreknowledge of what the consumer tag will be when we're configuring each subcomponent.

If not, how about taking a given consumer tag value then adding a separator and serial number (to insure uniqueness)? On the receiving end we can remove the serial number and recover our original value. It feels a little hacky but seems like it would give best of both.

majek commented 11 years ago

Good work, I'm convinced! Please see the patch and tell me if it's okay for you.

reedwade commented 11 years ago

(duplicating my comment so it's here also)

sweet!

Br3nda is away at a conference today. She may spot something we've forgotten.