Nest.js asynchrony behaviour - async-await

I don't clearly understand how works Nest.js asynchrony. For example if don't want my appliation block event loop then how i should work with this?
here is my controller
#Get()
async findAll() {
return await this.templatesService.findAll();
}
and here is my service
async findAll() {
return await this.templatesRepository.find();
}
Does this 'await' block my application somehow? I mean can i do my requests to backend if this 'await' waiting response?

The purpose of async/await is actually to prevent your application from freezing while handling requests. That means, you can send requests to your backend while the server is processing the previous one.

Related

How do I use Heartbeat with a Callback Return Step Function in my Lambda Function?

My Lambda function is required to send a token back to the step function for it to continue, as it is a task within the state machine.
Looking at my try/catch block of the lambda function, I am contemplating:
The order of SendTaskHeartbeatCommand and SendTaskSuccessCommand
The required parameters of SendTaskHeartbeatCommand
Whether I should add the SendTaskHeartbeatCommand to the catch block, and then if yes, which order they should go in.
Current code:
try {
const magentoCallResponse = await axios(requestObject);
await stepFunctionClient.send(new SendTaskHeartbeatCommand(taskToken));
await stepFunctionClient.send(new SendTaskSuccessCommand({output: JSON.stringify(magentoCallResponse.data), taskToken}));
return magentoCallResponse.data;
} catch (err: any) {
console.log("ERROR", err);
await stepFunctionClient.send(new SendTaskFailureCommand({error: JSON.stringify("Error Sending Data into Magento"), taskToken}));
return false;
}
I have read the documentation for AWS SDK V3 for SendTaskHeartbeatCommand and am confused with the required input.
The SendTaskHeartbeat and SendTaskSuccess API actions serve different purposes.
When your task completes, you call SendTaskSucces to report this back to Step Functions and to provide the results from the Task that your workflow can then process. You do not need to call SendTaskHeartbeat before SendTaskSuccess and the usage you have in the code above seems unnecessary.
SendTaskHeartbeat is optional and you use it when you've set "HeartbeatSeconds" on your Task. When you do this, you then need your worker (i.e. the Lambda function in this case) to send back regular heartbeats while it is processing work. I'd expect that to be running asynchronously while your code above was running the first line in the try block. The reason for having heartbeats is that you can set a longer TimeoutSeconds (or dynamically using TimeoutSecondsPath) than HeartbeatSeconds, therefore failing / retrying fast when the worker dies (Heartbeat timeout) while you still allow your tasks to take longer to complete.
That said, it's not clear why you are using .waitForTaskToken with Lambda. Usually, you can just use the default Request Response integration pattern with Lambda. This uses the synchronous invoke mode for Lambda and will return the response back to you without you needing to integrate back with Step Functions in your Lambda code. Possibly you are reading these off of an SQS queue for concurrency control or something. But if not, just use Request Response.

Asynchronous call using Spring webclient and just log the error without aborting the flow

I am trying to make an asynchronous call to a rest service using Spring webclient. I dont care if there is any exception during this call, but i want to just log if its successfull or failure (With http Status and details if Failure of course) but i want to continue to flow without stopping the flow. Can anyone suggest how can i improve below code:
In general , with regular try catch block I can do below:
try {
restTemplate.execute(....);
} catch(HttpStatusCodeException e) {
//log and continue the flow....
}
What I came up is with below, but not sure if its the best way to execute a webclient as i am still trying to understand all the intermittent or terminal operations within it.
#Async
public void test() {
webclient
.post().uri("/urihere")
.bodytoMono(requestBody)
//as exchange is deprecated
.exchangeToMono(response -> {
if(response.statusCode().is4xxHttpClientError) || response.statusCode().is5xxHttpServerError)) {
//log with response body
} else {
//log successs response.
}
});
}
I understand that I don't need to do a .block() as I don't want to wait until the request is completed. But what I am trying to understand is the test method with web client call have the same functionality as in with try catch ? Meaning, we just make a call and log the request /response but don't worry about the response?
Or am I doing anything incorrectly here. Need suggestions on above code for improvements or standards please (Is it fully reactive in nature with above code for the requirement is what I am trying to understand).

Angular/RxJS Should I unsubscribe on every ajax call?

