Padrão para solicitações com tempos de resposta longos?

6

Atualmente, estamos mantendo um "servidor web" python caseiro, onde gerar a 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 para dezenas de minutos) .

Um problema dessa arquitetura é que às vezes há necessidade de captar essa 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 duração - mas há muitas lacunas, e. g. o que acontece se o cliente simplesmente fechar o site?

Atualmente, estamos planejando aposentar a abominação doméstica de um servidor da Web e mudar para algo sensato - e. g. Flask rodando dentro de um IIS usando wfastcgi. Devido a razões políticas, o IIS está definido, então mudar para algo como o gúnico está fora da janela.

Todo o desenvolvimento ficou parado porque n \ u00e3o tem uma ideia, como matar os processos executados por (w) fastcgi - essa preocupa \ u00e7 \ u00e3o simplesmente n \ u00e3o faz parte da especifica \ u00e7o de fastcgi.

Meu sentimento é que uma tentativa de construir algo que incorpore isso é um erro - eu preferiria uma solução em que o servidor simplesmente descarregasse tais tarefas de computação intensiva em algum servidor de segundo plano (flask + celery?) e as sondagens de frontend .

Infelizmente, a antiga solução estava em vigor há tanto tempo que alguns desenvolvedores querem manter o comportamento a todo custo.

Como não sou um servidor weber, eu poderia gostar de algumas dicas / padrões de como soluções sensatas para um problema como esse poderiam parecer.

    
por Christian Sauer 20.02.2016 / 16:38
fonte

3 respostas

5

O que você está sugerindo está correto.

Deve ser assíncrono.

Você pode postar uma solicitação e a solicitação fornece um ID exclusivo. Ele posta um Done nessa id única em alguma loja onde você pode pesquisar.

Se você precisar cancelar uma solicitação, uma solicitação de cancelamento usando o mesmo ID deve ser postada

Além disso, no back-end em que esses cálculos estão sendo executados, por exemplo, em uma interface de execução de um Thread (estilo java), é possível verificar após alguns segundos se o processo for cancelado, verificando se uma postagem cancelada foi solicitada. Se for, o encadeamento deve sair. Esta é uma saída limpa. Você também pode usar uma interrupção para o segmento.

    
por 09.04.2016 / 03:34
fonte
2

Eu sugiro que você olhar para wsgi e usar multithreading . Você pode gerenciar cada solicitação em um encadeamento e implementar tempos limite no encadeamento. Você também deve conseguir gerenciar os segmentos e cancelar solicitações com mais facilidade.

    
por 09.04.2016 / 02:17
fonte
1

O problema que você atualmente enfrenta com uma simples postagem HTTP simplesmente não pode ser resolvido nesse protocolo. O HTTP funciona de forma assíncrona no cliente / servidor estrito, por isso não há notificação do lado do servidor nem cancelamento nativo. Além disso, você enfrentará o problema de respostas perdidas devido a tempos limite da rede da Internet. Vou sugerir uma abordagem diferente e moderna. Aviso de isenção de responsabilidade: um pouco menos de 90% de suporte ao navegador

Eu sugiro que você inverta o fluxo de informações e use websockets. O que você precisa fazer quando uma tarefa é executada é notificar seu usuário e enviar uma notificação do servidor para o cliente.

Quando uma tarefa é postada, ou, mais precisamente, como substituta da postagem, abra um websocket (use a tecnologia de servidor que você gosta, tornado, gevent, python-websocket etc.). Associe o encadeamento de tarefas no evento aberto websocket do servidor. Se o cliente fechar, o cliente enviará um evento de fechamento para o manipulador do seu websocket, para que você possa encerrar o encadeamento associado a ele. Senão, se a sua tarefa terminar normalmente, o servidor poderá enviar os dados para o cliente e fechar o websocket. Além disso, você precisa fazer o ping do servidor uma vez a cada 30 segundos porque o websockets fecha se ficar inativo por mais de um minuto.

Se você aplicar isso, isso será mais rápido e mais limpo do que uma pesquisa do lado do cliente, enquanto resolve problemas de lacuna, pois você tem um canal bidirecionnal real. Observe que você pode implementar serviços adicionais sobre o esquema de tarefas, como sessões, pings de progressão, etc.

    
por 08.06.2016 / 10:54
fonte

Tags