Using from a Web App?

9 views
Skip to first unread message

topfunky

unread,
Oct 11, 2008, 11:07:39 PM10/11/08
to AMQP
I love the syntax of the AMQP library but am having a hard time
understanding how to use it from a web app (Merb, at the moment). I
think I'm missing something about how EventMachine works.

I have a basic subscriber running. I try to run this from IRB:

require 'mq'
EM.run { MQ.new.topic('hello topic').publish("Hello world", :key =>
'hello key') }

Either

a) The message is received by the listener but IRB never returns
b) or, I call EM.stop_event_loop and IRB exits.

Or, I can do EM.fork(1), but that leaves an EventMachine running until
I exit.

What's the proper way to queue an event from a webapp? Do I need to
use the lower level API?

(I'm using the latest AMQP gem from GitHub and RabbitMQ from the
Mercurial repo).

Thanks,
Geoffrey Grosenbach

Aman Gupta

unread,
Oct 12, 2008, 1:48:36 AM10/12/08
to ruby...@googlegroups.com
> I love the syntax of the AMQP library but am having a hard time
> understanding how to use it from a web app (Merb, at the moment). I
> think I'm missing something about how EventMachine works.
>
> I have a basic subscriber running. I try to run this from IRB:
>
> require 'mq'
> EM.run { MQ.new.topic('hello topic').publish("Hello world", :key =>
> 'hello key') }

To test publishing, I would use something like:

ruby -rubygems -e '
require "mq"
AMQP.run do
# publish mesage


MQ.new.topic('hello topic').publish("Hello world", :key =>
> 'hello key')

# shut down gracefully to ensure message is published
AMQP.stop do
EM.stop
end
end
'

>
> Either
>
> a) The message is received by the listener but IRB never returns
> b) or, I call EM.stop_event_loop and IRB exits.

Unfortunately EM and irb don't play well together.

When you call EM.run, eventmachine takes over the ruby process and
calls ruby functions whenever events in the reactor fire. Any code
after the EM.run is not executed until the reactor is stopped.

> Or, I can do EM.fork(1), but that leaves an EventMachine running until
> I exit.

EM.fork_reactor is useful for pre-spawning a pool of workers that
subscribe to a queue (Queue#subscribe). It should be used sparingly,
and is not usually required when publishing messages
(Exchange#publish).

>
> What's the proper way to queue an event from a webapp? Do I need to
> use the lower level API?

The easiest way is to use a webserver that runs EM, such as Thin. If
you run your rails or merb process using Thin, you can simply use the
MQ api to publish from your controllers:

MQ.queue('world').publish('hello')
MQ.direct('pubsub').publish('message', :key => 'subscription topic')

>
> (I'm using the latest AMQP gem from GitHub and RabbitMQ from the
> Mercurial repo).

The github gem is usually out of date, so its better to build your own
gem. master has a few recent bug fixes and should be stable. I'm
finalizing a patch for get/ack support and plan on releasing 0.6 to
rubyforge soon.

Aman

>
> Thanks,
> Geoffrey Grosenbach
>
>
> >
>

topfunky

unread,
Oct 12, 2008, 1:49:12 PM10/12/08
to AMQP
On Oct 11, 10:48 pm, "Aman Gupta" <themastermi...@gmail.com> wrote:
> The easiest way is to use a webserver that runs EM, such as Thin. If
> you run your rails or merb process using Thin, you can simply use the
> MQ api to publish from your controllers:

Thanks for that and for the chat on IRC. I'll use thin for my webapp.

Geoffrey Grosenbach
http://peepcode.com

m94asr

unread,
Oct 13, 2008, 8:19:19 AM10/13/08
to AMQP
I got a simple rack app.

Publish works as described above:
AMQP.run do
MQ.queue('queue1').publish('hello')
end

What is the preferred way to check if there is a message in a queue1?
I do not want to wait till there is a message.

Thanks,
-Armin


Armin Roehrl

unread,
Oct 13, 2008, 9:55:28 AM10/13/08
to AMQP
ok, a trivial subscribe worked (if not inside the def initialize of the rack app).

Ben Hood

unread,
Oct 13, 2008, 10:18:15 AM10/13/08
to ruby...@googlegroups.com
Armin,

On Mon, Oct 13, 2008 at 1:19 PM, m94asr <m94...@gmail.com> wrote:
> What is the preferred way to check if there is a message in a queue1?
> I do not want to wait till there is a message.

Apart from the Queue.Declare command I mentioned in a previous post,
you can also poll a queue using the Basic.Get command. If you then
turn auto ack off, you can effectively turn the get into a peek by
just not sending the ack, which will cause the broker to requeue the
message when you close the channel, or if you send a Basic.Recover.

HTH,

Ben

Reply all
Reply to author
Forward
0 new messages