Should I unsubscribe on every ajax call? According to the RxJS contract, I should. Because AJAX calls are not streams or events, once they are done they are done. What is the reason of using RxJS at all in this particular case? Overtime it becomes the mess (I know about takeUntil, that's not the point here).
public remove(data: IData): void {
// unsubscribe from the previous possible call
if (this.dataSubscription &&
this.dataSubscription.unsubscribe) {
this.dataSubscription.unsubscribe();
}
this.dataSubscription = this.dataService
.delete(data.id)
.subscribe(() => {
this.refresh();
});
}
public ngOnDestroy(): void {
// unsubscribe on deletion
if (this.dataSubscription &&
this.dataSubscription.unsubscribe) {
this.dataSubscription.unsubscribe();
}
}
What is the advantage over simple promise, that looks cleaner and destroyed right after execution?
public remove(data: IData): void {
this.dataService
.delete(data.id)
.then(() => {
this.refresh();
});
}
This is DataService code
#Injectable()
export class DataService {
constructor(private _httpClient: HttpClient) { }
public delete(id: number): Observable<IModel> {
return this._httpClient.delete<IModel>(`${this._entityApiUrl}/${id}`);
}
}
Finite, cold Observables usually don't need to be unsubscribed. They work just like Promises in this regard. Assuming you're using Angular's HttpClient in your service, no unsubscription is necessary--it's much like a Promise in that situation.
First off, to clear some things up -- in your Promise example, you are imperatively managing the Promise by assigning it to this.dataSubscription. After that call is made, anything that calls this.dataSubscription.then() an arbitrary amount of time after the HTTP call will receive a Promise.resolve() and invoke that .then() function. The new Promise returned by Promise.resolve() will be cleaned up after it executes, but it's only until your class is destroyed that your this.dataSubscription Promise will be cleaned up.
However, not assigning that Promise as a property is even cleaner:
public remove(data: IData): void {
this.dataService
.delete(data.id)
.then(() => {
this.refresh();
});
}
plus, the Promise will be cleaned up at the end of its scope, not on the destruction of the class.
Observables, at least finite 'Promise-like' ones like this, work in much the same way. You don't need to manage the Subscription returned buy the .subscribe() method imperitavely, as it will execute and then be cleaned up as it's not assigned as a property:
public remove(data: IData): void {
this.dataService
.delete(data.id)
.subscribe(() => {
this.refresh();
});
}
It's a finite Observable and completes after the subscription, so calling subscribe again will return a new Subscription and re-call the Observable's function.
Imperitavely managing those subscriptions is indeed messy and usually a sign things could be done better.
The difference with RXJS's subscription management is that RXJS can become an incredibly powerful tool, one that is useful for way, way more than managing async AJAX calls. You can have hot Observables that publish data to hundreds of subscribers, Subjects that manage their own stream to many subscribers, infinite Observables that never stop emitting, higher-order Observables that manage state and return other Observables, etc. In this case unsubscribing is best practice, but honestly not going to cause performance issues outside of extreme cases.
A good comparison is the Observable.fromEvent() property. Just like it's best practice to use removeEventListener correctly after addEventListener, you should unsubscribe from this Observable correctly. However, just like removeEventListener,...it's not really done all the time and usually doesn't cause issues with today's platforms.
Also, in reference to the 'RxJS contract' that was stated: here's an excerpt from the same doc:
When an Observable issues an OnError or OnComplete notification to its observers, this ends the subscription. Observers do not need to issue an Unsubscribe notification to end subscriptions that are ended by the Observable in this way.
Finite Observables complete themselves after their emissions and don't need to be unsubscribed.
Usually you don't need to unsubscribe from HttpClient calls since all HttpClient calls complete the stream once they receive response from the server. Once an observable stream completes or errors, its the responsibility of the producer to release resources. For more information, read Insider’s guide into interceptors and HttpClient mechanics in Angular. You should unsubscribe only if you want to cancel the request.
Because AJAX calls are not streams or events, once they are done they are done... What is the advantage over simple promise, that looks cleaner and
destroyed right after execution?
AJAX calls are not just one time event. For example, you can have multiple progress events with XHR. Promise resolves with only one value, while HttpClient can emit multiple HTTP events:
export type HttpEvent<T> =
HttpSentEvent | HttpHeaderResponse | HttpResponse<T>| HttpProgressEvent | HttpUserEvent<T>
You don't need to unsubscribe on every ajax call. But then you are losing one of the core benefits of Observables - being able to cancel it.
You really need to think about what your code does and what is your standard workflow. What happens if the delete response takes a long time and user clicks it again, or clicks back, or goes to some other page?
Would you like refresh to still happen (since observable will still keep the callback in the memory) or would you rather cancel it?
It's up to you and your application at the end. By using unsubscribe you save yourself from unplanned side effects.
In your case, it's just a refresh so it's not a big deal. Then again, you will keep it in the memory and it might cause some side effects.

canceling Synchronous multipart request

I need to send multipart post request from AsyncTask using loopj, so I'm forced to use SyncHttpClient.
Reading the source code comments, I'm learning that a Request Handle returned from the post method of synchronous request cannot be used to cancel the request because it is already complete by the time this returns (which makes sense). Looks like a catch 22 though.
Is there another way to cancel a currently running Synchronous request?
Is it possible to use SyncHttpClient.cancelAllRequests(true); from the UI thread?
Well, SyncHttpClient.cancelAllRequests(true) from the UI thread does not work. Is it a bug?
Just make sure that you can use AsyncHttpRequest if you want to be able to cancel the running request. It doesn't matter if you are running your asynchronous http request from another thread or even an AsyncTask, you just have to make sure that the AsyncHttpRequest is called on the main thread. You can do this easily by forcing it into the main thread using
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
public void run() {
// run your AsyncHttpRequest in here.
// Since it is called from the main thread it will run asynchronously
// and therefore it can be cancelled easily by calling client.cancelAllRequests(true)
}
};
mainHandler.post(myRunnable);

