No momento, estamos mantendo um "servidor web" python caseiro, em que a geração de resposta para algumas solicitações pode demorar muito, principalmente devido a cálculos pesados - essas solicitações são basicamente postagens com tempos limite muito longos (pense em minutos a dezenas de minutos).
Um problema dessa arquitetura é que às vezes há a necessidade de cancelar uma solicitação - por exemplo, o usuário notou um erro ao configurar a solicitação. Atualmente, o cancelamento é outra solicitação, que cancela a solicitação de longa execução - mas há muitas lacunas, por exemplo, o que acontece se o cliente simplesmente fechar o site?
Atualmente, estamos planejando retirar a abominação doméstica de um servidor da Web e mudar para algo sensato - por exemplo, Flask sendo executado dentro de um IIS usando o wfastcgi. Por razões políticas, o IIS está configurado, portanto, mudar para algo como gunicorn fica fora da janela.
Todo o desenvolvimento parou nisso porque ninguém tem uma idéia de como eliminar os processos executados pelo (w) fastcgi - essa preocupação simplesmente não faz parte das especificações do fastcgi.
Meu sentimento é que uma tentativa de criar algo que incorpore isso é um erro - eu preferiria uma solução em que o servidor simplesmente transferisse essas tarefas intensivas de computação para algum servidor em segundo plano (flask + aipo?) E as pesquisas de front-end para isso.
Infelizmente, a solução antiga estava em vigor por tanto tempo que alguns desenvolvedores querem manter o comportamento a todo custo.
Não sendo um servidor de web, eu gostaria de algumas dicas / padrões de como seriam as soluções sensatas para esse problema.
fonte
Eu sugiro que você procure no wsgi e use multithreading . Você pode gerenciar cada solicitação em um encadeamento e implementar tempos limite no encadeamento. Você também deve poder gerenciar os encadeamentos e cancelar solicitações mais facilmente.
fonte
O problema que você enfrenta atualmente com uma simples postagem HTTP simplesmente não pode ser resolvido nesse protocolo. O HTTP funciona de forma assíncrona em cliente / servidor estrito, para que não haja notificações no servidor nem cancelamentos nativos. Além disso, você enfrentará o problema de respostas perdidas devido a tempos limite da rede na Internet. Vou sugerir uma abordagem diferente e moderna. Isenção de responsabilidade: pouco menos de 90% do suporte ao navegador
Eu sugiro que você inverta o fluxo de informações e use websockets. O que você precisa fazer quando uma tarefa é concluída é notificar seu usuário e enviar uma notificação de servidor para cliente.
Quando uma tarefa for publicada, ou, mais precisamente, como um substituto para a publicação, abra um websocket (use a tecnologia de servidor que você gosta, tornado, gevent, python-websocket etc.). Associe o encadeamento de tarefas no evento aberto do servidor websocket. Se o cliente sair, ele enviará um evento close ao seu manipulador de websocket, para que você possa finalizar o encadeamento associado a ele. Caso contrário, se sua tarefa terminar normalmente, o servidor poderá enviar os dados para o cliente e fechar o soquete da web. Além disso, você deve fazer o servidor executar ping uma vez a cada 30s, porque os websockets fecham se ficarem inativos por mais de um minuto.
Se você aplicar isso, será mais rápido e limpo do que uma pesquisa do lado do cliente, enquanto soluciona problemas de lacuna, pois você possui um canal bidirecional real. Observe que você pode implementar serviços adicionais sobre o esquema da tarefa, como sessões, pings de progressão etc.
fonte
Se sua tarefa precisar de muito tempo para ser concluída, não faça isso nesse pedido. Coloque na fila e faça outro processo que fará o trabalho.
Depois que o trabalho estiver concluído, basta enviar uma notificação ao usuário de que a "operação x" está concluída. Enquanto isso, mostre a mensagem "seu trabalho será concluído em aproximadamente x minutos".
fonte