In my Camel Route I need to send message to a JMS when an Exception hits my onException handlers. To speed up the main route, I try to send the messages asynchronously via a Wiretap
I try to use something like this:
onException().handled(true).logHandled(true)
.wiretap("seda:another_queue").end();
...
from("seda:another_queue?concurrentConsumers=5")
.to("jms:queue_for_my_exception_messages");
Is it necessary to use the Wiretap, or could I go with just the SEDA queues like this:
onException().handled(true).logHandled(true)
.to("seda:another_queue").end();
...
from("seda:another_queue?concurrentConsumers=5")
.to("jms:queue_for_my_exception_messages");
You do not need to use wiretap. Only seda-queues shall work.
Wiretap pattern should be used where you want to intercept messages between components for analysis or debugging purpose.
An important difference between Wiretap and SEDA is that when consuming from polling consumers (e.g. file or ftp) only wiretap is fire-and-forget.
When a thread consuming from a polling consumer reaches a .to(seda:xx) it will hand off the exchange and continue the route as expected or consume new exchanges from the endpoint. The exchange delivered to the seda endpoint will be commited to the originating Consumer by the seda thread and not the original consumer thread. That means that if you for instance have delete=true in your polling consumer endpoint definition, the file will not be deleted before the seda thread has finished.
Related
My understanding was that default behavior of ActiveMQ is to do async dispatch of messages to the consumers, but when I tried to test it by doing a Thread.sleep(60000); in my MessageListener#onMessage() then broker was not able to send queued messages until it received the acknowledgment from the dispatch of previous message.
So, then I tried to explicitly set the async flag, just in case, using ((ActiveMQConnectionFactory)connectionFactory).setDispatchAsync(true); as mentioned here but still same behavior.
Is there a way in which I can make sure that my ActiveMQ broker doesn't get blocked if one of the consumer is taking long time, please note that I know and read about "slow consumers" but this is not what I want, I want a truly async dispatch where-in where broker sends the message doesn't wait for any acknowledgement/response.
EDIT:
I just read about what-is-the-prefetch-limit-for and I am wondering that when broker is sending message synchronously to the consumer then what's the point of "prefetch limit"?
With the default configuration, ActiveMQ is configured to use a dispatch thread per Queue - you can use set the optimizedDispatch property on the destination policy entry - see configuring Queues.
set the optimizedDispatch="true" in activemq.xml
optimizedDispatch :
Default Value : false
Description : Don't use a separate thread for dispatching from a Queue.
Note that by doing a Thread.sleep(60000); in the MessageListener#onMessage() when using a single consumer the dispatcher of the consumer cannot send another messages.
UPDATE
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue=">" optimizedDispatch="true"/>
<policyEntries>
<policyMap>
<destinationPolicy>
queue=">" means all queues
EDIT by OP (hagrawal): To help future visitor to catch the concept quickly I am putting below the core concept in nut shell, please feel free to read all the comments below in order to know more. Many thanks to #HassenBennour for clarifying all this.
If there are 2 consumers connected and messages getting produced then
it will do robin round message dispatching to those consumer, but
suppose no consumer is connected, broker got 4 messages enqueued, a
consumer got connected with 3 as prefetch limit then it will deliver 3
messages to the consumer and then wait, meanwhile if some other
consumer gets connected then it will immediately deliver 4th message
to that otherwise it will wait for acknowledgment of 1st message
before delivering 4th message to same consumer.
I am working on prototyping a new web service for my company and we are considering Apache Camel as our integration framework. Here is a quick run-down of the high-level architecture:
-IBM Websphere MQ as the queuing solution
1) we receive http request
2) asynchronously persist this request
3a) do some processing on the request
3b) send to another tier for further processing
4) asynchronously update the request record in DB
5) respond to caller
What I want to do is:
When a http request comes in, put it on a queue to be processed and wait n seconds. If the web handler doesn't get a response in n seconds, reply to the caller with a custom message
Once the request is on the processing queue, a camel route is listening to this queue to process. When it pulls a message from queue, put a copy of the request on a different queue to be persisted asynchronously. Do some processing on the request. Then send it to another queue to be further processed and wait for a response. Then put it back on the persist queue to be asynchronously updated.
Then respond to web listener. Then web listener responds to web caller.
I am reading everything I can about Apache Camel and there is a lot of information about there. I might be on a little bit of information overload, and any help on the following concerns would be greatly appreciated:
1)
If the web listeners use an InOut exchange (with the first processing tier) without a replyTo queue defined, it will create a temporary queue for the response. What happens if this request times out? I understand I can set a requestTimeout on the exchange and, if it times out, catch that exception and set a custom message. But, will that temporary queue be killed? Or will they build up over time as requests time out?
2)
When it comes to scaling the processing tiers (adding more instances of those same routes on different machines), is it customary that if the instance that picks up the response (using a fixed reply to queue) is different than the instance that picked up the request, all the information about the original request is inside the message, so there is no need to share data across instances (unless of course there is data that is shared, like aggregrates and such)?
Any other tips and tricks when building a system like this would be very helpful.
Thanks!
I would say this solution is too complicated and there are too many areas which are hard both in terms of maintenance and also complexity. There is too much many steps mixing async and sync communication.
Why not simply the solution to the following steps:
Synchronously http request
Put message on MQ with reply to header
Message is picked up and sent to backend
If reply is not received within a given time transaction is terminated.
The reply to queue is removed
Requestor is notified.
I need to send a asynchronous message to client from my CXF (JAX WS) webservice layer...
How client would be capable of receiving it?What steps need to be taken care to achieve this?Is there a sample tutorial available?
You have two options to achieve asynchronous calls from client with CXF.
You can poll the service for response
You can define a callback which will be executed when the server's job is done
Each solution has pros and cons, so choose according to your needs.
The polling gives you a Response object and you can test if the call is complete on it by response.isDone(). (if not, wait some time, then send another request)
The callback gives you a Future object which wraps the call, you can define an AsyncHandler for instance when you call the service to define what will be run when the process is finished.
From the server side, you should take a look at WS-Addressing (to define a replyTo endpoint for callback if needed) and WS-POLICY: http://cxf.apache.org/docs/ws-addressing.html
Note that if you need to use callbacks (it seems so), you will have to define a CXF client on the client side to enable WS-addressing (on the cxf bus).
Do I need to do anything to make all requests asynchronous or are they automatically handled that way?
I ran some tests and it appears that each request comes in on its own thread, but I figure better to ask as I might have tested wrong.
Update: (I have a bad habit of not explaining fully - sorry) Here's my concern. A client browser makes a REST request to my server of http://data.domain/com/employee_database/?query=state:Colorado. That comes in to the appropriate method in the controller. That method queries the database and returns an object which is then turned into a JSON structure and returned to the calling app.
Now let's say 10,000 clients all make a similar query to the same server. So I have 10,000 requests coming in at once. Will my controller method be called simultaneously in 10,000 distinct threads? Or must the first request return before the second request is called?
I'm not asking about the code in my handler method having asynchronous components. For my case the request becomes a single SQL query so the code has nothing that can be handled asynchronously. And until I get the requested data, I can't return from the method.
No REST is not async by default. the request are handled synchronously. However, your web server (IIS) has a number of max threads setting which can work at the same time, and it maintains a queue of the request received. So, the request goes in the queue and if a thread is available it gets executed else, the request waits in the IIS queue till a thread is available
I think you should be using async IO/operations such as database calls in your case. Yes in Web Api, every request has its own thread, but threads can run out if there are many consecutive requests. Also threads use memory so if your api gets hit by too many request it may put pressure on your system.
The benefit of using async over sync is that you use your system resources wisely. Instead of blocking the thread while it is waiting for the database call to complete in sync implementation, the async will free the thread to handle more requests or assign it what ever process needs a thread. Once IO (database) call completes, another thread will take it from there and continue with the implementation. Async will also make your api run faster if your IO operations take longer to complete.
To be honest, your question is not very clear. If you are making an HTTP GET using HttpClient, say the GetAsync method, request is fired and you can do whatever you want in your thread until the time you get the response back. So, this request is asynchronous. If you are asking about the server side, which handles this request (assuming it is ASP.NET Web API), then asynchronous or not is up to how you implemented your web API. If your action method, does three things, say 1, 2, and 3 one after the other synchronously in blocking mode, the same thread is going to the service the request. On the other hand, say #2 above is a call to a web service and it is an HTTP call. Now, if you use HttpClient and you make an asynchronous call, you can get into a situation where one request is serviced by more than one thread. For that to happen, you should have made the HTTP call from your action method asynchronously and used async keyword. In that case, when you call await inside the action method, your action method execution returns and the thread servicing your request is free to service some other request and ultimately when the response is available, the same or some other thread will continue from where it was left off previously. Long boring answer, perhaps but difficult to explain just through words by typing, I guess. Hope you get some clarity.
UPDATE:
Your action method will execute in parallel in 10,000 threads (ideally). Why I'm saying ideally is because a CLR thread pool having 10,000 threads is not typical and probably impractical as well. There are physical limits as well as limits imposed by the framework as well but I guess the answer to your question is that the requests will be serviced in parallel. The correct term here will be 'parallel' but not 'async'.
Whether it is sync or async is your choice. You choose by the way to write your action. If you return a Task, and also use async IO under the hood, it is async. In other cases it is synchronous.
Don't feel tempted to slap async on your action and use Task.Run. That is async-over-sync (a known anti-pattern). It must be truly async all the way down to the OS kernel.
No framework can make sync IO automatically async, so it cannot happen under the hood. Async IO is callback-based which is a severe change in programming model.
This does not answer what you should do of course. That would be a new question.
How can the web server invoke a method on the client synchronously using SignalR? The key part here is that the server should wait for client to send data back to the server before continuing on?
Basically I'm looking to treat a client method invoke like a WCF service request. Invoke the client and wait for the data to be returned.
SignalR does not provide a way to synchronously invoke client-side methods.
To achieve the same functionality as a synchronous call, you could pass some sort of invocation ID as an argument to your client-side method. The client could then invoke a server-side method like ClientMethodCompleted with its invocation ID when the client-side method is done. Basically you will be implementing your own ACK.
If you go this route, you will have to track the client invocations along with their respective ID's on the server. You can then execute whatever logic you would have done after a synchronous call in the ClientMethodCompleted method on the server.
This should be fairly simple if you are invoking the method on only one client. If you are invoking the method on multiple clients you will have to keep track of which clients you are invoking your method on so you can ensure all the clients have acknowledged the invocation before running your followup code.
I would also make sure that you periodically clean up the data structure storing unacknowledged client invocations if you are at all worried about a DOS attack, since this would be an obvious attack vector that could allow a malicious client blowup memory consumption.