Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webapi 2 - how to properly invoke long running method async/in new thread, and return response to client

I am developing a web-api that takes data from client, and saves it for later use. Now i have an external system that needs to know of all events, so i want to setup a notification component in my web-api.

What i do is, after data is saved, i execute a SendNotification(message) method in my new component. Meanwhile i don't want my client to wait or even know that we're sending notifications, so i want to return a 201 Created / 200 OK response as fast as possible to my clients.

Yes this is a fire-and-forget scenario. I want the notification component to handle all exception cases (if notification fails, the client of the api doesn't really care at all).

I have tried using async/await, but this does not work in the web-api, since when the request-thread terminates, the async operation does so aswell.

So i took a look at Task.Run().

My controller looks like so:

public IHttpActionResult PostData([FromBody] Data data) {
    _dataService.saveData(data);
    //This could fail, and retry strategy takes time.
    Task.Run(() => _notificationHandler.SendNotification(new Message(data)));
    return CreatedAtRoute<object>(...);
}

And the method in my NotificationHandler

public void SendNotification(Message message) {
    //..send stuff to a notification server somewhere, syncronously.
}

I am relatively new in the C# world, and i don't know if there is a more elegant(or proper) way of doing this. Are there any pitfalls with using this method?

like image 937
Martin Hansen Avatar asked Feb 18 '16 09:02

Martin Hansen


2 Answers

It really depends how long. Have you looked into the possibility of QueueBackgroundWorkItem as detailed here. If you want to implement a very fast fire and forget you also might want to consider a queue to pop these messages onto so you can return from the controller immediately. You'd then have to have something which polls the queue and sends out the notifications i.e. Scheduled Task, Windows service etc. IIRC, if IIS recycles during a task, the process is killed whereas with QueueBackgroundWorkItem there is a grace period for which ASP.Net will let the work item finish it's job.

like image 168
Mark Walsh Avatar answered Nov 12 '22 15:11

Mark Walsh


I would take a look on Hangfire. It is fairly easy to setup, it should be able to run within your ASP.NET process and is easy to migrate to a standalone process in case your IIS load suddenly increases. I experimented with Hangfire a while ago but in standalone mode. It has enough docs and easy to understand API.

like image 2
Volodymyr Usarskyy Avatar answered Nov 12 '22 16:11

Volodymyr Usarskyy