Seeking simple example(s) for RuoteAMQP::Listener

5 views
Skip to first unread message

Charles.Magid

unread,
Sep 30, 2009, 4:19:48 PM9/30/09
to ruote
Good Day

Could you please validate my understanding of ruote-amqp, and possible
provide another example or two. Thank you very much in advance.

In general there are three ways to get information from an AMQP queue.

1) Blocking

Wait for information until it is available. IE the instruction
pointer does not advance

2) Non Blocking

See if there is a message on the queue but keep executing.

3) Asynchronous call back. There is a jump to a completely different
method which will be handed the message from the queue when any
message is available.

I was looking at the ruote-amqp/spec/listener_spec.rb rspec file as a
model for my code.

The example seems to use two of the above mechanisms but I would like
some clarification of the asynchronous call back method.

My understanding of how to deque from amqp using the ruote-amqp gem.

1) "loop do ... break unless @msg.nil? ... sleep 0.1 ... end" is
added to do blocking in conjunction with the Non blocking statement in
2).

2) "MQ.queue('test3').subscribe { |msg| @msg = ... }" keeps taking
messages off of test3 que until there are no messages there to be
taken off.

3) It seems that "@engine.register_listener( RuoteAMQP::Listener )" is
registering an asynchronous call back. Though I am not sure how this
works.

The register_participant example in RuoteAMQP::Participant was very
funny. I would like to see a simple example, using ruote 2.0, to
illustrate the use of asynchronous listeners.


Thank you very much in advance,

Charles M

John Mettraux

unread,
Sep 30, 2009, 8:57:35 PM9/30/09
to openwfe...@googlegroups.com
On Thu, Oct 1, 2009 at 5:19 AM, Charles.Magid <cmm...@gmail.com> wrote:
>
> The register_participant example in RuoteAMQP::Participant was very
> funny.  I would like to see a simple example, using ruote 2.0, to
> illustrate the use of asynchronous listeners.

Hello Charles,

Sorry, I won't reply directly to your question. I will just try to
provide a context, it could be useful since you're calling for an
example.


scenario 1) 'notification' (participant only)

- process instance reaches participant expression
- participant expression calls consume() of AmqpParticipant instance
- workitem is placed on queue
- on the other side, workitem is fetched by the "real participant"
- on the ruote side, the AmqpParticipant immediately replies to the
participant expression, the flow resumes immediately
- real participant does something with the workitem (especially with
its payload)

scenario 2) 'forth and back' (participant and listener)

- process instance reaches participant expression
- participant expression calls consume() of AmqpParticipant instance
- workitem is placed on queue
- on the other side, workitem is fetched by the "real participant"
- on the ruote side, the participant expression is waiting (is waiting
for its reply() method to get called)
- real participant does something with the workitem (especially with
its payload)
- after a while the real participant places a reply (the modified
workitem) on the queue dedicated for the AmqpListener
- the AmqpListener in the ruote engine fetches the workitem on its
queue, locates the expression waiting for it (thanks to the @fei
workitem instance variable) and calls the reply() method of that
expression with the workitem as parameter
- that participant expression replies to its parent expression, flow resumes

scenario 3) 'launch that' (listener only)

- AmqpListener receives item on the queue it listens to, it's a
launchitem, not a workitem
- AmqpListener calls engine.launch to start new process instance with
the info held in launchitem


I hope this will help, best regards,

--
John Mettraux - http://jmettraux.wordpress.com

Charles.Magid

unread,
Sep 30, 2009, 10:53:47 PM9/30/09
to ruote
Hi John,

Thank you very much.

Now that you have a more concrete example of what I am trying to do I
hope we can continue with the listener case from our irc?

Charles

On Sep 30, 8:57 pm, John Mettraux <jmettr...@openwfe.org> wrote:

John Mettraux

unread,
Oct 1, 2009, 12:23:03 AM10/1/09
to openwfe...@googlegroups.com
On Thu, Oct 1, 2009 at 11:53 AM, Charles.Magid <cmm...@gmail.com> wrote:
>
> Hi John,
>
> Thank you very much.
>
> Now that you have a more concrete example of what I am trying to do I
> hope we can continue with the listener case from our irc?

OK, so let's paste the conversation :

