Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Start extremely long running processes through a REST request

I'm working at an automation firm so we create processes for industrial automation. Previously this automation was done on the machine side of things, but we're slowly transitioning to controlling the machines with c#.

On my current project the production for one day takes about 2 hours. The operators of the factory have a web interface that we created in c# using asp.net core MVC in which they can start/pause/stop this production process.

When starting the process we await a function in our controller that is basically a while loop that controls this 2h long production process.

The problem is now that when I send out the REST request to start the production this request takes 2h to complete, I would prefer this request immediately completes and the production process starts on the background of my asp.net core application.

First I thought I could just leave out the await and simply do this in my controller (simplified code):

_ = _productionController.StartLongProcess(); // This contains the while loop
return Ok();

But since _productionController is scoped and all its dependencies are as well, these immediately get disposed of when the method returns and I can't access my database anymore for example.

The process should be able to continuously talk to our database to save information about the production process in case something fails, that way we can always pick off where we left off.

My question to you is now, are we tackling this the wrong way? I imagine it's bad practice to start these long running processes in the asp.net controller.

How do I make sure I always have access to my DatabaseContext in this long running process even though the REST request has already ended. Create a separate scope only for this method?

like image 468
Bastien verschaete Avatar asked Jun 06 '19 08:06

Bastien verschaete


People also ask

What is a long running request?

A long-running request starts when either a transaction begins, or when a request is made to invoke a stateful service. When in this mode, the connection between the client and the server is maintained until either the transaction ends, or the client indicates that stateful processing is no longer required.

What is a long running process?

Long running basically means waiting! Typically long running means that the process is waiting most of the time. This is not done by blocking any threads but typically by persisting state to some storage mechanism. So the term “long lived” might be even easier to understand for some readers.


1 Answers

Starting ASP.NET Core 2.1, the right way to do this (within asp.net) is to extend BackgroundService (or implement IHostedService).

Incoming requests can tell the background service to start the long-running operation and return immediately. You'll of course need to handle cases where duplicate requests are sent in, or new requests are sent in before the existing request is completed.

The documentation page has an example where the BackgroundService reads commands of a queue and processes them one at a time.

How do I make sure I always have access to my DatabaseContext in this long running process even though the REST request has already ended. Create a separate scope only for this method?

Yes, create a separate scope.

My question to you is now, are we tackling this the wrong way? I imagine it's bad practice to start these long running processes in the asp.net controller.

We've done something similar in the past. As long as fault-tolerance (particularly w.r.t. app restarts) and idempotence are built into the long-running-operation's logic, you should be good to go.

like image 180
galdin Avatar answered Sep 27 '22 19:09

galdin