Привет.
Стоит задача сделать API, под которым будет запускаться скриптик. Скрипт в свою очередь может выполняться очень и очень долго - от 90 секунд. API, как можно догадаться, должен отвечать моментально.
В качестве веб-севера будет выступать nginx с proxy на flask апликацию.
Как удалось выяснить, flask совсем не асинхронный.
Сразу возникала идея форкнуться и выполнять задачу в фоне.
Накидал для пробы:
def start():
pid1 = os.fork()
if pid1 == 0:
os.setsid()
x = 30
while x > 0:
sleep(1)
with open('/tmp/sleep.log', 'a') as fd:
pid = str(os.getpid())
print "child pid = ", pid
fd.write(pid + ' PID \n')
x -= 1
os._exit(0)
else:
print os.getpid()
while True:
pass
start()
В этом примере все замечательно работает. Создается новый процесс, задачка выполнятся в фоне. После завершения дочерний процесс умирает, родительский продолжает работать.
Попробовал перенести под flask:
@app.route('/api/start', methods=['POST'])
def start():
d1 = "DONE\n"
pid1 = os.fork()
if pid1 == 0:
os.setsid()
closer() #здесь закрываю все файловые дескрипторы унаследованные от родителя
x = 30
while x > 0:
sleep(1)
with open('/tmp/sleep.log', 'a') as fd:
pid = str(os.getpid())
print "child pid = ", pid
fd.write(pid + ' PID \n')
x -= 1
os._exit(0)
else:
print os.getpid()
return d1
Вот что происходит в этом примере:
username 6158 0.0 0.4 106528 26192 ? S 19:34 0:00 python -u /home/username/VCS/username/seek/lui/tcpdumper/dumper_api.py
username 6165 0.3 0.4 182876 26816 ? Sl 19:34 0:05 /usr/bin/python /home/username/VCS/username/seek/lui/tcpdumper/dumper_api.py
username 6262 0.0 0.0 0 0 ? Zs 19:34 0:00 [python] <defunct>
Дочерний процесс сразу становится зомби. Соответственно, в файл ничего не записывается.
Собственно, главный вопрос в том, почему так происходит.
Подскажите, какие еще варианты решения проблемы могут мне подойти.
Смотрел в сторону Tornado, subprocess ( его использовать нежелательно ).
Спасибо.