Pergunta

Primeiro,

a configuração:

Eu tenho um script que executa várias tarefas depois que um usuário clica no botão "upload" que envia ao script os dados necessários.Agora, esta parte é atualmente obrigatória, não temos a opção neste momento de cortar o upload e extrair de uma fonte ao vivo.

Esta seção é intencionalmente prolixa para deixar claro um ponto.Vá em frente se você odeia isso

No momento, os dados são analisados ​​​​a partir de uma fonte realmente interessante usando regex e depois divididos em um array.Em seguida, ele verifica o banco de dados em busca de quaisquer dados já no intervalo de datas dos dados carregados.Se os intervalos de datas dos dados ainda não existirem no banco de dados, ele insere os dados e gera sucesso para o usuário (há também algumas verificações de segurança, validação de fonte de dados e validação básica de upload)...Se os dados existirem, o script obtém os dados já no banco de dados, encontra as diferenças entre os dois conjuntos, exclui os dados antigos que não correspondem, adiciona os novos dados e envia um email para cada pessoa afetada por essas alterações (um e-mail por pessoa com todas as alterações relevantes no referido e-mail, o que é uma etapa totalmente diferente).Os endereços de e-mail são obtidos por meio de uma pesquisa LDAP, pois nosso banco de dados tem seu e-mail comercial, mas o LDAP tem seu e-mail pessoal, o que garante que eles recebam o e-mail antes de chegarem no dia seguinte e serem pegos de surpresa.Finalmente, é dito o utilizador de dados "alterações foram feitas, e-mails foram enviados". O que é realmente tudo o que eles se importam.

Agora posso estar adicionando uma API do Google Calendar que publica os dados (quando está agendando dados) no Google Calendar do usuário.Eu faria isso por meio do calendário de trabalho deles, mas pensei em molhar os pés com a API do Google antes de começar a configurar um sistema WebDav para Exchange.

</backstory>

Agora!

A questão prática

Neste ponto, pré-integração com o Google, o script leva no máximo um segundo e meio para ser executado.É bastante impressionante, pelo menos eu acho (o servidor, não minha codificação).Mas a parte do Google, nos testes, é LENTOOO.Provavelmente podemos consertar isso, mas isso levanta uma questão maior...

Qual é a melhor maneira de descarregar parte do trabalho depois que o usuário obteve a confirmação de que o banco de dados foi atualizado?Esta é a parte com a qual ele está mais preocupado e a parte mais crítica.As notificações por e-mail e as atualizações do Google Agenda existem apenas para o benefício das pessoas afetadas pelo upload e, se houver um problema com essas notificações, ele ficará sabendo (e então eu saberei), independentemente do script informar ele primeiro.

Então, existe uma maneira, por exemplo, de executar um cronjob acionado pela última execução de um script?O PHP pode criar cronjobs com exec() habilidade?Existe alguma maneira normalizada de lidar com o trabalho pós-execução que precisa ser feito?

Qualquer conselho sobre isso é muito apreciado.Sinto que o inchaço dos scripts reflete meu estágio de desenvolvimento e a necessidade de finalmente saber como fazer a divisão de trabalho em aplicativos da web.

Mas também fico preocupado que isso não seja feito, pois o usuário precisa saber quando todas as tarefas foram concluídas, etc.Então isso traz à tona:

As melhores práticas/pergunta mais subjetiva

Basicamente, existe uma ideia de que barras de progresso, descarregamento em tempo real e outras maneiras de manter o usuário vinculado ao script são - quando combinados com a otimização do código, é claro - o método melhor e mais preferido do que simplesmente dizendo "Concluímos sua parte, se você precisar de nós, notificaremos os usuários" etc.

Há alguma coisa GRANDE a evitar (além de, obviamente, não dar nenhum feedback ao usuário)?

Obrigado por ler.A parte da codificação é crucial, então não se sinta obrigado a cobrir a segunda parte ou se esqueça de cobrir a parte da codificação!

Foi útil?

Solução

Existem várias maneiras de fazer isso.Você poderia exec(), como diz acima, mas poderá se deparar com uma situação de DoS se houver muitos cliques de envio.a extensão pcntl é indiscutivelmente melhor no gerenciamento de processos como este.Confira esta postagem para ver uma discussão (há 3 partes).

Você pode usar Javascript para enviar uma segunda postagem ajax que executa o script de trabalho apropriado posteriormente.Ao usar ignore_user_abort() e enviar um Content-Length, o navegador pode se desconectar antecipadamente, mas seu processo Apache continuará a executar e processar seus dados.A vantagem não é o potencial de forkbomb. A desvantagem é que abrirá mais processos Apache.

Outra opção é usar um cron em segundo plano que olha para uma tabela de fila de processos em busca de coisas para fazer 'mais tarde' - você cola itens nesta tabela no front-end, remove-os no back-end durante o processamento (veja Zend_Queue).

Outra ainda é usar uma estrutura de trabalho mais distribuída, como redutor - que pode processar itens em outras máquinas.

Tudo depende de suas capacidades e requisitos gerais.

Outras dicas

Um cron job é bom para isso.Se tudo o que você deseja fazer quando um usuário carrega dados é dizer "Ei usuário, obrigado pelos dados!" Então isso vai ficar bem.

Se preferir uma abordagem mais imediata, você pode usar exec() para iniciar um processo em segundo plano.Em um ambiente Linux seria algo assim:

exec("php /path/to/your/worker/script.php >/dev/null &");

O & Parte diz "me corra na borda". O >/dev/null parte redireciona a saída para um buraco negro.No que diz respeito ao tratamento de todos os erros e à notificação das partes apropriadas - tudo depende do design do seu script de trabalho.

Para uma abordagem multiplataforma mais flexível, confira isto Postagem manual do PHP

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top