How to test that async controller is really running async - asp.net-web-api

I have created simple async controllers that call into async methods that then call PostAsync on the HttpClient to retrieve various REST service endpoints. All works well, but how can I test to insure that the controller is really calling a background thread and releasing the primary thread back to the pool? I want to insure that I do have all the async sweetness working correctly and that I am not inadvertently running synchronous methods despite all my work to make everything async.

I found that System.Threading.Thread.CurrentThread.IsThreadPoolThread will provide whether the current thread is still a threadpool thread or not.

Related

What is the right way to dubug context cancellation for a grpc call?

I am working on an go application, that uses gin to serve the rest APIs.
I 4 of my handler functions for the APIs call a goroutine which makes a gRPC call. A strange thing i see, all the grpc calls for one of the handler fails with context cancelled while the other 3 succeed.
Looking at the logs, i noticed that my API returns before the goroutine is executed. Could it be possible that gin cancels the context after the API returns?
The context is propagated from the handler function to the goroutine through a couple of intermediate calls.
The error that i see is rpc error: code = Canceled desc = context canceled
How can i debug this? Does gin cancel the context once it returns the response?
Does gin cancel the context once it returns the response?
The docs for Request.Context() (gin uses http.Request) say:
For incoming server requests, the context is canceled when the client's connection closes, the request is canceled (with HTTP/2), or when the ServeHTTP method returns.
So, yes, the context is closed when your handler (effectively the ServeHTTP method) returns (see here). The context would also be cancelled if the connection dropped for another reason (network issue, or even your server shutting down).
The right way to handle this really depends upon what you want to achieve:
In many cases the correct behaviour is to cancel the RPC calls when the context is cancelled. For example if you are retrieving info needed to fulfil the request then cancelling those requests may save resources.
If you are triggering calls that must complete then pass in a context.Background() (or another context not directly tied to the request).
How can i debug this?
Look at why your handler is returning before all RPC calls complete; if that is what you want then you will need to use a different context (but remember this probably means you are returning an OK response code when you don't actually know yet if the entire process will be successful).

Consequences of not awaiting

I have a .net webapi that has some code to send emails.
public async Task CheckOut(CheckOutData checkOutData){
...
...
...
//What are the risks if I remove the await
await SendEmail(checkOutData);
...
...
}
public async Task SendEmail(CheckOutData checkOutData)
{
try{
...
...
...
}
catch (exception ex){
//log Error
}
}
I have setup logging in the SendEmail code. My question is, if I remove the await, is it possible for the thread to be killed and the email not being sent if the execution completes before the SendEmail completes?
Am I safe if I remove the await? I am willing to accept that an exception will be swallowed, it will be logged.
The email will be sent unless the entire process stops.
Regarding threads, we can divide SendEmail to two parts:
SendEmail
// Code that will run on the calling thread. This is the code that will prepare the data and send it to the hardware.
// Code that will run on a thread-pool thread. This is the code that will run after the hardware will finish sending the message.
The first part of the method will hold the original thread so the thread will not be released before it will finish. The second part will run on a thread-pool thread so it doesn't matter if the original thread was released.
EDIT:
If you are hosting your application on IIS, the app domain maybe recycled so it's not advised to run code that last the request. It's described in this blog post https://blog.stephencleary.com/2012/12/returning-early-from-aspnet-requests.html
In the self-hosting case this feature doesn't exist (Application pool recycling with Selfhosting a ASP.NET application). So you can just run a long running process by using Task.Run
Long running task in ApiController (using WebAPI, self-hosted OWIN)
So in the self hosting case you can avoid the await. The part of your method that you won't wait for won't be killed. As in the Task.Run case described above.
Hope this helps

Authenticator breaking when refreshing tokens with coroutines runBlocking

I have this nondeterministic bug in production and I can't pin it down with a minimal example
My setup is okhttp, which drives Retrofit, which uses coroutines adapter
I use Authenticator to refresh tokens and retry the requests, something like this
fun Authenticator.authenticate() {
...
synchronized(this) {
runBlocking { retrofitService.suspendingRefreshTokens() }<---
...
}
}
What however SOMETIMES happens is that the api call just doesn't finish, as if the coroutines were broken.
I searched the internets and there seem to be some folks affected by this as well
Using Coroutine runblock with the Authenticator to handle 401 response from retrofit
Any intuition on what could be happening? I was thinking it was some sort of a deadlock because of the synchronized, however runBlocking seems to switch back to the original context, so it should be the same thread (atleast it appears that way in testing)
This never happened before with rxjava, where I used the same blockingGet() way to keep it blocking inside Authenticator; However rxjava retrofit adapter didn't use the async parameter; which leads me to believe it possibly could be a issue with Okhttp's threadpools somehow; rather than runBlocking? (which I also read is buggy)

How to design a spring boot application that can process 1k requests a second

I have a rest controller which accepts post requests and returns the statuses of whether the operations are successfull or not. It works fine for 100 requests per second as I have multiple operations underlying it which at the end send the response.
There could be hundreds of users trying to send the requests to the controller, thereby its all done using a completable future and http Async invoker. The problem happens when there are a 1000 requests per second and then the controller threads are exhausted as there are already multiple thread processing multiple requests and all are waiting for there future to be complete and then sending the response.
How can I make my rest controller be able to handle 1000 requests per Second without breaking.
there are already multiple thread processing multiple requests and all are waiting for there future to be complete and then sending the response.
You can actually make you controllers asynchronous by making them return a CompletableFuture. Just chain the calls on the CompletableFuture returned by your service to convert them into a an appropriate response instead of using get() or join():
#RequestMapping
public CompletableFuture<ResponseEntity<…>> processRequest() {
return myService.getStatusFuture()
.thenApply(status -> convertToResponseEntity(status));
}
Of course for this to work properly you should have a truly asynchronous service. If you are using #Async or submitting tasks with CompletableFuture.supplyAsync(), this will just move the problem from the HTTP threadpool to another threadpool.
It depends on the servlet server you are using. In the application.properties file, you can use the server.* properties to set the parameters you need.
In this link you can find these properties under the EMBEDDED SERVER CONFIGURATION section. If you are using the default tomcat embedded server, check out the server.tomcat.* properties. Especially the server.tomcat.accept-count, server.tomcat.max-connections and server.tomcat.max-threads properties.

When is the WebApiRequestLifestyle scope finished?

I am trying to get an instance from the container on an ActionFilter.OnActionExecuted. The dependency is registered with Lifestyle.Scoped in a web api.
After debugging a problem, I can see that the instance returned in the filter is different than the one returned during the request (e.g. injected into controllers)
Can anyone please explain what exactly are the start and end of a webapirequest lifestyle scope?
The scope for WebApiRequestLifestyle is created at the moment that Web API calls IDependencyResolver.BeginScope() and it ends once it calls Dispose() on the returned IDependencyScope instance.
In the past I noticed a few really weird quirks in Web APIs design that have to do with scoping and asynchonicity. For instance, Web API calls IDependencyScope.Dispose() after the async flow has already been finished. This means that at the time of the call to IDependencyScope.Dispose(), any data stored at the start of the request using CallContext.SetLogicalData can't be retrieved anymore at that point in time. So there is a gap between the end of the request and the disposal of the scope. Simple Injector depends on the availability of the CallContext during the request for resolving scoped instances.
What might be happening is that Web API calls your OnActionExecuted during this gap. Only few developers ever notice this quirk, since usually, during the time of the gap, all dependencies are already resolved. If however you are resolving services during that stage, things go wrong in Web API.

Resources