Corri para um problema de tempo limite usando migrar no outro dia e comecei a me perguntar como a API do Lote funciona internamente.
Pelo que entendi, na sua forma mais simples, você passará uma matriz de valores (nids por exemplo) e uma função para operar com esses valores. A API do lote processa um número fixo desses valores com cada solicitação até que seja concluída.
Quando um lote está sendo executado, a página parece usar solicitações do Ajax para mostrar o progresso da operação do lote (% de concluídos e mensagens). Suponho que aguarde até que a solicitação termine para atualizar o andamento e inicie a próxima solicitação imediatamente depois?
Se a página com a solicitação de lote estiver fechada, o processamento do lote será interrompido? Será reiniciado quando o mesmo URL for aberto novamente? Às vezes, o módulo de migração continua, mas provavelmente está usando filas?
É assim que o lote funciona (com base no meu entendimento)
1. Inicialize
Inicialize o processamento em lote. Com base na configuração dos clientes (Navegadores), se o JavaScript está ativado ou não.
Clientes habilitados para JavaScript são identificados pelo conjunto de cookies 'has_js' em drupal.js. Se nenhuma página ativada para JavaScript tiver sido visitada durante a sessão atual do navegador do usuário, a versão não JavaScript será retornada.
Se o Lote ativado por JavaScript usar a solicitação ajax, mantenha a conexão ativa através da solicitação.
Se o JavaScript não estiver ativado, o Batch usa define uma metatag em html para fazer intervalos regulares de atualização para manter a conexão ativa através da solicitação.
(É assim que a barra de progresso é atualizada sobre o andamento da tarefa concluída.)
Processo descontínuo
Para iniciar o processo, o Lote cria uma Fila e adiciona todas as operações (funções e argumentos) que você define na matriz de lotes, como
$batch = array ('operations'=> array(
array('batch_example_process', array($options1, $options2)),
array('batch_example_process', array($options3, $options4)),),'finished'=>'batch_example_finished','title'=> t('Processing Example Batch'),'init_message'=> t('Example Batch is starting.'),'progress_message'=> t('Processed @current out of @total.'),'error_message'=> t('Example Batch has encountered an error.'),'file'=> drupal_get_path('module','batch_example').'/batch_example.inc',);
Além disso, também atribui um ID de lote que é único entre os lotes.
Agora, as chamadas em lote reivindicam os itens da fila um por um e executam a função definida com os argumentos definidos nele.
Esta é uma parte crucial. A função (Operação) que implementa a operação em lote deve agrupar os dados e processá-los de maneira muito eficiente, tendo em mente o limite de memória do PHP, Time out . Não fazer isso terminará no seu problema.
Corri para um problema de tempo limite usando migrar no outro dia e comecei a me perguntar como a API em lote funciona internamente.
A função de lote
As funções que implementam o Lote devem executar as seguintes ações com muito cuidado,
Número de itens nas operações para processar como,
if(!isset($context['sandbox']['progress'])){
$context['sandbox']['progress']=0;
$context['sandbox']['current_node']=0;
$context['sandbox']['max']= db_result(db_query('SELECT COUNT(DISTINCT nid) FROM {node}'));}
Limitar o número de itens a serem processados em uma chamada de função, como configurar um limite,
// For this example, we decide that we can safely process 5 nodes at a time without a timeout.
$limit =5;
Atualização no processo para pós-processamento como,
Informar o mecanismo do Lote se o Lote foi concluído ou não,
// Inform the batch engine that we are not finished,// and provide an estimation of the completion level we reached.if($context['sandbox']['progress']!= $context['sandbox']['max']){
$context['finished']= $context['sandbox']['progress']/ $context['sandbox']['max'];}
A maioria dos pontos acima é realizada pelas operações em lote do Drupal, se houver falta na função Implementing. Mas é sempre melhor definir na função de implementação
Retorno de chamada finalizado em lote
Esta é a última chamada de retorno chamada quando definida na matriz de lotes. Geralmente, um relatório de quanto processado etc ...
RESPOSTAS
Se a página com a solicitação de lote estiver fechada, o processamento do lote será interrompido? Será reiniciado quando o mesmo URL for aberto novamente? Às vezes, o módulo de migração continua, mas provavelmente está usando filas?
Sim, o ideal é reiniciar o lote e, como dito acima, é baseado na função que você implementa.
Para resolver seu problema de tempo limite do PHP, use o lote Drush, disponível no módulo de migração, mas primeiro desenterre as funções de lote do migrate e tente dividir seus dados de processamento.
Terrific walk-through. Eu também gostaria de salientar que o lote inicia o processamento durante o que, pelo menos para o usuário, parece ser a "Inicialização". tela. Ou seja, se levar 4 segundos para configurar e 10 segundos para processar o primeiro item de lote, o usuário verá o processo "Inicializando". por catorze segundos neste exemplo. Isso faz sentido porque a primeira mensagem na tela não init é "n concluída", que só funcionaria depois que algumas forem processadas. Se isso estiver errado, por favor me corrija!
precisa saber é o seguinte
Além disso, pela minha experiência. Se você sair da página, a operação em lote / parte em processo ainda consumirá recursos até que seja concluída. Ele não dispara mais o trabalho em lotes, mas conclui o atual.
Elias Lynn
10
Se a página com a solicitação de lote estiver fechada, o processamento do lote será interrompido?
Sim, será parado.
Será reiniciado quando o mesmo URL for aberto novamente? Às vezes, o módulo de migração continua, mas provavelmente está usando filas?
Como disse Dinesh, isso depende da implementação.
Você deve executar a migração usando drush, porque
Drush é executado na linha de comando e não está sujeito a nenhum limite de tempo (em particular, o max_execution_time do PHP não se aplica). Portanto, quando você inicia um processo de migração em execução via drush, ele simplesmente é iniciado e continua sendo executado até terminar.
Ao executar processos por meio de uma interface da web, aplica-se o tempo max_execution_time do PHP (normalmente 30 segundos, se não menos). Assim, para processos de longa execução, precisamos usar a API do Lote, que gerencia a divisão de um processo em várias solicitações. Portanto, um processo de migração será iniciado, executado por aproximadamente 25 segundos, e então parará e permitirá que a API do Lote emita uma nova solicitação de página, na qual o processo de migração é reiniciado, ad infinitum.
Então, entendendo isso, por que Drush é melhor?
É mais rápido
A API do Lote apresenta muita sobrecarga - desligando e reinvocando as solicitações de página, o processo de migração precisa executar todos os construtores necessários novamente, as conexões com o banco de dados restabelecidas e as consultas executadas novamente, etc. E, para uma importação parcial, é necessário escolher onde parou - se os primeiros 500 registros de origem foram importados, ele precisa encontrar o 501 ° registro. Dependendo do seu formato de origem e de como é construído, isso pode ou não ser dimensionado - se você estiver usando marcas d'água alta com uma fonte SQL, a própria consulta poderá eliminar os registros anteriores e começar exatamente de onde você parou. Caso contrário, o Migrate precisa rolar pelos dados de origem procurando o primeiro registro não importado. Com, digamos, um grande arquivo XML como sua fonte,
É mais confiável
A execução de migrações pelo navegador adiciona sua área de trabalho e sua conexão local à Internet, como pontos de falha. Uma falha na rede quando a API do Lote está passando para a solicitação da próxima página, uma falha no navegador, um fechamento acidental da guia ou janela errada podem interromper sua migração. A execução drush reduz as partes móveis - você elimina sua área de trabalho e a conexão local à Internet como fatores.
É mais útil
Se algo der errado durante a execução no Drush, se houver alguma mensagem de erro útil, você as verá. As falhas no uso da API do Lote geralmente são engolidas e tudo o que você vê é a completamente inútil "Uma solicitação HTTP AJAX foi encerrada de forma anormal. A seguir, são fornecidas informações de depuração. Caminho: / batch? Id = 901 & op = do StatusText: ResponseText: ReadyState: 4".
Você pode encontrar mais informações sobre isso aqui .
Enquanto isso, se você deseja executar o lote, mesmo que a janela do navegador esteja fechada, considere o módulo Processo em Segundo Plano . Ele tem um submódulo em lote de plano de fundo que faz o truque.
Esse módulo assume a API em lote existente e executa tarefas em lote em um processo em segundo plano. Isso significa que, se você sair da página de lote, os trabalhos continuarão e você poderá retornar ao indicador de progresso posteriormente.
Sim, será parado.
Como disse Dinesh, isso depende da implementação.
Você deve executar a migração usando drush, porque
Você pode encontrar mais informações sobre isso aqui .
Enquanto isso, se você deseja executar o lote, mesmo que a janela do navegador esteja fechada, considere o módulo Processo em Segundo Plano . Ele tem um submódulo em lote de plano de fundo que faz o truque.
fonte
Entenda cuidadosamente a API do lote e estes módulos ajudarão você a:
1- Progerss Esta é uma tentativa de implementar uma estrutura genérica para acompanhar qualquer progresso
2- O progresso em segundo plano assume a API em lote existente e executa tarefas em lote em um processo em segundo plano
fonte