2015-04-20 13 views
7

Mam aplikację Flask działającą za Apache HTTPD. Apache jest skonfigurowany do posiadania wielu procesów podrzędnych.Jak wywołać funkcję, gdy Apache kończy proces Flask?

Aplikacja Flask tworzy plik na serwerze z nazwą pliku równą identyfikatorowi procesu. Kod wygląda mniej więcej tak:

import os 

@app.before_first_request 
def before_first_request(): 
    filename = os.getpid() 
    with open(filename, 'w') as file: 
     file.write('Hello') 

Gdy proces dziecko ginie/zakończony/zakończone chciałbym aplikację kolbę do usunięcia tego pliku.

To nie jest bardzo ważne, aby usunąć plik, ponieważ pliki te nie zajmują dużo miejsca, więc jeśli pojawią się dziwne błędy, nie muszę ich obsługiwać. Ale dla normalnego przepływu pracy, chciałbym mieć pewne czyszczenie, gdy Apache wyłączy proces Flask.

Każdy pomysł na najlepszy sposób na zrobienie tego?

Odpowiedz

6

Najlepszym sposobem dodania funkcji czyszczenia przed zakończeniem procesu kontrolowanego przez serwer Pythona (takiego jak aplikacja Flask działająca w kontekście serwera WSCI w Apache, a nawet lepiej, w Gunicorn za Apache) jest użycie procedury obsługi wyjścia atexit.

Opracowanie na oryginalnym przykład tutaj jest dodanie obsługi wyjścia robi porządki z .pid pliku:

import atexit 
import os 

filename = '{}.pid'.format(os.getpid()) 

@app.before_first_request 
def before_first_request(): 
    with open(filename, 'w') as file: 
     file.write('Hello') 

def cleanup(): 
    try: 
     os.remove(filename) 
    except Exception: 
     pass 

atexit.register(cleanup) 
+1

Apache/mod_wsgi pewno zawsze stara się zapewnić, że wywołania zwrotne atexit są wywoływane, nawet w przypadkach, gdy proces Musi zostać zamknięty z powodu takich warunków, jak czas oczekiwania, itp. W gunicorn nie ma tak dobrych gwarancji, a ty musiałbyś być o wiele ostrożniejszy w używaniu atexitu pod gunicornem, jak w różnych przypadkach, w których nie byłoby to wywołane. W obu przypadkach nie powinieneś polegać na nim, a aplikacja powinna być odporna na plik istniejący w następnym uruchomieniu, jeśli nie istnieje. Oddzielne zadanie do usunięcia, które może wymagać, jak opisuje inna odpowiedź. –

+0

Dla niektórych innych serwerów WSGI zwroty zwrotne nie mogą być w ogóle wywoływane. Uważam, że tak jest w przypadku uWSGI, chyba że zmusisz go do korzystania z jednego tłumacza, ponieważ nie podejmuje on kroków w celu zapewnienia wywołania zwrotnego w sub-interpretatorach. Musiałby podjąć specjalne kroki, ponieważ Python nie wywołuje atexitych wywołań zwrotnych w podinterpretatorach, a Apache/mod_wsgi używa specjalnych sztuczek, aby upewnić się, że są. –

+0

świetne informacje @GrahamDumpleton! Dzięki za to, a wyjątek chroni przed wywołaniem '' os.remove''. –

2

Najprostszym sposobem byłoby obsłużenie tego poza procesem Apache. Nie ma gwarancji, że proces zawsze usunie pliki (na przykład, jeśli ponownie uruchomisz żądanie pośrednie serwera apache).

Podejście, które podjąłem w przeszłości, to użycie cron. Napisz mały skrypt gdzieś w swoim repozytorium i wykonuj go zgodnie z harmonogramem (codziennie zwykle działa). Skrypt ten może po prostu usunąć wszystkie pliki w directorty, które są starsze niż 24 godziny, więc zawsze będziesz miał okienko o wartości 1 dni.

Ma to dwie zalety:

  1. jesteś w całkowitą kontrolę nad scenariuszem, i może korzystać z dowolnego języka, który chcesz.
  2. Możesz robić fantazyjne rzeczy z tymi plikami. Możesz je skompresować i przechowywać w innym miejscu, usuwać je lub wykonywać na nich analizy. Całkowicie do Ciebie!

Większość języków skryptowych ma niewielką klasę opakowania, która może być bardziej przyjazna dla użytkownika cron. Popularny dla Ruby jest whenever.

Powiązane problemy