1

I have a Python HTTP server, on a certain GET request a file is created which is returned as response afterwards. The file creation might take a second, respectively the modification (updating) of the file.

Hence, I cannot return immediately the file as response. How do I approach such a problem? Currently I have a solution like this:

 while not os.path.isfile('myfile'):
      time.sleep(0.1)
 return myfile

This seems very inconvenient, but is there a possibly better way?

A simple notification would do, but I don't have control over the process which creates/updates the files.

Erandir
  • 389
  • 1
  • 3
  • 7

4 Answers4

0

Something like this will remove the os call:

while updating:
    time.sleep(0.1)
return myfile

...

def updateFile():
    # updating file

    updating = false
ATOzTOA
  • 34,814
  • 22
  • 96
  • 117
  • *A simple notification would do, but I don't have control over the process which creates/updates the files.* – Erandir Jan 04 '13 at 06:40
0

Implementing blocking io operations in synchronous HTTP requests is a bad approach. If many people run the same procedure simultaneously you may soon run out of threads (if there is a limited thread pool). I'd do the following:

A client requests the file creation URI. A file generating procedure is initialized in a background process (some asynchronous task system), the user gets a file id / name in the HTTP response. Next the client makes AJAX calls every once a while (polling), to check if the file has been created/modified (seperate file serve/check-if-exists URI). When the file is finaly created, the user is redirected (js window.location) to the file serving URI.

This approach will require a bit more work, but eventually it will pay off.

Krzysztof Rosiński
  • 1,488
  • 1
  • 11
  • 24
0

You can try using os.path.getmtime, this would check the modification time of the file and return if it's less than 1 sec ago. Also I suggest you only make a limited amount of tries or you will be stuck in an infinite loop if the file doesn't get created/modified. And as @Krzysztof Rosiński pointed out you should probably think about doing it in a non-blocking way.

import os
from datetime import datetime
import time

for i in range(10):
    try:
        dif = datetime.now()-datetime.fromtimestamp(os.path.getmtime(file_path))
        if dif.total_seconds() < 1:
            return file            
    except OSError:            
        time.sleep(0.1)
root
  • 76,608
  • 25
  • 108
  • 120
0

You could use Watchdog for a nicer way to watch the file system?

Alex L
  • 8,748
  • 5
  • 49
  • 75