Advantage of asynchronous code on server side? - asynchronous

Suppose I have an API endpoint written in JavaScript such as Scenario A and Scenario B below (Note, this is pseudo code for illustration purposes).
The result of the database call, and the results of function A and function B need to be returned by the server at the same time.
Note: my question is not about how asynchronous code works.
Scenario A - asynchronous
db_connection.async_query(sql)
.then( result => {
functionA(result);
})
.then( result => {
functionB(result);
})
Scenario B - synchronous
const result = db_onnection.sync_query(sql)
functionA(result)
functionB(result)
Since the result of the database call and the result of both functions need to be returned by the server simultaneously, is there any benefit to the asynchronous version? It is less concise and not as easy to read as the synchronous version.
I have a fairly complex application with asynchronous code in the browser which makes perfect sense, but I wonder if it adds needless complexity to the server side since I am ultimately sending back the result of everything all at once anyway.
An exception I can think of is if I were to make an API call to enter a new user into the database and also send them an email. The email will not be part of the server response so asynchronous execution is better as they can run simultaneously.
What is the advantage to the asynchronous version of these two scenarios?

Related

Choosing between calling asp.net core blazor methods synchronously or asynchronously

I have a CRUD app in Blazor that simply fetches the assignment lists from a table and has an AssignmentReminderService for data access layer that has a method (async version)
public async Task<AssignmentReminder> AddAssignment(AssignmentReminder assignment)
{
_context.assignments.Add(assignment);
await _context.SaveChangesAsync();
return assignment;
}
I can also call the method with synchromus code as :
public AssignmentReminder AddAssignment(AssignmentReminder assignment)
{
_context.assignments.Add(assignment);
_context.SaveChanges();
return assignment;
}
Now it is just one database being accessed from a local server(could be hosted on cloud as well) with just one assignment table and the default authentication/authorization tables generated when one uses Individual User Account (aspnetusers, aspnetroles etc)
Can someone let me know which of the two ways I should use (between async or sync) method declaration?
In the general case, you should use asynchronous APIs if they are available. This will result in greater scalability on the server side, since asynchrony will allow the calling request thread to be used for other requests while the asynchronous operation is in progress.
There are specific scenarios where this guideline doesn't apply. E.g., if you're calling a generic asynchronous API (like Stream.ReadAsync) but you know that the implementation is actually synchronous (like MemoryStream). But in general, if there's an asynchronous API, then that's the one you should use.
You should be clear about the version of blazor you're talking about, because using async methods in the client is different from using them in the server version.
which of the two ways I should use (between async or sync) method declaration?
The first one.
The scarce resource here are the Threads. You want to keep their number down, and the first approach enables that by releasing the Thread to do other work.
In the second approach the Thread is suspended for the duration of the I/O operation. You would need more Threads to handle the same number of requests.
So using async I/O lets the same hardware handle more requests at the same time.

Why 'await' cannot be used in ordinary functions?

