Can someone please help me understand the difference between async scope and vm in mule. I understand vm is like in memory JMS, but if my requirement is to process something asynchronously, can I use either of them at will ? If not, what are the differences.
For example, what can be the difference between the following:
Main flow1 calling another flow using async scope:
<flow name="mainflow1">
...
<async>
<flow-ref name="anotherflow" />
</async>
...
</flow>
Main flow2 calling another flow using VM:
<flow name="mainflow2">
...
<outbound-endpoint address="vm://anotherflow" exchange-pattern="one-way" />
..
</flow>
Assume another flow writes a record to some database and is not of request-response type.And how about thread safety. Are both complete thread safe?
Matt's answer is correct. I might add a couple of additional benefits you get for the extra cost of going through a queue instead of just calling another flow:
Using a VM outbound endpoint (or indeed, any queue) offers you the ability to queue up messages under temporary high load, and control what happens when there are more messages than your target flow can consume (maximum outstanding messages, what to do when you reach that maximum, how long to wait for a publish to succeed before you error out, etc). This is the purpose of SEDA.
On the consumer end, using a queue instead of a flow reference allows you to use a transaction to be sure that you do not consume the message unless your intended processing succeeds.
VM queues offer a convenient place to test parts of your application in isolation. You can use the MuleClient in a functional test to send or receive messages from a VM queue to make sure your flows work properly.
The main difference between the two is the context of the flow. When using a vm endpoint, mule treats the message as if it were a completely new incoming message. It has a completely new context and separate properties and variables. If you want to inherit the properties and variables from the calling flow, you can use a flow-ref to call a flow or subflow (see here for the differences between a flow and subflow: http://www.mulesoft.org/documentation/display/current/Flows+and+Subflows). Since the vm endpoint creates a new context, there is more overhead in the call and it is less efficient, but with that extra overhead, you get all of the infrastructure that comes with making a full mule call.
Related
I have created a custom logger which sends messages to a service bus queue. My problem is that the Microsoft.Extensions.Logging.ILogger has no async Log method, so am having to call an async method synchronously which can cause issues.
_queueClient.SendAsync(message).Wait();
So my questions is, what is the safest way for me to accomplish this without it causing thread starvation?
Net Core Logging is designed specifically to not use async methods. They believe that logging should be quick enough that it doesnt need it.
"Logging should be so fast that it isn't worth the performance cost of
asynchronous code."
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.2
The recommendation is that if you need to log stuff like this, you use a "Batched Logger" instead.
"Instead, synchronously add log messages to an in-memory queue and have
a background worker pull the messages out of the queue to do the
asynchronous work of pushing data to SQL Server."
So, basically, you should move your queue calls into a background worker (HostedService) and get it to do the async calls in the background worker instead. Your normal "logger" method should call something that sticks the messages into a MemoryCache queue or something similar and then your background worker will fetch the out of there in the background. I'm sure (off the top of my head) the Azure Logger has a simple example of this sort of thing
I have a .Net Core Web Api setup where I expose an endpoint that is basically a forever-frame. I am constrained by an API contract that forces me to expose it as such.
That forever-frame pushes data that is received from a Redis pub/sub channel. I will have multiple listeners on this endpoint, and they should basically be individual subscribers to the same channel.
I use StackExchange.Redis.
There is one thing I cannot wrap my head around, and that is how to use the ConnectionMultiplexer in this scenario. Everywhere I read about it I am told to have one global ConnectionMultiplexer. But if I do that won't I unsubscribe all subcribers when one leaves and shuts down a subscription to the channel that they are all listening to?
If I don't then I will run into a memory leak I am sure.
A global ConnectionMultiplexer keeps the number of connections to Redis at a minimum, but I don't see any way to avoid it here.
Is there something I have misunderstood?
Always use the same instance of ConnectionMultiplexer, or you will lose the benefits of using a multiplexer.
I had a similar issue when calling unsubscribe on a channel caused all subscribers to unsubscribe too.
If you look at the ISubscriber interface, there is two ways to subscribe to a channel :
void Subscribe(RedisChannel channel, Action<RedisChannel, RedisValue> handler, CommandFlags flags = CommandFlags.None);
ChannelMessageQueue Subscribe(RedisChannel channel, CommandFlags flags = CommandFlags.None);
I took the second one and it solved my problem.
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.
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.
I'm setting up a web service in Axis2 whose job it will be to take a bunch of XML and put it on to a queue to be processed later. I understand its possible to set up a client to invoke a synchronous web service asynchronously by creating a using an "invokeNonBlocking" operation on the "Call" instance. (ref http://onjava.com/pub/a/onjava/2005/07/27/axis2.html?page=4)
So, my question is, is there any advantage to using an asynchronous web service in this case? It seems redundant because 1) the client isn't blocked and 2) the service has to accept and write the xml to queue regardless if it's synchronous or asynchronous
In my opinion, asynchronous is the appropriate way to go. A couple of things to consider:
Do you have multiple clients accessing this service at any given moment?
How often is this process occurring?
It does take a little more effort to implement the async methods. But I guarantee, in the end you will be much happier with the result. For one, you don't have to manage threading. Your primary concern might just be the volatility of the data in the que (i.e. race/deadlock conditions).
A "sync call" seems appropriate, I agree.
If the request from the client isn't time consuming, then I don't see the advantage either in making the call asynchronous. From what I understand of the situation in question here, the web-service will perform its "processing" against the request some time in the future.
If, on the contrary, the request had required a time consuming process, then an async call would haven been appropriate.
After ruminating some more about it, I'm thinking that the service should be asynchronous. The reason is that it would put the task of writing the data to the queue into a separate thread, thus lessening the chances of a timeout. It makes the process more complicated, but if I can avoid a timeout, then it's got to be done.