instalar app python ubuntu python-2.7 flask

python - app - install pip ubuntu



Frasco de tubería rota con solicitudes (3)

Me gustaría enviar una solicitud REST local en una aplicación de matraz, como esta:

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"]

El envío curl -X POST http://localhost:5000/john/hi hace que se congele toda la aplicación del matraz. Cuando envío una señal de muerte, aparece un error de tubería roto. ¿Hay alguna manera de evitar que el matraz se congele aquí?


Aquí hay varias cosas en juego, y trataré de abordarlas una a la vez.

Primero, probablemente estés usando el servidor de desarrollo de juguetes. Este servidor tiene muchas limitaciones; principalmente entre estas limitaciones es que solo puede manejar una solicitud a la vez. Cuando crea una segunda solicitud durante su primera solicitud, está bloqueando su aplicación: ¡La función requests.post() está esperando que Flask responda, pero Flask está esperando que la post() vuelva! La solución a este problema en particular es ejecutar su aplicación WSGI en un entorno multiproceso o multiproceso. Prefiero http://twistedmatrix.com/trac/wiki/TwistedWeb para esto, pero hay varias otras opciones.

Con eso fuera del camino ... Este es un antipatrón. Es casi seguro que no desea invocar todos los gastos generales de una solicitud HTTP solo para compartir alguna funcionalidad entre dos vistas. Lo correcto es refactorizar para tener una función separada que haga ese trabajo compartido. Realmente no puedo refactorizar tu ejemplo particular, porque lo que tienes es muy simple y realmente ni siquiera merece dos puntos de vista. ¿Qué querías construir, exactamente?

Editar: Un comentario pregunta si el modo multiproceso en el servidor stdlib de juguete sería suficiente para evitar que se produzca el interbloqueo. Voy a decir "tal vez". Sí, si no hay ninguna dependencia que impida que ambos subprocesos progresen y ambos subprocesos progresan lo suficiente para finalizar sus tareas de red, las solicitudes se completarán correctamente. Sin embargo, determinar si dos hilos se estancarán entre sí es indecidible (prueba omitida como obtusa) y no estoy dispuesto a decir con certeza si el servidor stdlib puede hacerlo bien.


Ejecute su aplicación de matraz bajo un servidor WSGI adecuado capaz de manejar solicitudes concurrentes (tal vez gunicorn o uWSGI ) y funcionará. Durante el desarrollo, habilite los hilos en el servidor proporcionado por Flask con:

app.run(threaded=True)

pero tenga en cuenta que el servidor Flask no se recomienda para uso en producción.

Lo que sucede es que al usar las solicitudes está haciendo una segunda solicitud a su aplicación de matraz, pero como todavía está ocupado procesando la primera, no responderá a esta segunda solicitud hasta que no se realice con esa primera solicitud.

A propósito, en Python 3, la implementación de socketserver maneja la desconexión de forma más elegante y continúa funcionando en lugar de bloquearse.


El error que causó el bloqueo se corrigió en la versión 0.12 , publicado el 21 de diciembre de 2016. ¡Sí! Esta es una solución importante que muchos han estado esperando.

Desde el registro de cambios de Flask:

  • Revertir un cambio de comportamiento que provocó la falla del servidor de desarrollo en lugar de devolver un error interno del servidor (solicitud de extracción n.º 2006).