Correction: as follows from two answers, the problem looks to be specific to dart as C# implements Task.Wait allowing to achieve the desired effect. I would be grateful for any further information on the reasons why this is not possible in dart or how to achieve it there. I would be happy to close the question in its current form.
There are situations where it could make sense to have synchronous functions use asynchronous calls internally waiting for their completion before delivering the result. This is explicitly not allowed in both C# and Dart: anything that uses await must be marked as async (thus returning a future).
A simple example in Dart, but the same is valid for C#:
Disclaimer: this is not how I would do things, so do not suggest a "correct" solution of converting all methods to async; the code here is just to illustrate the question.
I have a fully asynchronous implementation of a generic wrapper for HTTP requests to some particular REST API. It does some login, authentication etc.:
class RequestProcessor {
Future post(String path, [payload]) async {
return request("POST", path, payload);
}
}
I would like to implement a high-level user-facing API translating to requests to the REST-API. Some of those methods I'd like to have synchronous. This is what I would like and am not allowed to have:
class API {
final RequestProcessor processor;
API(this.processor);
// this takes long and should be asynchronous, happy with a future (OK)
Future getQueryResults(query) async {
return await processor.post("/query", query);
}
// here I would prefer to have it synchronous (COMPILE ERROR)
String getVersion() {
return await processor.post("/version");
}
}
Question: Why is this not allowed?
It's a design choice.
Dart is single-threaded - each synchronous function call will run to completion before allowing any other code to run. If you allow a synchronous function to block until a future is complete, then no other code will run and the future will never complete (because the code that would complete it can't run).
It is possible to have a system that allows other code to run while one synchronous function is blocked. That requires either having more than one active stack (parallel or not), or implicitly transforming the entire program to be async. Neither choice is great when you compile to JavaScript, so Dart did not try to do that.
The await is an asynchronous wait so it does not make sense to have it in a synchronous function. To be asynchronous the method needs to return when the awaited operation is initiated, whereas the synchronous method needs to run to completion.
You can use a synchronous wait instead, in which case your method does not need to be async. In C# you can do this by calling the Wait() method on the returned task.
Because waiting and returning a future is fundamentally different.
Returning a future frees the current thread and optionally schedules a continuation for later, waiting blocks the current thread.
For example, in a UI thread, returning a future is fine but waiting will cause the UI to hang, in a web server thread waiting will block the thread and prevent the web server from handling more request, etc.
It's even possible waiting for what should be an async operation will cause a deadlock.
.net provide Task.Wait for when you know waiting is fine, I don't know about dart - but this is not automatic (except for await inside catch clauses in async methods in C#)
In Dart marking a function/method async tells the VM that it needs to rewrite the code before executing it.
await doesn't change an async function to a sync one, the function is still async, it just allows nicer syntax than then(() { return ...then(() { return...})}) chains.
If you make an async call everything following is async, there is nothing you can do about it.

Async calls using HTTPClient vs Direct calling methods asynchronously using Tasks for a synchronous service

I have a scenario in my existing application where on the click of a Save button a Javascript function is called. This javascript function internally makes 4-5 asynchronous calls to webservices.For some reasons we have big javascript files now with lot of business logic. Also we are facing performance issues in the application. To reduce the number of XHR calls we are making to the server, we thought of consolidating these calls on the server side and just make a single call from our Javascript.
On the server side we are using Async Await to make this calls asynchronous.So we have created a wrapper service with one method which now calls different service methods using SendAsync method exposed by HTTPClient.
Our underlying services are all synchronous and to achieve asynchronous functionality we used HTTPClient. We measured performance and it shows considerable gain.
But, one of our colleague pointed out that we will actually have an overhead of serialization and Deserialization as well as we are originating now other webservice calls from server which will ultimately run synchronously.So why not directly call the methods instead of new HTTP calls.
ow our methods are all synchronous and to make them asynchronous we will have to use Tasks which will again be overhead.
Both the approaches will be overhead but we see the making new HTTP requests using async await more inline with the microservices concept.
There is a debate and I would like to know other thoughts.
My two-cents:
The approach of aggregating the information on the server side is good.
From my point of view the use of HTTPClient internally on the server side is a solution only if you want to connect to a legacy service and you do not have the ability to integrate it directly. HTTPClient is simple to use and robust, but it's technically a lot more overhead than using a Task (think of error handling, serialisation, testing, network/socket-resources).
A Task is also nice, since it allows proper cancelation, which HTTPClient cannot achieve (HTTPClient can only close the socket, other end could still block resources).
On top of the general resource aspect, the use of Futures makes the Task a perfect match:
https://msdn.microsoft.com/en-us/library/ff963556.aspx

Web API 2 - are all REST requests asynchronous?

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.

Meteor threading style clarification

Meteor's documentation states:
In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node
Do they actually mean?
A) the server is running multiple threads in parallel (which seems unusual within the Node.js ecosystem)
or
B) There is still only a single thread within an evented server and each request is processed sequentially, at least until it makes calls to resources outside the server - like the datastore, at which point the server itself is handling the callbacks while it processes with other requests, so you don't have to write/administer the callbacks yourself.
Brad, your B is correct.
Meteor uses fibers internally. As you said, there's only one thread inside an evented server, but when you do (eg) a database read, Fibers yields and control quickly gets back to the event loop. So your code looks like:
doc = MyCollection.findOne(id);
(with a hidden "yield to the event loop, come back when the doc is here") rather than
MyCollection.findOne(id, function (err, doc) {
if (err)
handle(err);
process(doc);
});
Error handling in the fiber version also just uses standard JavaScript exceptions instead of needing to check an argument every time.
I think this leads to an easier style of code to read for business logic which wants to take a bunch of actions which depend on each other in series. However, most of Meteor's synchronous APIs optionally take callbacks and become asynchronous, if you'd like to use the async style.

Resources