HttpWebRequest async versus Begin/End

I have a Web API project whose controller in turn makes web requests to a third party REST interface. My controller CRUD functions i have marked as async however the implementation is such that i use HttpWebRequest blocking functions GetRequestStream and GetResponse.
Is this suitable or should i use the Begin/End methods of HttpWebRequest too. This seems like overkill as it would be asyncing an already async operation, or would it allow more concurrent outgoing web requests?
Looking for the best solution for throughput both incoming and outgoing.
the controller is marked async but the implementation uses synchronous HttpWebRequest calls, in that my controller is awaiting Task.Run( sync web request )
Think about what is happening in the request. The request comes in and ASP.NET takes a thread pool thread to handle the request. The controller action queues the work to the thread pool (taking up another thread), and then awaits that work, freeing up the original request thread. You haven't gained anything by using await because there's still a thread pool thread blocking on the web request.
For this reason, you should almost never use Task.Run (or any other method that queues work to the thread pool) on ASP.NET.
Is this suitable or should i use the Begin/End methods of HttpWebRequest too. This seems like overkill as it would be asyncing an already async operation
It's not really asynchronous right now; there's still a thread being blocked. I call this "queue blocking work to a thread pool thread and then await it" technique fake asynchrony.
The appropriate fix is to use HttpClient, which was designed for asynchronous use; or, you could use TaskFactory<T>.FromAsync to wrap the Begin/End methods into an awaitable task.
The thing i dont understand though is if i use await HttpClient.SendAsync then somewhere something must be blocking waiting for a response
No, there doesn't have to be something blocking somewhere. As I describe on my blog, in a truly asynchronous scenario (i.e., not fake-asynchrony), there is no thread.
I would recommend you to retain the async methods, and use HttpClient instead of HttpWebRequest, because it supports asynchronous calls as well.
Let's have a look at a pseudo example of a CarsController calling a third party service.
public class CarsController : ApiController
{
[Route("cars/{id}")]
public async Task<IHttpActionResult> Get(int id)
{
//Get a car by its id
HttpClient client = new HttpClient();
//Read the content directly
string result = await client.GetStringAsync("http://www.google.com");
//process the result returns from the thrid party REST service
return Ok(result);
}
}
As you can see, HttpClient supports reading String/ Stream/ ByteArray asynchronously via GetXXXAsync() methods.
If you want to access to the underlying response content, that can be achieved by using the following code:
[Route("responsecars/{id}")]
public async Task<IHttpActionResult> GetResponseStream(int id)
{
HttpClient client = new HttpClient();
HttpResponseMessage responseMessage =await client.GetAsync("http://www.google.com", HttpCompletionOption.ResponseContentRead);
HttpContent content = responseMessage.Content;
//using one of the ReadAsync methods
string text =await content.ReadAsStringAsync();
return Ok(text);
}
Hope this help.
Asynchrony on the server is separate and independent from asynchrony on the client.
You can call a synchronous Web API method asynchronously from the client with WebRequest.GetResponseAsync, or you can call an asynchronous Web API method synchronously from the client with WebRequest.GetResponse, or you can have asynchrony on both sides, which is probably the best approach. You don't need to use Begin/End APM-style WebRequest APIs, unless you target .NET 4.0 on the client. Use Task-based async APIs instead.
In either case, a complete HTTP request will be sent to the client when your Web API controller method has fully finished, regardless of whether it is implemented as synchronous or asynchronous (Task-based).

Resources