Werkzeug: Werkzeug trava após gravar em um tubo fechado

Criado em 20 jun. 2016  ·  41Comentários  ·  Fonte: pallets/werkzeug

Tenho um servidor Werkzeug em execução no NGINX. Quando um cliente se desconecta enquanto espera a resposta do servidor Werkzeug, o NGINX fecha o pipe para o Werkzeug. Quando o programa Python grava a resposta em Werkzeug, ocorre a seguinte exceção e Werkzeug falha:

Traceback (última chamada mais recente):
Arquivo "server.py", linha 81, em
app.run (host = args.host, port = args.port, debug = False)
Arquivo "/usr/local/lib/python2.7/dist-packages/flask/app.py", linha 843, em execução
run_simple (host, porta, self, ** opções)
Arquivo "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", linha 694, em run_simple
interno()
Arquivo "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", linha 659, no interior
srv.serve_forever ()
Arquivo "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", linha 499, em serve_forever
HTTPServer.serve_forever (self)
Arquivo "/usr/lib/python2.7/SocketServer.py", linha 238, em serve_forever
self._handle_request_noblock ()
Arquivo "/usr/lib/python2.7/SocketServer.py", linha 297, em _handle_request_noblock
self.handle_error (solicitação, client_address)
Arquivo "/usr/lib/python2.7/SocketServer.py", linha 295, em _handle_request_noblock
self.process_request (request, client_address)
Arquivo "/usr/lib/python2.7/SocketServer.py", linha 321, em process_request
self.finish_request (solicitação, client_address)
Arquivo "/usr/lib/python2.7/SocketServer.py", linha 334, em finish_request
self.RequestHandlerClass (request, client_address, self)
Arquivo "/usr/lib/python2.7/SocketServer.py", linha 651, no init
self.finish ()
Arquivo "/usr/lib/python2.7/SocketServer.py", linha 710, finalizado
self.wfile.close ()
Arquivo "/usr/lib/python2.7/socket.py", linha 279, próximo
self.flush ()
Arquivo "/usr/lib/python2.7/socket.py", linha 303, alinhado
self._sock.sendall (ver [write_offset: write_offset + buffer_size])
socket.error: [Errno 32] Tubo quebrado

Há alguma opção de configuração que estou perdendo para evitar que ele trave? Normalmente, todas as exceções são capturadas e um erro 500 é retornado, com o servidor permanecendo ativo.

Comentários muito úteis

Guiado pelo recente commit de correção, consegui corrigir esse problema chamando app.run com passthrough_errors = False. YMMV

Todos 41 comentários

Use um servidor WSGI de produção, como Gunicorn ou uWSGI, não o servidor de desenvolvimento Werkzeug.

Tenho um problema muito semelhante, exceto que estou usando o servidor de desenvolvimento Werkzeug para desenvolvimento (que é, AFAICT, seu uso pretendido), ou seja, com o navegador conectado diretamente à porta 5000.

O erro acontece várias vezes por hora, forçando uma reinicialização manual do servidor para continuar o desenvolvimento.

Aqui está um traceback:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 659, in inner
    srv.serve_forever()
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 499, in serve_forever
    HTTPServer.serve_forever(self)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 238, in serve_forever
    self._handle_request_noblock()
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 297, in _handle_request_noblock
    self.handle_error(request, client_address)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 655, in __init__
    self.handle()
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 216, in handle
    rv = BaseHTTPRequestHandler.handle(self)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 251, in handle_one_request
    return self.run_wsgi()
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 193, in run_wsgi
    execute(self.server.app)
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 186, in execute
    write(b'')
  File "/Users/fermigier/envs/extranet-spr/lib/python2.7/site-packages/werkzeug/serving.py", line 152, in write
    self.send_header(key, value)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 401, in send_header
    self.wfile.write("%s: %s\r\n" % (keyword, value))
IOError: [Errno 32] Broken pipe

