0

EDIT: Context

I have to develop a web asp.net application which will allow user to create "Conversion request" for one or several CAO files.

My application should just upload files to a directory where I can convert them.

I then want to have a service that will check the database updated by the web application to see if a conversion is waiting to be done. Then I have to call a batch command on this file with some arguments.

The thing is that those conversion can freeze if the user give a CAO file which has been done wrongly. In this case, we want the user or an admin to be able to cancel the conversion process.

The batch command use to convert is a third party tool that I can't change. It need a token to convert, and I can multithread as long as I have more than one token available. An other application can use those token at the same moment so I can't just have a pre-sized pool of thread according to the number of token I have.

The only way I have to know if I can convert is to start the conversion with the command and see if in the logs it tells me that I have a licence problem which mean either "No token available" or "Current licence doesn't accept the given input format". As I allow only available input formats on the web application, I can't have the second problem.

The web application is almost done, I mean that I can upload file and download results and conversion logs at the end. Now I need to do the service that will take input files, convert them, update convert status in database and lastly add those files in the correct download dirrectory.


I have to work on a service which will look in a database at a high frequency (maybe 5 or 10 seconds) if a row is set as "Ready to convert" or "Must be canceled".

If the row is set to "ready to convert" I must try to convert it, but I do it using a third party dll that have a licence token system that allow me to do only 5 converts simultaneously atm.

If the row is set to "Must be canceled" I must kill the conversion because it's either freeze and the admin had to kill it or because the user canceled his own task.

Also, conversion times can be very long, from 1 or 2 seconds to several hours depending on the file size and how it has been created.

I was thinking about a pooling system, as I saw here :

Stackoverflow answer

Pooling system give me the advantage to isolate the reading database part to the conversion process. But I have the feeling that I loose a kind of control on background process. Which is maybe juste because I'm not used to them.

But I'm not very used to services and even if this pool system seems good, I don't know how I can cancel any task if needed ?

The tool I use to convert work as a simple batch command that will just return me an error if no licence are available now, but using a pool how can I make the convert thread wait for the convert to be done if No licence are available is a simple infinite while loop an appropriate answer ? It seems quite bad to me.

Finally, I can't just use a "5 threads pool" as thoses licences are also used by 2 others applications which doesn't let me know at any time how many of them are available.

The idea of using pool can also be wrong, as I said, I'm not very used to services and before starting something stupid, I prefer ask abotu the good way to do it.

Moreover, about the database reading/writing, even if I think that the second option is better, should I:

  • Use big models files that I already use on my ASP.NET web application which will create a lot of objects (one for each row as it's entities models).

  • Don't use entities models but lighter models which will be less object entities oriented but will probably be less ressources demanding. This will also be harder to maintain.

So I'm more asking about some advices on how I should do it than a pure code answer, but some example could be very useful.

EDIT: to be more precise, I need to find a way to:

(For the moment, I stay with only one licence available, I will evolve it later if needed) Have a service that run as a loop and will if possible start a new thread for the given request. The service must still be running as the status can be set to "Require to be cancel".

At the moment I was thinking about a task with a cancellation token. Which would probably achive this.

But if the task find that the token isn't currently available, how can I say to my main loop of the service that it can't process now ? I was thinking about having just an integer value as a return where the return code would be an indicator on the ending reason: Cancellation / No token / Ended... Is that a good way to do ?

Grégory L
  • 612
  • 6
  • 17
  • *"look in a database at a high frequency (maybe 5 or 10 seconds)"* [cries internally] –  Dec 12 '17 at 14:15
  • @Will As I said, I'm a beginner in services, so it would be better to explain why you consider this as a bad practice ;) – Grégory L Dec 12 '17 at 14:17
  • It's a bad practice, one that many of us are forced to use for various reasons, and at sub-second frequencies. *[crying internally intensifies]* –  Dec 12 '17 at 15:08
  • @Will I quite easily understand that's pretty a pretty bad one indeed, but is there any other option that could help to avoid this ? – Grégory L Dec 12 '17 at 15:10

1 Answers1

1

What I'm hearing is that the biggest bottleneck in your process is the conversion... pooling / object mapping / direct sql doesn't sound as important as the conversion bottleneck.

There are several ways to solve this depending on your environment and what your constraints are. Good, fast, and cheap... pick 2.

As far as "best practice" go, there are large scale solutions (ESBs, Message Queue based etc), there are small scale solutions (console apps, batch files, powershell scripts on Windows scheduler, etc) and the in-between solutions (this is typically where the "Good Enough" answer is found). The volume of the stuff you need to process should decide which one is the best fit for you.

Regardless of which you choose above...

My first step will be to eliminate variables...

  • How much volume will you be processing? If you wrote something that's not optimized but works, will that be enough to process your current volume? (e.g. a console app to be run using the Windows Task Scheduler every 10 - 15 seconds and gets killed if it runs for more than say 15 minutes)

  • Does the third party dll support multi-threading? If no, that eliminates all your multi-threading related questions and narrows down your options on how to scale out.

You can then determine what approach will fit your problem domain...

  • will it be the same service deployed on several machines, each hitting the database every 10-15 seconds?, or
  • will it be one service on one machine using multi-threading?
  • will it be something else (pooling might or might not be in play)?

Once you get the answer above, the next question is.

  • will the work required fit within the allocated budget and time constraint of your project? if not, go back to the questions above and see if there questions above that you can answer differently that would change the answer to this question to yes.

I hope that these questions help you get to a good answer.

Goose
  • 546
  • 3
  • 7
  • Thanks for your answer! Indeed, the main problem is about the conversion. I'll update the main post to give more information about the entire process. – Grégory L Dec 13 '17 at 09:22