SpinGo / op-rabbit

The Opinionated RabbitMQ Library for Scala and Akka
Other
232 stars 73 forks source link

How do I declare queues? #40

Closed gzoller closed 9 years ago

gzoller commented 9 years ago

In the Java API I can call myChannel.queueDeclare(qName,...) to be sure a queue exists before trying to use it. I typically have a short bit of code at the beginning of my program that rolls through and does this for all the queues I'm going to need.

What's the equivalent in this world? I've tried something like this but it doesn't build:

    Subscription.run(rabbitControl) {
        channel() { 
            queue("testQ")  // Declare the queue
        }
    }

(Note this isn't my actual "using" of the queue in a stream--for which I plan to use Akka Streams. This is just pre-work to declare the queues.)

I tried to call queue("testQ").declare(???), but declare needs a Channel, so how do I get that? Honestly for this pre-work it doesn't even have to be a fancy Directive-based thing. If there's not already a way to do this, perhaps rabbitControl could receive a QueueDeclare message that tweaks the right things internally?

Ideas appreciated...

gzoller commented 9 years ago

Ok, so playing with this some more...

Attempt #1) Assume queues are auto-declared internally (some code seems to imply maybe)

AckedSource(List("message 1","message 2"))
            .map(Message.queue(_,"testQ"))
            .to(MessagePublisherSink(rabbitControl))
            .run

This did... nothing. No error messages given. testQ not auto-created, so no content in RabbitMQ.

Attempt #2) Manually create testQ in Rabbit web Admin first, then run code in #1 above.

This did... nothing, which I found surprising. I thought that would work.

Attempt #3) Manually create testQ as before but this time run:

rabbitControl ! Message.queue("Testing 1,2,3", queue = "testQ")

This added 1 message to testQ!

So I guess I still need to know how to declare queues in this framework, as well as why #2 didn't work, as this is pretty much lifted from the docs. My successful test #3 proves I'm connected to RabbitMQ and able to communicate with it.

timcharper commented 9 years ago

Queues are declared by the consumers.

There's a mechanism to have message publishers declare queues / exchanges. I'll respond more in a bit.

Sent from my iPhone

On Oct 16, 2015, at 16:28, Greg Zoller notifications@github.com wrote:

Ok, so playing with this some more...

Attempt #1) Assume queues are auto-declared internally (some code seems to imply maybe)

AckedSource(List("message 1","message 2")) .map(Message.queue(_,"testQ")) .to(MessagePublisherSink(rabbitControl)) .run This did... nothing. No error messages given. testQ not auto-created, so no content in RabbitMQ.

Attempt #2) Manually create testQ in Rabbit web Admin first, then run code in #1 above.

This did... nothing, which I found surprising. I thought that would work.

Attempt #3) Manually create testQ as before but this time run:

rabbitControl ! Message.queue("Testing 1,2,3", queue = "testQ") This added 1 message to testQ!

So I guess I still need to know how to declare queues in this framework, as well as why #2 didn't work, as this is pretty much lifted from the docs. My successful test #3 proves I'm connected to RabbitMQ and able to communicate with it.

— Reply to this email directly or view it on GitHub.

gzoller commented 9 years ago

There's much I don't understand. I did kludge together a way to declare queues. Not sure if its the right thing...seems pretty involved, but it did appear to work:

    val connectionActor = await((rabbitControl ? RabbitControl.GetConnectionActor).mapTo[ActorRef])
    val channelCreated = await((connectionActor ? CreateChannel(ChannelActor.props(), None)).mapTo[ChannelCreated])
    channelCreated.channel ! ChannelMessage { _.queueDeclare("testQ",true,false,false,null) }
    system.stop(channelCreated.channel)
timcharper commented 9 years ago

Is there a reason you can't just have your consumers idempotently declare the queues / bindings?

gzoller commented 9 years ago

My consumers and producers are different processes and both will likely use the same libraries.

So basically my consumers may come online first in a system of many moving pieces.

Sent from my iPhone

On Oct 18, 2015, at 10:18 PM, Tim Harper notifications@github.com wrote:

Is there a reason you can't just have your consumers idempotently declare the queues / bindings? — Reply to this email directly or view it on GitHub.

timcharper commented 9 years ago

OK, then it is completely possible to have your producers declare the Queue/binding if they don't already exist on first message sent.

Just have your publisher use the same object as the consumer binds to. Be sure to reuse the publisher. Otherwise it will re-declare on every message send.

Sent from my iPhone

On Oct 19, 2015, at 13:13, Greg Zoller notifications@github.com wrote:

My consumers and producers are different processes and both will likely use the same libraries.

So basically my consumers may come online first in a system of many moving pieces.

Sent from my iPhone

On Oct 18, 2015, at 10:18 PM, Tim Harper notifications@github.com wrote:

Is there a reason you can't just have your consumers idempotently declare the queues / bindings? — Reply to this email directly or view it on GitHub.

— Reply to this email directly or view it on GitHub.