---8<---
11:25 charles_: John, thank you very much for your response to my last
post. I think I need to be a little more concrete. With that in mind
I put up two new pasties which do not work but I am trying to get to
work with 10k not just 10 listeners. I hope that is possible. ;)
http://pastie.org/637565 receive, http://pastie.org/637548 send
11:25 jmettraux: 10 thousand listeners ?
11:25 charles_: more if possible
11:26 jmettraux: why such a big number ?
11:26 charles_: I can not answer that
11:26 charles_: I want to but I can not
11:26 charles_: ;(
11:26 jmettraux: well if 1 ruby process can handle 10k amqp listeners
11:27 jmettraux: then 1 ruote engine can do it
11:27 jmettraux: you should probably package this new version of your
question in a continuation of the mailing list thread
11:27 jmettraux: so that Kenneth and others can pick it up
11:28 jmettraux: http://pastie.org/637548 : the sendme participant is
a block participant
11:29 jmettraux: it means that it executes its block and then
immediately reply to the engine
11:29 jmettraux: so the process terminates immediately
11:29 jmettraux: in the block of sendme
11:29 jmettraux: what you have looks like ruby code
11:30 jmettraux: but it seems you're thinking you can call another
participant "amqp" like this, out of thin air
11:30 jmettraux: ruote process definitions in ruby are turned into
Abstract Syntax Tree at execution
11:30 jmettraux: they are not real ruby code
11:31 jmettraux: you cannot mix that like that
11:31 jmettraux: let me rewrite that pastie
11:31 charles_: that would be great
11:32 charles_: it is ok if the sends are sequential
11:32 jmettraux: yes
11:34 jmettraux: http://gist.github.com/198667
11:35 jmettraux: I have to go now, lunch time
11:35 jmettraux: if you continue the thread with the listener pastie,
I'll reply there
11:35 jmettraux: ttyl !
11:37 charles_: thank you, ttyl?
11:37 jmettraux: talk to you later ;)
11:37 charles_: nice,
11:40 charles_: I am heading to bed, my forum post yesterday was
really about the listener gist http://pastie.org/637565, I did not
get what you were asking?
11:41 charles_: about the thread with the listener pastie 22:35
12:52 jmettraux: back
12:58 jmettraux: 22:35 in which timezone ?
--->8---

So, http://pastie.org/637548 is wrong, it will end up with an error
like "NameError: undefined local variable or method `amqp'" for each
of the "sendme" participants.

The right way would be something like http://gist.github.com/198667

Pastie http://pastie.org/637565 is exotic as well. The _break outside
of the loop is meaningless. The loop itself is a Ruby loop not a ruote
one (use the 'repeat' expression instead
(http://ruote.rubyforge.org/exp/cursor.html)). "remaining" is
interpreted as the Ruby method call... Copy and paste programming is
not a way to go.

http://pastie.org/637565 --> http://gist.github.com/198728

Best regards,

Charles.Magid

unread,
Oct 1, 2009, 1:42:25 PM10/1/09
to ruote
Hi

thank you again for http://gist.github.com/198728. But it is an
example off a push onto queue and wait for a response on a queue. I
was hoping for a wait on response without a push first. Is that
possible?

Regards,

Charles

On Oct 1, 12:23 am, John Mettraux <jmettr...@openwfe.org> wrote:
> really about the listener gisthttp://pastie.org/637565,  I did not
> get what you were asking?
> 11:41 charles_: about the thread with the listener pastie 22:35
> 12:52 jmettraux: back
> 12:58 jmettraux: 22:35 in which timezone ?
> --->8---
>
> So,http://pastie.org/637548is wrong, it will end up with an error
> like "NameError: undefined local variable or method `amqp'" for each
> of the "sendme" participants.
>
> The right way would be something likehttp://gist.github.com/198667
>
> Pastiehttp://pastie.org/637565is exotic as well. The _break outside
> of the loop is meaningless. The loop itself is a Ruby loop not a ruote
> one (use the 'repeat' expression instead
> (http://ruote.rubyforge.org/exp/cursor.html)). "remaining" is
> interpreted as the Ruby method call... Copy and paste programming is
> not a way to go.
>
> http://pastie.org/637565-->http://gist.github.com/198728

John Mettraux

unread,
Oct 1, 2009, 8:35:48 PM10/1/09
to openwfe...@googlegroups.com
On Fri, Oct 2, 2009 at 2:42 AM, Charles.Magid <cmm...@gmail.com> wrote:
>
> thank you again for http://gist.github.com/198728.  But it is an
> example off a push onto queue and wait for a response on a queue.  I
> was hoping for a wait on response without a push first.  Is that
> possible?

Hello,

you could

a) set up a vanilla amqp listener and react to messages on its queue
(none of the scenarii)

Using a non- ruote-amqp listener to react upon messages, launching
ruote process instances.

b) use the AmqpListener of ruote-amqp and react on messages translated
into workitems (scenario 3) Unfortunately, ruote 2.0 (and ruote-aqmp)
seem not yet ready to received launchitems [over amqp], I will work
with Kenneth to fix that.

Advanced :

c) use the 'listen' expression [1] in conjunction with the AmqpListener

---8<---
sequence do
listen :to => "janet", :upon => :reply
participant :ref => 'after_janet_replied'
end
--->8---

The listen expression will block the process instance until a workitem
is received by any listener and is adressed/coming from the
participant named 'janet' (technically it's more like "the participant
whose name matches the regular expression /janet/). Note the :upon =>
:reply.

It seems a) and b) are not what you're looking for. I've traditionally
always discouraged the "fire a process that listens for an event"
approach in favour of the "listen for an event that fires a process"
approach, but maybe you've got your reasons and you understand what
you do.

[1] http://ruote.rubyforge.org/exp/listen.html


I hope this will help, best regards,

Reply all
Reply to author
Forward
0 new messages