ASP.NET - Request a web page to unzip a file on the server
We are using SharpZipLib . We need to be able to unpack the files on the server and place them in a separate folder. The request to unpack the file will be made by the user from the web page. I think if the files are big enough it will take a long time to decompress. We don't want users to get stuck on the page, waiting for unpacking to continue browsing the site.
What's a good way to deal with this scenario: allocate another thread to take care of unpacking the file, create a separate Windows service that will decompress the files, or ... what?
What are the pros and cons of doing this through a separate thread or window service?
a source to share
Advantages of a separate process
Work performed in a separate process can be separated in time, as well as physically and from a security point of view, from the page stream. Split in Time: If you choose, you can buffer unwrap requests until "later" when the load is lower, and if you have spare CPU cycles to do so.
Also physically disconnected; for a large-scale system, you can have multiple worker processes, even deployed across multiple independent machines, doing this work asynchronously, and this level of processing can scale independently of the processing of the web page. There are bottlenecks in any system, and the advantage of distributed deployments is that you can scale individual workloads yourself to more efficiently remove bottlenecks.
I would argue that this latter benefit is only useful on a very large scale. In most cases, you will not have the same transaction volume that would benefit from an independent physical layer of scaling. This applies not only to your workload, but 98% of all workloads. The YAGNI principle applies to scalability as well.
Physical decoupling also allows disparate workloads (page flow and ZIP decompression) to be independently developed. In other words, suppose the work item was not a simple "unzip file," but something more complex, with a few steps and decision points along the way. Designing a worker processor in a separate process allows you to create and test a page flow independently of the workflow processing. This can be a good advantage if they have to develop on their own.
This physical decoupling is also good if the work items will flow through different channels. Let's say a web page isn't the only way for a worker to work. Let's say you have an ftp drop, web service, or machine controlled mailbox that can also receive production data. In this case, it would make sense to separate the processing of the workflow from the processing of the web page.
Finally, these things are decoupled from runtime security. In some web application server deployments, security rules prevent the web server from writing to disk — the web servers do not have writeable disk storage. A separate asynch workflow can be deployed on a separate part of the network, with a lot of storage, and possibly constrained by a separate set of security requirements. This may or may not apply to you.
Advantages of Threaded Processing
The advantage of doing the work in a separate thread is that it is much easier. The decoupling introduces complexity and cost. By managing work in a separate thread, you don't have any of the operational overhead of managing a separate process, possibly on a separate machine. No additional configuration, no new build / deployment step. There is no additional backup. No additional security identification to maintain. Messaging is not worth worrying about (outside of sending a stream).
You can opt for a slightly more complex workitem handling and, if necessary, do the work synchronously when the zipfile looks small enough. Suppose you set the response time threshold to 4 seconds - above that you need an asynchronous workload below 4 seconds, you do it "inline". Of course, you never know for sure how long a zipfile will take, but you could set up a good heuristic based on file size. This optimization is available to you whether you are using an external async process or a separate thread, but to be honest, it is easier to use the optimization when using a separate thread. Less extra work. So this is an advantage for a multi-threaded approach.
Nondifferentiators
If you choose to use the AJAX polling engine for workplace status notification, this will work with either a separate process or a separate thread. I don't know how you would track work items, but I would assume that when a particular work item (zip file?) Is complete, then you update a record somewhere - a file in the file system, a table in the database This update occurs if it is performed by a thread in the same process or by a separate process (Windows service). So the AJAX client that polls will just check the db table or filesystem anyway, and get notified of the workflow status in the same way, regardless of your architecture decision.
How to solve
The theory is interesting, but ultimately useless, without real work constraints.
Workload is one of the key items in the real world. You didn't say how big these zip files are, but I'm guessing they are "normal size". Something around 4 GB or less. It usually takes 20-60 seconds for such a zip file to unzip my laptop, but of course it will be smaller on a server with real storage and faster processor. You also haven't characterized concurrency transactions - how many of these things will happen at any given time. I guess the concurrency is not particularly high.
If so, I am taking a simpler approach to asynchronous flow. You do it in ASP.NET, I rely on the server OS. The CLR has good thread management and ASP.NET has good process scalability. This way, even under high loads, you will get good CPU utilization and scaling, without any fine tuning effort.
If work items were longer, say the order of hours or even days, and the time was unpredictable (for example, closing the stock order) - well, in this case, I'm leaning towards an asynchronous process. If the concurrency was in thousands per second, or again very unpredictable, this would recommend a separate process as well. If the failure modes were complex enough, I might want the work items to be in a separate process to manage. If the processing of the workitem is likely to change regularly (adding an extra step to suit changing business conditions), I might want it in a separate process.
But none of these things seem to be true in your case - unpacking zip files.
a source to share
The disadvantages of a separate stream include:
- When the page ends, there is no easy way to get notified of what another thread is doing.
- The application can be restarted at any time.
- It would be easy to accidentally start the process twice if the user submits the page twice.
- Multi-threaded code is difficult to debug.
Benefits of a separate stream:
- Less code
- It's easy to make fire and forget if the user doesn't need a notification when unpacking is complete.
- No extra work to install.
The advantages and disadvantages of a Windows service are roughly the opposite of the above.
a source to share
Personally, I've gone the route of a Windows service with messaging between them to make progress, like revert handle
to unzip, which can be used to monitor state.
However, you might also think that perhaps crush the thread to do this and it will happily run and the page will return.
a source to share