2012-09-25 17 views
40

Chciałbym wysłać prośbę miejscowego Spoczywaj w app kolby, tak:Kolba broken pipe wniosków

from flask import Flask, url_for, request 
import requests 

app = Flask(__name__) 

@app.route("/<name>/hi", methods=["POST"]) 
def hi_person(name): 
    form = {"name": name} 
    return requests.post(url_for("hi", _external=True), data=form) 

@app.route("/hi", methods=["POST"]) 
def hi(): 
    return 'Hi, %s!' % request.form["name"] 

Wysyłanie curl -X POST http://localhost:5000/john/hi powoduje, że cała aplikacja kolba do zamrożenia. Kiedy wysyłam sygnał zabicia, pojawia się błąd zepsutej rury. Czy istnieje sposób, aby zapobiec zamarznięciu kolby?

Odpowiedz

89

Uruchom aplikację do butelkowania pod odpowiednim serwerem WSGI obsługującym równoległe żądania (być może gunicorn lub uWSGI) i to zadziała. Przy opracowywaniu, włącz wątki w kolbie dostarczonego z serwerem:

app.run(threaded=True) 

jednak pamiętać, że serwer Kolba nie jest zalecany do użytku produkcyjnego.

Co się dzieje, że przy użyciu żądań wysyłanych jest żądanie drugie zapytanie do aplikacji do kolb, ale ponieważ wciąż jest zajęty przetwarzaniem pierwszego, nie odpowie na to drugie żądanie, dopóki nie zostanie wykonane z tym pierwszym żądaniem .

Nawiasem mówiąc, w Pythonie 3 implementacja socketserver obsługuje rozłączanie z większą wdziękiem i nadal działa, a nie ulega awarii.

+0

+1, zdecydowanie))><(( –

+2

uruchomić aplikację WSGI gwintowaną, ale pojawia się pęknięcia przewodu anyways: app.run (debug = true, gwintowany = True, host = 0.0. 0.0 ', port = 8080) – loretoparisi

+1

@loretoparisi: Bez szczegółów niemożliwych do zdiagnozowania Uruchomienie kodu w pytaniu za pomocą linii 'app.run()' i dostosowanego polecenia 'curl' działa dobrze. Być może powinieneś opublikować nowy pytanie? –

16

W grze jest kilka rzeczy, a ja postaram się do nich odnieść w pojedynkę.

Najpierw prawdopodobnie korzystasz z serwera rozwoju zabawek. Ten serwer ma wiele ograniczeń; głównie wśród tych ograniczeń jest to, że może obsłużyć tylko jedno żądanie na raz. Kiedy tworzysz drugie żądanie podczas pierwszego żądania, zamykasz swoją aplikację: funkcja requests.post() czeka na odpowiedź Flask, ale sama Flask czeka na powrót do post()! Rozwiązaniem tego problemu jest uruchomienie aplikacji WSGI w środowisku wielowątkowym lub wieloprocesowym. Wolę od tego http://twistedmatrix.com/trac/wiki/TwistedWeb, ale jest jeszcze kilka innych opcji.

Z tym na uboczu ... To jest antypapier. Niemal na pewno nie chcesz wywoływać wszystkich narzutów żądania HTTP tylko po to, aby dzielić funkcjonalność między dwoma widokami. Prawidłową rzeczą do zrobienia jest refaktor, aby mieć oddzielną funkcję, która wykonuje tę wspólną pracę. Nie mogę naprawdę odmienić twojego konkretnego przykładu, ponieważ to, co masz, jest bardzo proste i tak naprawdę nie zasługuje na dwa widoki. Co dokładnie chcesz zbudować?

Edytuj: Komentarz pyta, czy tryb wielowątkowy na serwerze stdlib dla zabawki byłby wystarczający do utrzymania zakleszczenia. Powiem "może". Tak, jeśli nie ma żadnych zależności, które sprawiają, że oba wątki nie robią postępu, a oba wątki wykonają wystarczające postępy w celu zakończenia zadań sieciowych, żądania zakończą się poprawnie. Jednak ustalenie, czy dwa wątki będą się nawzajem zakleszczyć, jest nierozstrzygalne (dowód pomijany jako rozwarty) i nie jestem skłonny powiedzieć na pewno, że serwer stdlib może zrobić to dobrze.

+0

+1 zgłoszenie prośby w ramach obsługi żądania jest w większości przypadków złe, prośba http do siebie ... ick –

+0

Wpadłem na ten problem, ponieważ łączyłem dwie usługi internetowe które wcześniej działały jako oddzielne procesy. Jedyny interak między tymi dwiema usługami był POST. Połączyłem je w ten sam proces, wykorzystując plany i bum, zamroziły. Tak więc, trochę więcej refaktoryzacji jest w porządku. – jfocht

+0

@Corbin, więc czy opcja threaded = True jest niewystarczająca jak TwistedWeb w przypadku wieloprocesowego wykonywania wielowątkowego przy każdym żądaniu? – loretoparisi

3

Błąd, który spowodował awarię, to fixed in Version 0.12, wydany 21 grudnia 2016 r. Tak! Jest to ważna poprawka, na którą wielu czekało.

Od changelogu Kolby:

  • Cofnij zmiany zachowań, które złożyły crash serwera dev zamiast zwracania Internal Server Error (wyciągnąć wniosek # 2006).
+0

Tak! Dzięki za wskazówkę. Aktualizacja do skrzynki 0.12 rozwiązała problem. Teraz te błędy są po prostu rejestrowane bez awaryjnego serwera. –

Powiązane problemy