0

I have an ASP.Net app in which I am creating a unique user file when user logs in and then delete this file when user logs out. Also, for each request that user submits during his/her session, this file is updated with some data. The code I am using is as below. All file handling is done using static methods of System.IO.File class, which will always close and dispose file connections automatically.

Each user file is only accessed by a single thread at a time, which leads me to believe that above file handling should be safe for multi-user scenario.

I am worried that when there are many users logged into the ASP.Net app, then this file handling may cause some issues, but not sure.

Question: What could be possible issues with file handling in above scenario in a multi-user scenario, OR it appears safe? There could be large number of users like 500 or more using the ASP.Net app.

//create unique file on login
File.WriteAllText(userFileStoragePath, userData);

//update unique file on every request
File.WriteAllText(userFileStoragePath, userData);

//delete file on log out
File.Delete(userFileStoragePath);
Sunil
  • 20,653
  • 28
  • 112
  • 197
  • Why a file, why not a database (SQLite)? – Lloyd Jul 20 '16 at 16:28
  • @Lloyd i think that the question is about - why a database would be better – enkryptor Jul 20 '16 at 16:30
  • 1
    I guess you could make it work, it's just that using a database would likely be faster. It also won't work if you ever need to scale you application across multiple machines. – kamilk Jul 20 '16 at 16:32
  • I have tried SQLite which is an excellent option. But there is only one issue with SQLite and that is it locks the database file exclusively for each write, so writes will become slower and so will reads when there are many users online in my ASP.Net app. On the other hand, writing to a unique file would overcome this limitation. – Sunil Jul 20 '16 at 16:32
  • Actually I see no reason to handle user requests with files. You create a file every time user logs in and delete it every time user logs off. It seems the information isn't really stored. It would be faster to handle it in memory, not using files nor databases.. – enkryptor Jul 20 '16 at 16:33
  • I do not want to consume memory for this since I have disabled sessions in my ASP.Net app. And storing in ASP.Net cache is an option in my app but it's unreliable since ASP.Net automatically recycles cache items, if it runs low in memory. – Sunil Jul 20 '16 at 16:34
  • A database *server* (SQL Server/Express, MySQL etc) is designed to do this in an efficient, thread and concurrency safe way. – Alex K. Jul 20 '16 at 16:38
  • Answering the question - the possible issue is the performance one. Especially in a low-memory system, where file operations can't be properly cached. I can't believe you get better performance with files comparing with a database solution - that seems like a bad database design (since the database shouldn't be locked on every write operation). – enkryptor Jul 20 '16 at 16:39
  • @AlexK., I agree with you, but do you see any issues with the file handling I am doing? – Sunil Jul 20 '16 at 16:39
  • 2
    "I do not want to consume memory for this" - why? Because of the performance? But memory is a way faster than disk. And how much memory do you really save this way? How did you measure it? – enkryptor Jul 20 '16 at 16:41
  • It seems messy to have unnecessary disk IO, a pain to back up and maintain historical data. See [database vs. flat files](http://stackoverflow.com/questions/2356851/database-vs-flat-files). That said if you don't want to use a caching service use Session Storage, that will not be flushed by the server during an active session. – Alex K. Jul 20 '16 at 16:43
  • @enkryptor, The database design is not responsible for SQLite being exclusively locked, but that's how SQLite works. Note that SQLite is being used as an embedded database and not as client-server relational database. You can verify this fact from SQLite website: https://www.sqlite.org/faq.html. The website says: `When any process wants to write, it must lock the entire database file for the duration of its update. But that normally only takes a few milliseconds. Other processes just wait on the writer to finish then continue about their business.` – Sunil Jul 20 '16 at 16:43
  • @AlexK., I have sessions disabled in my ASP.Net app, and also there is no requirement to back up these user files since they are only useful for a single user session. – Sunil Jul 20 '16 at 16:45
  • 1
    @Sunil are you handling users not explicitly logging out? That's a must, otherwise you'll end up with an accumulating set of files. – p e p Jul 20 '16 at 16:46
  • @pep, That's a good point and yes I have a Hangfire job that runs in the background once a day to delete such files, where user did not explicitly logout. – Sunil Jul 20 '16 at 16:47
  • @enkryptor, As I explained in a comment that I cannot use memory in ASP.Net because sessions are disabled in my ASP.Net app. This means the only other memory option I have is ASP.Net cache, but cache items can be removed automatically by ASP.Net in situations when its running low on memory. So ASP.Net cache is not reliable option for me. – Sunil Jul 20 '16 at 16:50
  • Wouldn't it be better to store the state client-side and keep the server stateless? – enkryptor Jul 20 '16 at 16:56
  • @enkryptor, Yes that is an option, but because the data I am storing is sensitive information, so I decided to store it on server-side rather than on client-side. Data on server-side is more secure than data on client-side which can be stolen. – Sunil Jul 20 '16 at 16:59
  • "it locks the database file exclusively for each write, so writes will become slower" - did you measure it, or do you believe it would be slower? Because, you know, despite you can open multiple files logically, the physical hard drive is being used exclusively as well. – enkryptor Jul 20 '16 at 17:02
  • What happens if the file already exists? – enkryptor Jul 20 '16 at 17:03
  • 1
    @Sunil Regardless of whether this is a good design or not, I don't believe you'll be even close to hitting IO limitations. Even if all 500 of your users do something at once, that means 500 file writes at one "instant". Performance depends on most largely on: size of text being written to file each time, your particular disk performance, expected # of requests per user per period of time. But most likely, you are going to have minimal traffic into those files in any given time frame. Also, not sure if this is what you intend, but 'File.WriteAllText' will overwrite the file each time. – p e p Jul 20 '16 at 17:05
  • @p e p, Yes, I intend to either create the file or overwrite its contents. I think it should be good performance if the disk size is large enough , since each file is unique so file concurrency is ZERO for each file. Also, I am only storing a string that is a maximum of 1000 characters in each user file. – Sunil Jul 20 '16 at 17:09
  • @enkryptor, If file exists then the code `File.WriteAllText` overwrites it. – Sunil Jul 20 '16 at 17:10
  • "the data I am storing is sensitive information, so I decided to store it on server-side" - the point was to save the STATE client-side, not the respective information. For instance, if a client sends their credit card number - you can store it server-side, in your database. That number doesn't change when the client logs off. It exists out of the session context, it won't change, so it is not a part of the state. The constantly changing state should be stored client-side (e.g. step of a checkout process). – enkryptor Jul 20 '16 at 17:11
  • @enkryptor, In our ASP.Net app we do have sensitive information that is not credit card data and which I cannot disclose. – Sunil Jul 20 '16 at 17:13
  • @pep, Do you want to post your comment as an answer since your explanation seems correct to me? – Sunil Jul 23 '16 at 20:49

0 Answers0