views:

30

answers:

3

On my site a user may upload a file (pic, zip, audio, video, whatever). He then may decide to replace it with a newer revision. This user may upload a file, make a post then decide to put up a new revision replacing the old (lets say its a large zip or tar.gz file). Theres a good chance people may be downloading it if he sent out an email or even im for the home user.

Problem. I need to replace the file and people may be downloading and it may be some minutes before it is deleted. I dont want my code to stall until i cant delete or check every second to see if its unused (especially bad if another user can start and he takes long creating a cycle).

How do i delete the file while users are downloading the file? i dont care if they stop i just care that the file can be replaced and new downloads are the new revision.

+4  A: 

What about referencing the files indirectly?

A mapping script, maps a virtual file entry from your site to a real file . If the user wants to upload a new revision of his file you just update the mapping, not the real file.

You can install a daily task that scans all files and deletes all files without a mapping and without open connections.

lajuette
Or put the mapping in a database.
Aaron Digulla
I still like to delete them. I would have to read the db everytime a file is accessed and i am planning to host these files on other servers instead of just my main one. And if they are not on lan (different co) it would increase lag or i will need a copy on every network which will add write slave complexities.
acidzombie24
The queries you need to execute should be *very fast*, because they can be cached.The layer of abstraction provided by a script, that delivers the file (instead of accessing it directly) can be a great advantage. You can vary the way you store the file, make your architecture pluggable.
lajuette
+3  A: 

lajuette's answer is right, the easiest solution is to work around the file locking altogether:

  1. When a user uploads file foo.zip, internally store it as foo-v1.zip.
  2. Create a mapping file somewhere (database, code, whatever) that maps foo.zip to foo-v1.zip.
  3. Rather than exposing a direct link to the file, expose a link to a service that gets the file: mysite.com/Download?foo.zip or something. This service uses the mapping to determine which version of the file to send to the client.
  4. When a new version is uploaded, create foo-v2.zip and update the mapping file.

It wouldn't be that hard to write a scheduled task that cleans up old, un-mapped files.

Seth Petry-Johnson
hmm, ok i'll consider it but i'll wait for more answers before accepting. IIRC linux this would be no problem. Right now my server supports url rewriting so i wouldnt need a /download?foo.zip
acidzombie24
@acidzombie24: I'm not a 'nix guy, but could you use symbolic links to do this? e.g. create a symlink for `foo.zip` that points to the latest version of a file. When a new file comes in, just update the symlink to point to the new version? Still still avoids the locking problem because _new_ requests will automatically go to the newest version of the file, allowing you to easily delete the older version of the file once all requests for it have completed.
Seth Petry-Johnson
excellent idea. My server is windows so i could possibly do that. Have everything as shortcuts and change where the shortcut points to. I think i'll accept this. -edit- yes i will. I cant think of any problems. url rewrites allow the file to be anything i want. It doesnt even matter if the jpg or zip ends with .lnk. I cant see windows locking and the only thing thats left is to actually write the code and test the locking + replacing and i'm done. anyways great answer. accepted.
acidzombie24
+1  A: 

If your oppose to a database and If the filenames are in a fix format (such as user/id.ext) you could append the id with a revision number and enumerate the folder using a pattern (user/id-*) and use the latest revision.

acidzombie24

related questions