I have a AWS lambda function written in c#. This function is responsible for calling 5-6 API calls (Post requests).
All of these API calls are independent of each other.
I do not care of the about the responses from any of these API calls.
Each of the API call takes about 5 seconds to complete even though I do not care about the follow up response.
Question:
I want my lambda function to execute and respond within a second. How can I asynchronously make my API calls such that lambda function can finish all of these within my time limit without waiting for the responses from the API calls? Ideally, I want to implement a fire and forget API call system that sends the final response back without any delay.
According to AWS lambda documentation, I have to use await operator with asynchronous calls in lambda to avoid the function being completed before the asynchronous calls are finished.
Am I missing something here? Or is there a way to accomplish this?
Thanks
You can't run code "outside" of a serverless request. To try to do so will only bring pain - since your serverless host has no idea that your code is incomplete, it will feel free to terminate your hosting process.
The proper solution is to have two lambdas separated by a queue. The first (externally-facing) lambda takes the POST request, drops a message on the queue, and returns its response to the caller.
The second (internal-only) lambda monitors the queue and does the API calls.
For your use case, using AWS Step functions will provide a fully managed solution. The steps are as follows.
Define you AWS step function flow, based on whether you want trigger them parallel or one after another.
Integrate the initial step with API Gateway POST method.
After starting the Step function state machine, it will return a success state (Immediately without waiting for the end state)
There are few benefits with Step functions over custom Lambda flow implementation.
You can configure to retry each step, if individual steps return errors.
If any of the steps ends up with an error, you can trigger a callback.
You can visually identify and monitor which step had issues & etc.
If you just want a fire and forget, then don't use await. Just use an HttpClient method (get, put, etc.) to call the API, and you're done. Those methods return a Task<HttpResponseMessage> which you don't care about, so it's fine for your Lambda to exit at that point.
Related
I am using SendGrid (cloud based SMTP service) to send emails from a web api project. I want my application to wait/block (for say 30 secs) until I have a response from SendGrid before returning the response to the client, rather than returning immediately. The SendGrid library has a DeliverAsync method which returns a Task.
I have been looking at how I might Wait on the task.
I have read endless articles about how one might do this and understand that if it was my own code I would use the ConfigureAwait(false) on the task to prevent a deadlock and allow me to Wait. The problem here is that the code is not mine! It doesn't look like SendGrid have a synchronous Send method.
I do not have async controllers wired up, although appreciate this would be a way to do this, but I'd like to know if there is another way I could do this.
Hope this makes sense!!
If you can await all the way up to and including the controller action, you should, and as that's your code it should be achievable. In that case, at most you might want to consider ConfigureAwait(true) for the call from the controller method only, and have the rest (downwards) as ConfigureAwait(false) (as library methods should be). Most of the time you don't even need the context preserved in the controller action - it depends what you do there - and in that case use ConfigureAwait(false) there too.
You use "wait/block" as though they're the same, but in the TAP world they're quite different. Using await will wait for the SendGrid() call to complete before continuing, while not blocking the calling thread.
If you can't do that, it's far less-preferable to use the blocking .Wait() or .Result, or as others mention GetAwaiter().GetResult(). All 3 will block the caller as well. In Web API you can often get away with this; but in other contexts - e.g. WinForms - you probably won't.
As it's your code, use await.
I THINK I understand the basic principle of an asynchronous POST method from a high level view point. The big advantage is that the caller gets a quick response, even though the processing of the data from the POST might not be completed yet.
But I don't really understand how this applies to a GET method. The response needs to contain the data, so how can there BE a response before processing is completed? Why have an API with a GET request handler that utilizes asynchronous methods?
I don't think it matters for this general type of question, but I'm writing in C# using Web API.
On the network there is no such thing as an async HTTP call. It's just data flowing over TCP. The server can't tell whether the client is internally sync or async.
the caller gets a quick response
Indeed, the server can send the response line and headers early and data late. But that has nothing to do with async IO or an async .NET server implementation. It's just some bytes arriving early and some late.
So there is no difference between GET and POST here.
why ... utilize asynchronous methods?
They can have scalability benefits for the client and/or the server. There is no difference at the HTTP level.
So the app can do other things that don't need the data.
If you implement a GET as synchronous (and let's say you are on a bad network, where it takes 20 seconds to get it), you can't
Show progress
Allow the user to cancel
Let them initiate other GETs
Let them use other parts of the app
EDIT (see comments): The server wants to respond asynchronously for mostly the same reason (to give up the thread). Actually getting the data might be asynchronous and take some time -- you wouldn't want to block the thread for the whole time.
It doesn't make any sense if you're building a RESTful API, in which GET should return a resource (or a collection) and be idempotent (not make any changes).
But if you're not following those principles, a GET request could perform some work asynchronously. For example, GET /messages/3 could return the message to the client, but then asynchronously do other work like:
mark the message as read
send a push notification to the user's other clients indicating that the message is read
schedule a cronjob 30 days in the future to delete the message
etc.
None of these would be considered a RESTful API, but are still used from time to time.
I am making a asp.net webapi call that posts some data to the server and will need to be processed. The client does not need to wait for the processing to finish. I would like to return something like this
HttpResponseMessage objReturn = Request.CreateResponse(HttpStatusCode.Ok);
//start a thread to do some work processing the data
//return while the data is being processed
return objReturn;
Most of the example I find are about how to use async methods and wait for the processing to complete. I need the opposite.
thanks for you suggestions.
more code for those asking, the following code gives me a warning that the method lacks await and will run synchronously.
public async Task<HttpResponseMessage> Post()
{
HttpResponseMessage objReturn = Request.CreateResponse(HttpStatusCode.Ok);
//data processing logic
//something longer running that the client doesnt need to wait for
//like converting a pdf to jpg or other I/O operations
return objReturn;
}
If I read your question correctly, you want a user to call an API, quickly receive a response, and have that trigger a longer running task.
In general, you do not use Web Api to run this longer task, instead yo use a service (i.e. Windows Service).
That service will sit there ... waiting for work ...
your Api will give it work! (Using a database, queues, files, etc.)
However, depending on how important this is, how much effort, and how much time ... you may not want to create a whole separate service. There are some "tools" that can help you.
QueueBackgroundWorkItem
http://hangfire.io/
^^ They will help you run long tasks in your Api directly! ^^
The warning explains most of your problems. Just decorating a method with async does not mean that it runs asynchronous automatically. If you don't have any asynchronous work in your data processing logic it will run synchronously. Event if you have some asynchronous calls in there, the compiler can decide to run it synchronously if it think that's the better option. Remember that asynchronous work does NOT involve another thread.
Some hints what you can do. First, you should make your I/O calls asynchronous. The .NET framework offers a lot you can use here. Second, you should not do that work in a controller. A controller should be small and don't do heavy processing, because it is your communicator to the rest of the world. Pass everything that needs more processing to a queue where a worker role (such as a Windows Service) picks up the work that needs to be done. With that the controller has nothing to do as passing data to the queue, give a result to the client that it was put into the queue ... and done. After that your controller can pick up additional work.
I'm not a C# guy I'm more an Objective-C guy but lately I've seen a lot of implementations of:
public void Method(Action<ReturnType> callback, params...)
Instead of:
public ReturnType Method(params...)
One of the examples of this is the MVVM Light Framework, there the developer implements the data service contract (and implementation) using the first approach, so my question is: Why this? Is just a matter of likes or is the first approach asyncronous by defaut (given the function pointer). If that's true, is the standard return death? I ask cause I personally like the second approach is more clear to me when I see an API.
Unlike the API returning ReturnType, a version with callback can return right away, and perform the callback later. This may be important when the value to return is not immediately available, and getting it entails a considerable delay. For example, and API that requests the data from a web service may take considerable time. When the result data is not required to proceed, you could initiate a call, and provide an asynchronous callback. This way the caller would be able to proceed right away, and process notifications when they become available.
Consider an API that takes a URL of an image, and returns an in-memory representation of the image. If your API is
Image GetImage(URL url)
and your users need to pull ten images, they would either need to wait for each image to finish loading before requesting the next one, or start multiple threads explicitly.
On the other hand, if your API is
void Method(Action<Image> callback, URL url)
then the users of your API would initiate all ten requests at the same time, and display the images as they become available asynchronously. This approach greatly simplifies the thread programming the users are required to do.
The first method is likely to be an asynchronous method, where the method returns immediately and the callback is called once the operation has finished.
The second method is the standard way of doing method returns for (synchronous) methods in C#.
Of course, API designers are free to make whatever signature they seem fit; and there might be other underlying details to justify the callback style. But, as a rule of thumb, if you see the callback style, expect the method to be asynchronus.
I was going through MSDN documentation on WebServices. Here and here, both these links talk about calling a webservice and wait for the response, which is also a general trend that I have seen while asynch implementation.
I don't understand "why do we need to wait for service call to return"? And, if we are waiting why don't make an synchronous call. What is the difference between an "asynch call followed by wait" and a "synchronous call"?
To be useful, the asynchronous call needs to do its thing while you go do something else. There are two ways to do that:
Provide a callback method for the asynchronous handle, so that it can notify you when it is completed, or
Periodically check the asynchronous handle to see if its status has changed to "completed."
You wouldn't use a WaitHandle to do these two things. However, the WaitHandle class makes it possible for clients to make an asynchronous call and wait for:
a single XML Web service
(WaitHandle.WaitOne),
the first of many XML Web services
(WaitHandle.WaitAny), or
all of many XML Web services
(WaitHandle.WaitAll)
to return results.
In other words, if you use WaitOne or WaitAny on an asynchronous web service that returns several results, you can obtain a single result from your web service call, and process it while you are waiting on the remaining results.
One very practical use of asynchronous calls is stuff like this
http://i.msdn.microsoft.com/Bb760816.PB_oldStyle%28en-us,VS.85%29.png
If you want to update your UI while you're waiting for a 'server' to do something, you need to make an asynchronous call. If you make a synchronous call, your code will be stuck waiting, but if you make an asynchronous call you can update the UI or even let the user go do other stuff while you're waiting for the callback. This goes beyond UI, you may make an asynchronous call to start some non-critical task and continue on with your code and its possible you don't even register for a callback if the result is unimportant.
If you do NOTHING while waiting for the asyncronous call, then its less useful.
Using asynchronous call can free up your application to do other things while waiting for the response. Since there is a fairly large amount of time (in computer cycles) waiting for a web server to respond, that time can be used for better things such as displaying a status update or doing some other work.
For example, if you had a program that performed a complicated calculation and a step of that calculation included using some reference data from a remote web service. By calling the web service asynchronously at the start of the calculation, continuing the parts of computation that can be performed locally, and then using the result of the web service call when it is available to complete the computation you can reduce the overall time of the calculation.
Since your application code is not blocked waiting for the web service to respond, you are able to utilize that wait time to the benefit of the user.
Another reason is scaling, particularly in web sites that make calls to other web services. By using asynchronous page methods (or tasks), IIS can scale your application more effectively by deferring your pages that are waiting on asynchronous web requests to whats known as an "IO thread", freeing up the main ASP.NET worker threads to serve more web pages.
The first example you're linking to issues an async call and then immediately waits for the result. Other than forking off the job to another thread, there's little difference between this and a synchronous call as far as I can tell.
The other example, however, talks about doing multiple async calls at once. If this is the case, it makes sense to launch all calls and then wait because the calls may execute in parallel.
One of the possible uses of an asynchronous call followed by a wait is that asynchronous operations often support cancellation whereas blocking calls do not. Combined with the CancellationToken pattern in .NET 4.0 (or a similar custom pattern pre-.NET4) you can create an operation that appears to be synchronous but can be cancelled easily.