Eu tenho o mesmo problema que @sfermigier com o servidor de desenvolvimento ( debug=True ) e tenho o mesmo erro de rastreamento.

Esse comportamento geralmente ocorre em um caso muito simples: você está usando algum tipo de recurso de preenchimento automático. O navegador inicia uma conexão para tokens de consulta e, em seguida, para e inicia outra solicitação de mais tokens. Você vai acabar com muitos tubos quebrados. E isso não foi um problema até o último lançamento, o que bloqueou completamente o servidor de desenvolvimento.
Portanto, sugerir o uso de um servidor de aplicativos completo é uma boa solução, mas ainda vejo um problema aqui. Um problema apenas de desenvolvimento, é claro, mas o fato de ser tão comum para disparar torna-o perturbador para muitos desenvolvedores que não estão acostumados com _protocolos internos_.
Um pipe quebrado é muito comum (pense em uma solicitação longa por erro e o desenvolvedor apertando o botão de parada do navegador) e não deve quebrar o servidor de desenvolvimento.
Apenas minha opinião. :)

@xcash

Esse comportamento geralmente ocorre em um caso muito simples: você está usando algum tipo de recurso de preenchimento automático. O navegador inicia uma conexão para tokens de consulta e, em seguida, para e inicia outra solicitação de mais tokens.

Se estiver relacionado, posso confirmar que experimentei esse problema usando browsersync com gulp.js .

Alguém tem solução que não inclua a execução de um servidor WSGI? Parece que estou tendo esse problema com bots realizando uma varredura SYN no meu host.

@glennzw você pode ser mais específico em seu ambiente? Você não deve ter seu servidor de desenvolvimento público na web aberta acessível por bots. :) Em tal situação, como um host de demonstração para clientes, é sempre melhor usar pelo menos um servidor de aplicativos real como o gunicorn, que ocupa um espaço muito pequeno.

