Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify intended uses for AsyncRabbitTemplate. #574

Closed
dave-r12 opened this issue Mar 3, 2017 · 9 comments
Closed

Clarify intended uses for AsyncRabbitTemplate. #574

dave-r12 opened this issue Mar 3, 2017 · 9 comments

Comments

@dave-r12
Copy link

dave-r12 commented Mar 3, 2017

I'm trying to better understand the cases for using the AsyncRabbitTemplate. The docs mention that the sendAndRecieve will not block. After reviewing the details of the implementation, it seems the send call does block, but the receive will not block. Does that sound right?

My initial interpretation was that both send and receive would be async. Would you have any recommendation on doing that? Maybe using @Async?

@garyrussell
Copy link
Contributor

What makes you think the send will block? RabbitMQ is async - although I guess it will block if the broker can't keep up and applies flow control to the connection.

It was not the intent of this template to "ignore" conditions when the broker is in a sad state, just to avoid blocking your thread while waiting for a reply.

@artembilan
Copy link
Member

To confirm @garyrussell 's comment:

 /**
     * Publish a message.
     *
     * Invocations of <code>Channel#basicPublish</code> will eventually block if a
     * <a href="http://www.rabbitmq.com/alarms.html">resource-driven alarm</a> is in effect.
     *
     ....
     */
    void basicPublish(String exchange, String routingKey, boolean mandatory, BasicProperties props, byte[] body)

@dave-r12
Copy link
Author

dave-r12 commented Mar 3, 2017

@garyrussell @artembilan thanks for the quick response. Sorry, by blocking I meant writing to the socket's OutputStream. I'm in a situation where I'd like to send but not block (not do I/O) on the thread sending the message. Do you think that would be a good case for using @Async?

@artembilan
Copy link
Member

artembilan commented Mar 3, 2017

Well, Spring AMQP since version 1.7 supports the latest RabbitMQ client with a NIO option: https://www.rabbitmq.com/blog/2016/11/24/rabbitmq-java-client-4-0-is-released/

Since it isn't there by default you should configure your RabbitConnectionFactoryBean for the setUseNio(true).
No reason to overhead with the @Async - the Framework will do the stuff for you!

@dave-r12
Copy link
Author

dave-r12 commented Mar 3, 2017

Interesting ok. Maybe if I could be more specific, if I want to send a message during a web request, but I'd rather not block the request, is that the route you'd take (NIO)? I feel like what I need is a way to 'queue' the message, with a separate thread pulling off the queue and sending it. Does that sound like a weird approach? An added constraint is that the message must be guaranteed delivered (thinking publisher confirms.)

@artembilan
Copy link
Member

It will be queued in the NIO loop anyway, but doing that manually you are losing context of the RabbitTemplate. It would be much complicated for your to get a reply from there.

We are just sharing with you an info how it works.
Everything rest is your decision.

In the future consider to ask similar question on StackOverflow.
GH (and JIRA) is for bugs and fuature requests.

@dave-r12
Copy link
Author

dave-r12 commented Mar 3, 2017

Yeah, apologies I got off track, thanks for the response.

@dave-r12 dave-r12 closed this as completed Mar 3, 2017
@garyrussell
Copy link
Contributor

I feel like what I need is a way to 'queue' the message, with a separate thread pulling off the queue and sending it.

An added constraint is that the message must be guaranteed delivered (thinking publisher confirms.

Those two requirements are competing. If you hand off to a volatile queue, you can be sure you will lose messages in the event of a server failure.

Generally, unless you have a congested network/broker, the send won't block; I fear you are worrying about a situation that is unlikely to occur and, if it does, you have bigger problems than a slow HTTP response.

@dave-r12
Copy link
Author

dave-r12 commented Mar 4, 2017

Those two requirements are competing. If you hand off to a volatile queue, you can be sure you will lose messages in the event of a server failure.

Yeah, good point.

Generally, unless you have a congested network/broker, the send won't block;

Hmm, I don't completely agree. At the end of the day we're talking about writing to a socket. I'd love to assume networking issues won't happen. I'd prefer not to ignore those cases though.

Bringing it back to the original issue, when I saw Async I immediately thought 'run this in the background.' But as you mentioned, this was not the intent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants