Execução de processos em segundo plano
Assim que tivermos um processo em segundo plano, está na hora de nos comunicarmos com ele.
Visto que o processo está "desgarrado" do processo que o criou, será necessário definir um canal de troca de informações. Há algumas possibilidade para este canal, entre elas: banco de dados e arquivos. Não vou explorar o uso de bancos de dados como canal de comunicação pois o objetivo do artigo é usar uma conexão permanente a um banco de dados entre várias sessões.
O uso de arquivo para troca de dados e controle de processos é muito utilizado em sistemas de controle de versões (CVS). A técnica utilizada é bastante semelhante, podendo tornar-se mais complexa de acordo com a necessidade.
Para um exemplo básico, será feito um script que envia comandos SQL e os retorna em formato CSV com a primeira linha sendo o cabeçalho.
O controle do processo
O controle da execução do processo deve garantir a leitura dos dados e entrada, a execução do processamento e a saída do retorno.
Como nosso processo será acessado via arquivos, serão necessários três arquivos:
.exec - Será usado como sinalizador de andamento do processo, sua existência define que o processo está em andamento, sua ausência indica o oposto.
.in - Será a entrada de dados. Se houver bytes disponíveis no arquivo, significará que há dados a processar, ao final do processo, o arquivo será truncado e a ausência de bytes indicará que o processo deve aguardar.
.out - É a saída dos dados. Só possuirá dados válidos quando o arquivo .in não possuir um byte sequer.
O processo
O processo pode ser programado da seguinte maneira:
As linhas 2 e 3 já foram explicadas anteriormente.
Na linha 5 é criado o arquivo .exec, sinalizando o início do processo.
Na linha 7 está o corpo de controle do processo, que é executado contínuamente enquanto existir o arquivo .exec. Na linha 32 é visto um artifício para poupar recursos do servidor e retomar o processo a cada 1 segundo.
Na linha 11 está um comando necessário para atualizar os dados sobre os arquivos utilizados, sem ele o processo trabalha sobre dados em buffer e não tem o comportamento esperado.
Na linha 12 é visto o processo de entrada de dados, ou seja, quando ouver bytes em .in, estes são processados.
Entre as linhas 13 e 30está o controle da execução do processo. Este consiste em ler a consulta do arquivo de entrada, executá-la e escrever a saída no arquivo .out no formato CSV.
Ao final, na linha 29 o arquivo .out é fechado e o arquivo .in é truncado, setando seu tamanho para 0, ou seja, validando os dados da saída.
E desta forma o processo continua enquanto não vencer o tempo limite do script ou o arquivo .exec ser removido.
Visto que o processo está "desgarrado" do processo que o criou, será necessário definir um canal de troca de informações. Há algumas possibilidade para este canal, entre elas: banco de dados e arquivos. Não vou explorar o uso de bancos de dados como canal de comunicação pois o objetivo do artigo é usar uma conexão permanente a um banco de dados entre várias sessões.
O uso de arquivo para troca de dados e controle de processos é muito utilizado em sistemas de controle de versões (CVS). A técnica utilizada é bastante semelhante, podendo tornar-se mais complexa de acordo com a necessidade.
Para um exemplo básico, será feito um script que envia comandos SQL e os retorna em formato CSV com a primeira linha sendo o cabeçalho.
O controle do processo
O controle da execução do processo deve garantir a leitura dos dados e entrada, a execução do processamento e a saída do retorno.
Como nosso processo será acessado via arquivos, serão necessários três arquivos:
.exec - Será usado como sinalizador de andamento do processo, sua existência define que o processo está em andamento, sua ausência indica o oposto.
.in - Será a entrada de dados. Se houver bytes disponíveis no arquivo, significará que há dados a processar, ao final do processo, o arquivo será truncado e a ausência de bytes indicará que o processo deve aguardar.
.out - É a saída dos dados. Só possuirá dados válidos quando o arquivo .in não possuir um byte sequer.
O processo
O processo pode ser programado da seguinte maneira:
<?php set_time_limit(7200); ignore_user_abort(true); fopen('./.exec','w'); $conn = mysql_connect($servidor,$usuario,$senha); mysql_select_db($bdados); while (file_exists('./.exec')) { clearstatcache(); if (file_exists('./.in') && filesize('./.in')) { $out = fopen('./.out','w'); $query = mysql_query(file_get_contents('./.in')); $campos = mysql_num_fields($query); $sep = ''; for ($i = 0; $i < $campos; $i++) { fwrite($out,$sep.mysql_field_name($query,$i)); $sep = ';'; } fwrite($out,"\n"); while ($res = mysql_fetch_row($query)) { for ($i = 1; $i < $campos; $i++) { fwrite($out,$sep.$res[$i]); $sep = ';'; } fwrite($out,"\n"); } fclose($out); fclose(fopen('./.in','w')); } sleep(1); } ?>
As linhas 2 e 3 já foram explicadas anteriormente.
Na linha 5 é criado o arquivo .exec, sinalizando o início do processo.
Na linha 7 está o corpo de controle do processo, que é executado contínuamente enquanto existir o arquivo .exec. Na linha 32 é visto um artifício para poupar recursos do servidor e retomar o processo a cada 1 segundo.
Na linha 11 está um comando necessário para atualizar os dados sobre os arquivos utilizados, sem ele o processo trabalha sobre dados em buffer e não tem o comportamento esperado.
Na linha 12 é visto o processo de entrada de dados, ou seja, quando ouver bytes em .in, estes são processados.
Entre as linhas 13 e 30está o controle da execução do processo. Este consiste em ler a consulta do arquivo de entrada, executá-la e escrever a saída no arquivo .out no formato CSV.
Ao final, na linha 29 o arquivo .out é fechado e o arquivo .in é truncado, setando seu tamanho para 0, ou seja, validando os dados da saída.
E desta forma o processo continua enquanto não vencer o tempo limite do script ou o arquivo .exec ser removido.
Muito bom o artigo, irei colocar em prática e passo o que tive de experiência
11/07/2009 6:22pm
(~15 anos atrás)
Não sabia que tinha como executar em segundo plano em PHP, funciona simulando um pequeno ambiente Thread.