FWIW, não tenho acompanhado muito os lançamentos e este problema (muito chato) começou a acontecer para mim em algum momento entre maio - agosto de 2016, pelo que posso dizer. Eu adicionei isso ao meu setup.py install_requires = ['Werkzeug<0.11', 'flask<0.11', ... - que parece contornar o problema (IME, apenas fixar Werkzeug não pareceu funcionar?)

Para mim, o caso de duplicação era bastante simples - carregue uma página, mas não a deixe terminar de carregar. Ou seja, basta acionar _qualquer_ erro de pipe quebrado - e o servidor da web irá travar e falhar em atender a quaisquer outras solicitações. IMHO, os servidores web não podem _estar_ quando um cliente fecha a conexão prematuramente - mesmo os de desenvolvimento.

Será que todos vocês têm passthrough_errors definido em algum lugar?

@untitaker nesse caso, paletes / frasco # 1674 paletes / frasco # 1679 paletes / frasco # 1928 possivelmente relacionados?

Não sei, gostaria que um dos repórteres confirmasse.

Em 26 de agosto de 2016 17:05:25 CEST, David Lord [email protected] escreveu:

@untitaker , nesse caso, paletes / frasco # 1674 paletes / frasco # 1679
paletes / frasco nº 1928 possivelmente relacionados?

Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242761250

Enviado do meu dispositivo Android com K-9 Mail. Por favor desculpe minha brevidade.

cc @miguelgrinberg

Acho que Werkzeug deve lidar com tubos quebrados e erros de redefinição de conexão. Isso realmente não é uma indicação de um erro, o cliente simplesmente foi embora. Parece, neste caso, que uma exceção especial deve ser levantada, uma que seja reconhecida pelo método catch-all acima como uma a ser ignorada, mesmo se a passagem de erro for definida.

Veja como o gunicorn faz isso: https://github.com/benoitc/gunicorn/blob/39f62ac66beaf83ceccefbfabd5e3af7735d2aff/gunicorn/workers/sync.py#L151 -L154

É isso que deve fazer. Estou tentando descobrir como reproduzir
este comportamento, mas ainda não há um caso de teste claro disponível. Daí a questão
cerca de passthrough_errors .

Suspeito que não seja um bug no Werkzeug e que o navegador do usuário
simplesmente tem uma conexão ainda aberta que bloqueia outras solicitações (em vez do
falha do servidor). Se você fechar o navegador e reabri-lo, o servidor deve
funcionar novamente.

Na sexta-feira, 26 de agosto de 2016 às 11h54:16 -0700, Miguel Grinberg escreveu:

Acho que Werkzeug deve lidar com tubos quebrados e erros de redefinição de conexão. Isso realmente não é uma indicação de um erro, o cliente simplesmente foi embora. Parece, neste caso, que uma exceção especial deve ser levantada, uma que seja reconhecida pelo método catch-all acima como uma a ser ignorada, mesmo se a passagem de erro for definida.

Veja como o gunicorn faz isso: https://github.com/benoitc/gunicorn/blob/39f62ac66beaf83ceccefbfabd5e3af7735d2aff/gunicorn/workers/sync.py#L151 -L154

Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242821084

Ah, e erros de pipe quebrado _são_ exibidos, sim, mas eles nunca devem desligar o servidor como descrito. Veja o comentário anterior sobre o possível motivo.

Testei novamente os bits mais recentes e ainda estou vendo o mesmo comportamento no meu ambiente. Mas como você parecia estar tendo problemas para se reproduzir, tentei descobrir por que sou especial.

import time
from flask import Flask
app = Flask(__name__)


@app.route('/')
def hello_world():
    time.sleep(5)
    return 'Hello, World!'


if __name__ == "__main__":
    app.run()

Funcionou conforme o esperado com flask run mas o servidor da web travaria se você fechasse o navegador da web antes de permitir que a resposta fosse processada ao iniciar por meio de python hello.py

Parece que uma parte da sua resposta foi perdida.

Na sexta-feira, 26 de agosto de 2016 às 12h29:39 -0700, clayg escreveu:

Testei novamente os bits mais recentes e ainda estou vendo o mesmo comportamento no meu ambiente. Mas como você parecia estar tendo problemas para se reproduzir, tentei descobrir por que sou especial.

You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment-242829536

sim, em slack triple-ticks é como você bloqueia a cotação e ctrl-return é como você new-line
no github, triple-ticks é como você bloqueia a cotação, mas ctrl-return é como você envia
... enfim ... memória muscular

Editei minha postagem imediatamente após enviá-la para finalização - e só estou respondendo porque parece que você está respondendo por e-mail e não tenho certeza se o github enviará outro aviso após a minha edição.

Não consigo reproduzir com o teste de sono de @clayg acima. Na verdade, eu não consigo entender o erro de tubo quebrado. Fecho o navegador antes que a solicitação retorne uma resposta, mas Werkzeug executa a solicitação até o fim de qualquer maneira, imprime a linha de log 200 no console e não mostra nenhum erro.

Eu também tentei o mesmo truque usando meu exemplo de fluxo de vídeo em flask, que usa uma resposta de fluxo para fornecer quadros de vídeo em um fluxo sem fim e, mesmo para esse, posso fechar o navegador e a solicitação termina sem nenhum erro. Este é estranho, porque tenho certeza de que, no passado, esse aplicativo dispararia um erro de pipe quebrado no console antes de encerrar a solicitação.

Na verdade, eu falei muito cedo. Posso reproduzir todas as vezes com meu aplicativo de streaming de vídeo ao usar o Python 2.7. Não consigo reproduzir no 3.5. Todos os rastreamentos de pilha acima são para o 2.7, portanto, lembre-se disso se estiver testando com Python 3.

Mais um ponto de dados interessante. Se estiver executando com o reloader, quando o processo filho sair, o processo mestre que está executando o reloader inicia outro, portanto, não há interrupção. Mas se você estiver executando o servidor sem o recarregador, o erro de pipe interrompido o levará de volta ao console.

Editar: desconsidere o recarregador iniciando outra parte do processo, que não parece estar acontecendo e, em vez disso, eu provavelmente estava vendo o efeito de alterar a configuração do erro de passagem.

Ok, aqui está a análise do que acho que está acontecendo:

  • O cliente vai embora no meio do pedido
  • O pedido continua. A conexão do soquete parece estar em buffer, portanto, na maioria dos casos, as gravações no soquete não causarão problemas.
  • Assim que a solicitação terminar, a classe de servidor de soquete emitirá um flush() no soquete. Esse era o assunto de um bug antigo na biblioteca Python que está corrigido atualmente: http://bugs.python.org/issue14574. A solução nessa correção foi capturar socket.error e ignorá-lo.
  • Em seguida, o servidor de soquete tenta fechar a conexão. Este é o seguinte quadro de pilha, do backtrace do OP:

File "/usr/lib/python2.7/SocketServer.py", line 710, in finish self.wfile.close()

  • Infelizmente, no Python 2.7, a primeira coisa que o método socket.close() faz é limpar novamente:

File "/usr/lib/python2.7/socket.py", line 279, in close self.flush()

  • Essa segunda tentativa de flush não é protegida com try / except, portanto, gera a exceção EPIPE.
  • O servidor de soquete captura a exceção e a entrega ao método handle_error() do servidor.
  • A implementação de Werkzeug de handle_error() olha para a configuração passthrough_errors , e uma vez que temos isso sempre definido como True , aumenta novamente o erro EPIPE e o deixa borbulhar até o principal.

O código de soquete no Python 3 é completamente diferente e, em particular, não parece ter nenhuma chamada de flush sem try / excets. O erro EPIPE nem mesmo surge para Werkzeug ao usar o Python 3.

Temos passthrough_errors definido como true? Em Werkzeug, é falso por padrão.

Em 27 de agosto de 2016 02:10:13 CEST, Miguel Grinberg [email protected] escreveu:

Ok, aqui está a análise do que acho que está acontecendo:

  • O cliente vai embora no meio do pedido
  • O pedido continua. A conexão do soquete parece ser
    em buffer, então, na maioria dos casos, as gravações no soquete não causarão
    problemas.
  • Assim que a solicitação terminar, a classe de servidor de soquete emitirá um flush()
    no soquete. Este era o assunto de um bug antigo na biblioteca Python
    que está corrigido atualmente: http://bugs.python.org/issue14574. o
    solução nesta correção foi capturar socket.error e ignorá-lo.
  • Em seguida, o servidor de soquete tenta fechar a conexão. Isto é o
    seguinte frame de pilha, do backtrace do OP:
 File "/usr/lib/python2.7/SocketServer.py", line 710, in finish
 self.wfile.close()

  • Infelizmente, no Python 2.7, a primeira coisa a socket.close()
    método faz é limpar novamente:
 File "/usr/lib/python2.7/socket.py", line 279, in close
 self.flush()

  • Esta segunda tentativa de flush não é protegida com try / except, então
    ele levanta a exceção EPIPE.
  • O servidor de soquete captura a exceção e, em seguida, entrega-a ao
    método handle_error() do servidor.
  • A implementação de Werkzeug de handle_error() analisa o
    passthrough_errors configuração, e como temos isso sempre definido para
    True , aumenta novamente o erro EPIPE e o deixa borbulhar até o topo.

O código do soquete no Python 3 é completamente diferente e, em particular,
não parece ter nenhuma chamada de flush sem try / excets ao redor
eles. O erro EPIPE nem mesmo borbulha para Werkzeug ao usar
Python 3.

Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242881523

Enviado do meu dispositivo Android com K-9 Mail. Por favor desculpe minha brevidade.

Oh, ahem: https://github.com/pallets/flask/pull/1679

Acho que passthrough_errors deve ser dependente de app.debug . NVM, é inútil

Não vejo outra opção senão reverter esse PR, na verdade. passthrough_errors=True apenas faz o que deve fazer, o que não é um bom comportamento padrão se não houver um depurador anexado ao programa.

Esqueça, eu encontrei outra maneira. Dois PRs:

Uma vez que ambos são mudanças de comportamento em um sentido amplo, prefiro não retrocedê-los.

Acho que https://github.com/pallets/flask/pull/1996 é uma solução aceitável. O importante é que ele corrige o caso comum em que você não deseja que as exceções sejam propagadas. Se você deseja propagar, então está depurando e, nesse caso, obtendo o socket.error propagado quando não deveria não é um grande negócio.

A correção https://github.com/pallets/werkzeug/pull/998 não é ótima. O aplicativo pode gerar essas exceções legitimamente de algo que está fazendo com soquetes em seus próprios manipuladores, e esses também seriam silenciados. A solução ideal seria que eles sejam capturados no local em que ocorrem e, em seguida, gerados novamente como alguma classe de exceção personalizada que handle_error pode reconhecer e ignorar. Dado que provavelmente não queremos alterar ou sobrecarregar SocketServer , acho que meu voto é apenas deixar esta parte como está. Você terá o EPIPE despejado no console, mas apenas no Python 2, e pelo menos ele não irá parar o servidor depois que a outra correção entrar. É inofensivo e é um comportamento que existia no passado, antes de eu fazer o passthrough_errors mudança.

O comportamento que você descreve só acontece com PASSTHROUGH_ERRORS habilitado. Caso contrário, a exceção é capturada de dentro do Flask.

Acho que essa melhoria cosmética não vale a pena.

Em 27 de agosto de 2016 18:29:30 CEST, Miguel Grinberg [email protected] escreveu:

Acho que https://github.com/pallets/flask/pull/1996 é um aceitável
solução. O importante é que ele corrige o caso comum em que
você não deseja que as exceções sejam propagadas. Se você deseja propagar,
então você está depurando e, nesse caso, obtendo o socket.error
propagado quando não deveria não é um grande negócio.

A https://github.com/pallets/werkzeug/pull/998 correção não é boa
no entanto. O aplicativo pode gerar essas exceções legitimamente de
algo que está fazendo com soquetes em seus próprios manipuladores, e esses
ser silenciado também. A solução ideal seria que estes fossem detectados
no local em que ocorrem e, em seguida, são ressaltados como uma exceção personalizada
classe que handle_error pode reconhecer e ignorar. Dado que nós
provavelmente não quero alterar ou sobrecarregar SocketServer , acho que meu
votar é apenas deixar essa parte como está. Você receberá o EPIPE despejado para
o console, mas apenas no Python 2, e pelo menos não vai parar
o servidor após a outra correção entrar. É inofensivo e é um
comportamento que existia no passado, antes de eu fazer o
passthrough_errors mudança.

Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -242926832

Enviado do meu dispositivo Android com K-9 Mail. Por favor desculpe minha brevidade.

Fixo no mestre.

O comportamento que você descreve só acontece com PASSTHROUGH_ERRORS habilitado

Sim, omiti esse detalhe. Mas essa mudança afetaria até mesmo o Python 3, onde nada disso é um problema. No Py3, com os erros de passagem ativados, um socket.error legítimo gerado pelo aplicativo seria silenciado.

mestre parece wfm, ansioso para o próximo lançamento, obrigado!

Olá, eu uso um servidor de desenvolvimento Werkzeug em execução no NGINX. Estou enfrentando o mesmo problema, alguém poderia me ajudar com isso,
11:13:11 web.1 | 127.0.0.1 - - [15/Sep/2016 11:13:11] "GET /api/method/frappe.utils.print_format.download_pdf?doctype=Purchase%20Order&name=PO-00001&format=PO&no_letterhead=0 HTTP/1.1" 200 - 11:13:11 web.1 | Error on request: 11:13:11 web.1 | Traceback (most recent call last): 11:13:11 web.1 | File "/home/ommi/frappe-bench/env/lib/python2.7/site-packages/werkzeug/serving.py", line 193, in run_wsgi 11:13:11 web.1 | execute(self.server.app) 11:13:11 web.1 | File "/home/ommi/frappe-bench/env/lib/python2.7/site-packages/werkzeug/serving.py", line 184, in execute 11:13:11 web.1 | write(data) 11:13:11 web.1 | File "/home/ommi/frappe-bench/env/lib/python2.7/site-packages/werkzeug/serving.py", line 152, in write 11:13:11 web.1 | self.send_header(key, value) 11:13:11 web.1 | File "/usr/lib/python2.7/BaseHTTPServer.py", line 401, in send_header 11:13:11 web.1 | self.wfile.write("%s: %s\r\n" % (keyword, value)) 11:13:11 web.1 | IOError: [Errno 32] Broken pipe

Por favor ajude

Ragav usa outro servidor de aplicação em vez do dev integrado do werkzeug
servidor, como gunicorn. É a única solução agora.

15/09/2016 8:07 GMT + 02: 00 Ragav [email protected] :

Olá, eu uso um servidor de desenvolvimento Werkzeug em execução no NGINX, estou enfrentando o
mesmo problema, alguém poderia me ajudar com isso, `` `
11:13:11 web.1 | 127.0.0.1 - - [15 / Set / 2016 11:13:11] "GET
/api/method/frappe.utils.print_format.download_pdf?
doctype = Purchase% 20Order & name = PO-00001 & format = PO & no_letterhead = 0
HTTP / 1.1 "200 -
11:13:11 web.1 | Erro na solicitação:
11:13:11 web.1 | Traceback (última chamada mais recente):
11:13:11 web.1 | Arquivo "/ home / ommi / frappe-bench / env /
lib / python2.7 / site-packages / werkzeug / serving.py ", linha 193, em run_wsgi
11:13:11 web.1 | execute (self.server.app)
11:13:11 web.1 | Arquivo "/ home / ommi / frappe-bench / env /
lib / python2.7 / site-packages / werkzeug / serving.py ", linha 184, em execução
11:13:11 web.1 | escrever (dados)
11:13:11 web.1 | Arquivo "/ home / ommi / frappe-bench / env /
lib / python2.7 / site-packages / werkzeug / serving.py ", linha 152, por escrito
11:13:11 web.1 | self.send_header (chave, valor)
11:13:11 web.1 | Arquivo "/usr/lib/python2.7/BaseHTTPServer.py", linha 401,
em send_header
11:13:11 web.1 | self.wfile.write ("% s:% s \ r \ n"% (palavra-chave, valor))
11:13:11 web.1 | IOError: [Errno 32] Tubo quebrado

Por favor ajude

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/pallets/werkzeug/issues/954#issuecomment -247243400,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AA6MZ6DNiRIfL91CLeYOoA70W9_nQQzGks5qqOCMgaJpZM4I58cy
.

Guiado pelo recente commit de correção, consegui corrigir esse problema chamando app.run com passthrough_errors = False. YMMV

O bug que causou a falha foi corrigido na versão 0.12 , lançada em 21 de dezembro de 2016.

  • Reverta uma mudança de comportamento que fez o servidor de desenvolvimento travar em vez de retornar um erro interno do servidor (solicitação pull # 2006).

A versão 0.12 foi lançada apenas na semana passada.

Na segunda-feira, 20 de março de 2017 às 09h05 -0700, Alan Rotman escreveu:

O bug que causou a falha foi corrigido na versão 0.12 , lançada em 21 de dezembro de 2016.

  • Reverta uma mudança de comportamento que fez o servidor de desenvolvimento travar em vez de retornar um erro interno do servidor (solicitação pull # 2006).

-
Você está recebendo isso porque modificou o estado abrir / fechar.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -287807602

Acabei de ver ReleaseNotes hoje e estou esperando por essa correção há muito tempo.

Veja: http://flask.pocoo.org/docs/0.12/changelog/
Versão 0.12
Lançado em 21 de dezembro de 2016, codinome Punsch.

https://pypi.python.org/pypi/Flask/0.12
Tipo de arquivo Py Versão carregada no tamanho
Flask-0.12-py2.py3-none-any.whl (md5) Python Wheel 2.7 2016-12-21 80 KB
Flask-0.12.tar.gz (md5) Fonte 2016-12-21 519 KB

Ah, sim, você quer dizer Flask. Certo.

Na segunda-feira, 20 de março de 2017 às 09:22:15 AM -0700, Alan Rotman escreveu:

Acabei de ver ReleaseNotes hoje e estou esperando por essa correção há muito tempo.

Veja: http://flask.pocoo.org/docs/0.12/changelog/
Versão 0.12
Lançado em 21 de dezembro de 2016, codinome Punsch.

https://pypi.python.org/pypi/Flask/0.12
Tipo de arquivo Py Versão carregada no tamanho
Flask-0.12-py2.py3-none-any.whl (md5) Python Wheel 2.7 2016-12-21 80 KB
Flask-0.12.tar.gz (md5) Fonte 2016-12-21 519 KB

-
Você está recebendo isso porque modificou o estado abrir / fechar.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/pallets/werkzeug/issues/954#issuecomment -287813405

Apenas uma observação para quem se depara com esse problema ao executar o flask 0.12.2 no werkzeug no modo threaded = True:
No modo threaded, por padrão, parece que cada thread werkzeug realmente ainda tem esse problema, ou seja, se você solicitar uma rota que leva algum tempo para retornar e, em seguida, fecha a conexão do cliente, aquele werkzeug em particular registra um IOError Broken Pipe e então morre. O servidor em geral continua a funcionar, exceto que em meu aplicativo eu estava descobrindo que isso estava causando um vazamento de memória de alguma forma, com o processo de frasco crescendo lentamente após um tubo rompido em qualquer thread, usando toda a RAM e, em seguida, SWAP e, finalmente, sendo morto pelo sistema operacional.
O envio explícito de passthrough_errors = False em app.run parece ter resolvido o problema - os threads não morrem mais quando o cliente se desconecta, eles registram o IOError e, em seguida, também registram isso (que eu nunca vi sem definir explicitamente passthrough_errors = False):

Exception happened during processing of request from ('127.0.0.1', 50652)
----------------------------------------

E então o servidor continua a funcionar normalmente. Ainda tenho que esperar algumas horas para ver se o vazamento de memória aparecerá novamente, mas tenho esperança de que não.

Apenas no caso de ser útil para alguém.

Também vi este erro em um contêiner do Ubuntu Docker no Kubernetes no Ubuntu VM:

Error on request:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", line 270, in run_wsgi
    execute(self.server.app)
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", line 261, in execute
    write(data)
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", line 227, in write
    self.send_header(key, value)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 412, in send_header
    self.wfile.write("%s: %s\r\n" % (keyword, value))
IOError: [Errno 32] Broken pipe

Eu criei uma nova VM xenial do Ubuntu e executei o mesmo código no contêiner do Ubuntu Docker no Kubernetes, e esse erro não foi visto e o Python Flask funcionou conforme o esperado. Acho que foi um problema com meu host (Ubuntu VM).

@vhosakot Você pode me dizer como definiu a configuração do seu aplicativo? Eu encontrei um problema semelhante no mesmo ambiente que o seu.

Em uma função de rota, usei outra função destinada ao roteamento.
Peguei os dados da resposta dessa função.
Agora, quando usei _loads () _ nesses dados, estou recebendo o erro.

...
response = get_contents().data
        if response:
            data = loads(response)
..

Erro: IOError: [Errno 32] Broken pipe

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

caiz picture caiz  ·  3Comentários

sorenh picture sorenh  ·  4Comentários

miki725 picture miki725  ·  10Comentários

Nessphoro picture Nessphoro  ·  6Comentários

taion picture taion  ·  7Comentários