1

I'm writing a 200k JSON file from a console app to a web folder of an IIS box every 10 min. Mobile clients regularly pick up their data from this file via IIS.

Wondering what'd happen if IIS hits the file while its being written. This question says File.WriteAllText uses FileShare.Read - so someone could FEASIBLY read it while it's being written.

I'm about to test this with a v. big file and see how IIS handles a request in the middle of the write. I remember a trick in UNIX to write to a version file json.201207231033 and update the symlink to json.

Does anyone else have experience with this?

Community
  • 1
  • 1
  • The answer is really that you should lock the file while you're writing to it, if you really want to avoid any problems. http://stackoverflow.com/a/6805806/101827 – Mike Atlas Jul 23 '12 at 02:14
  • What will IIS do if it hits a file that's locked? Serve down some 400 error? That wouldn't be ideal – TesterTurnedDeveloper Jul 23 '12 at 02:41
  • We're talking about two different kinds of locking. I'm talking about a [mutual-exclusion](http://en.wikipedia.org/wiki/Lock_%28computer_science%29) [lock](http://msdn.microsoft.com/en-us/library/c5kehkcz%28v=vs.71%29.aspx), which is something that you could use to block retrieval temporarily while you're doing a write, which would not cause an error to your clients. You probably need to implement a layer in between your clients and the file, if they're retrieving it directly. – Mike Atlas Jul 23 '12 at 02:53
  • i can see where the confusion was. I'm writing the json file from a console app. updated my question. – TesterTurnedDeveloper Jul 23 '12 at 02:55
  • Honestly, that is a really strange way to publish data on the web. Most web applications execute code on the web server on a request, which then goes and retrieves fresh data. Why is it designed like this, exactly? – Mike Atlas Jul 23 '12 at 02:58
  • can't give away too much details about my employer's site. let's say i want to display aggregate data from share prices on a mobile device - whenever it fires up i get the share prices from the server, and the user can click a refresh button to see updated prices. don't want to perform the aggregate query with every request (it makes a few min to run). the console app could dump the json into a SQL database, and have the webserver read from that (seems like a lot of overhead to me) – TesterTurnedDeveloper Jul 23 '12 at 03:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/14292/discussion-between-mike-atlas-and-testerturneddeveloper) – Mike Atlas Jul 23 '12 at 16:15

1 Answers1

1

Here's how I would tackle your problem with the following pseudocode in an ASP.NET page. You're going to cache the results in memory, and refresh the data when it's been in the cache longer than 10 minutes.

    var data = Cache["data"];
    if (data.Timestamp <= 
        DateTime.Now.Substract(TimeSpan.FromMinutes(10)))
    {
            //Refresh cache with new data when it's older than 10min.
            // You could hypothetically do this in a separate thread
            // if you wanted to do so.      
            data = new Data(GetFromDb(), timestamp);
            Cache["data"] = data;

            return Cache["data"];
    }
    else
    {
            //Use existing data
            return Cache["data"];
    }            

Here's a reference on how to use IIS's runtime cache.

If you wanted to ensure your cached value is always fresh, you could create a job that hits this page every 10 minutes, rather than your current solution's approach.

There are plenty of other ways you could go about caching the data, but using the OS file system isn't really the optimal one.

Community
  • 1
  • 1
Mike Atlas
  • 8,193
  • 4
  • 46
  • 62
  • interested to know how the cache can be updated from another thread. add a route /UpdateCache that a scheduled task hits every 10 min? or have the console app / website use the 4.0 System.Runtime.Caching classes. will suss it out – TesterTurnedDeveloper Jul 24 '12 at 00:10