On Thu, Oct 29, 2015 at 11:51 AM, Anders Rye <
ander...@gmail.com> wrote:
>
> I have a listener processing messages from a service, and I was trying to
> run request against another service within that message handler. The
> responder never seems to get the request, and the thread hangs waiting for
> the response.
>
> This example hangs for me:
>
> (let [q1 (queue "Queue1")
> q2 (queue "Queue2")]
> (respond q2 inc)
> (listen q1 #(do (println "q1 got" %) (println "q2 returned" @(request q2
> %))))
> (publish q1 1))
> q1 got 1
> => nil
>
There are two things happening here that, together, cause this to hang:
1) By default, there is a local JMS transaction around the listener's
function - this allows us to roll back the receipt of the message
and any publishes that use the context that is active during the
call.
2) Any publish within the listener's function will use that active
context (primarily for transactionality), and the publish won't
succeed until the context is committed, once the listener function
returns. `request` uses `publish`, so the deref hangs, because the
request message won't be published until the context is committed,
which won't happen until the listener's function returns.
If you need to escape the implicit transaction inside the listener,
you can set the `:mode` of the listener to something other than
`:transacted`:
(listen q1
#(do (println "q1 got" %)
(println "q2 returned" @(request q2 %)))
:mode :auto-ack)
>
> Second: passing a local context to request
>
> (with-open [c (context)]
> (let [q (queue "TestQueue")]
> (respond q inc)
> @(request q 1 :context c)))
>
> Throws IllegalArgumentException Listening only accepts a remote context.
> org.projectodd.wunderboss.messaging.jms.JMSDestination.listen
> (JMSDestination.java:62)
This happens because if there is a context provided to `request`, that
context is reused to create a listener to get the respose to the
request. I'm pretty sure this is a bug - we should only be reusing
that context if it is a *remote* context, which I believe was the
intent for adding this behaviour.
I've filed two issues in JIRA for this [1] to improve the
documentation around listen to clarify the use of a local transaction,
and [2] to only reuse the context in `request` if it's remote,
assuming that we don't have another reason for reusing the context.
[1]:
https://issues.jboss.org/browse/IMMUTANT-588
[2]:
https://issues.jboss.org/browse/IMMUTANT-589
- Toby