Primeiro commit
Signed-off-by: Rodrigo Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
commit
a1beb6a2e0
425 files changed
+193665
No files matched your search
@@ -0,0 +1,507 @@
|
||||
<?php
|
||||
// process_queue.php
|
||||
|
||||
ini_set('memory_limit', '512M');
|
||||
date_default_timezone_set('America/Araguaina');
|
||||
|
||||
// Aumentar o tempo máximo de execução do script para 300 segundos (5 minutos)
|
||||
set_time_limit(300);
|
||||
|
||||
// Verifique se a extensão `pcntl` está disponível
|
||||
if (!function_exists('pcntl_fork')) {
|
||||
die("A extensão pcntl não está disponível. Por favor, habilite-a para continuar.\n");
|
||||
}
|
||||
|
||||
// Definir o número máximo de processos filhos
|
||||
define('MAX_CHILDREN', 3);
|
||||
|
||||
$childProcesses = [];
|
||||
|
||||
// Função para registrar logs
|
||||
function log_message($message, $level = 'INFO') {
|
||||
$timestamp = date("Y-m-d H:i:s P"); // Inclui o fuso horário
|
||||
// Apenas logar mensagens de nível INFO, ERROR e WARN
|
||||
if (in_array($level, ['INFO', 'ERROR', 'WARN'])) {
|
||||
file_put_contents('/var/log/process_queue.log', "[$timestamp] [$level] $message\n", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
log_message("Script iniciado.", 'INFO');
|
||||
|
||||
function process_file($row) {
|
||||
// Cada processo filho deve estabelecer sua própria conexão com o banco de dados
|
||||
$mysqli = new mysqli("10.15.0.42", "root", "34641747", "valida");
|
||||
|
||||
if ($mysqli->connect_error) {
|
||||
log_message("Connection failed: " . $mysqli->connect_error, 'ERROR');
|
||||
exit(1); // Sair com erro
|
||||
}
|
||||
|
||||
// Assegurar que as mensagens de log incluam o ID do processo
|
||||
$process_id = getmypid();
|
||||
log_message("Processo $process_id: Processando arquivo ID " . $row['id'] . ": " . $row['file_path'], 'INFO');
|
||||
|
||||
try {
|
||||
$file_path = $row['file_path'];
|
||||
$queue_id = $row['id'];
|
||||
$user_agent = $row['user_agent'];
|
||||
$ip_address = $row['ip_address'];
|
||||
$host_name = $row['host_name'];
|
||||
$access_time = $row['access_time'] . ' ' . date("P"); // Adiciona fuso horário
|
||||
$language = $row['language'];
|
||||
$referer = $row['referer'];
|
||||
$protocol = $row['protocol'];
|
||||
$connection = $row['connection'];
|
||||
$viewport_width = $row['viewport_width'];
|
||||
$viewport_height = $row['viewport_height'];
|
||||
$original_location = $row['original_location']; // Novo campo para localização original
|
||||
|
||||
// Recuperar a porta do cliente
|
||||
$result_port = $mysqli->query("SELECT port FROM client_ports WHERE queue_id = $queue_id");
|
||||
$client_port = $result_port->fetch_assoc()['port'] ?? 'N/A';
|
||||
$result_port->free();
|
||||
|
||||
// Atualizar status para 'processing'
|
||||
$stmt_update = $mysqli->prepare("UPDATE queue SET status = 'processing' WHERE id = ?");
|
||||
$stmt_update->bind_param("i", $queue_id);
|
||||
$stmt_update->execute();
|
||||
$stmt_update->close();
|
||||
|
||||
log_message("Processo $process_id: Atualizou status para 'processing' para o arquivo ID $queue_id.", 'INFO');
|
||||
|
||||
// Gerar checksums
|
||||
$checksums = generate_checksums($file_path);
|
||||
|
||||
// Capturar data e hora
|
||||
$file_datetime = get_file_datetime($file_path);
|
||||
|
||||
// Registrar timestamp usando OpenTimestamps
|
||||
$timestamp_result = register_timestamp_opentimestamps($file_path);
|
||||
$signature_time = date("d/m/Y H:i:s P"); // Inclui fuso horário
|
||||
|
||||
if ($timestamp_result['success']) {
|
||||
$ots_base64 = $timestamp_result['ots_base64'];
|
||||
|
||||
// Coletar dados do dispositivo
|
||||
$device_data = [
|
||||
'User Agent' => $user_agent,
|
||||
'IP Address' => $ip_address . ':' . $client_port,
|
||||
'Host Name' => $host_name,
|
||||
'Access Time' => $access_time,
|
||||
'Language' => $language,
|
||||
'Referer' => $referer,
|
||||
'Protocol' => $protocol,
|
||||
'Connection' => $connection,
|
||||
'Viewport Width' => $viewport_width,
|
||||
'Viewport Height' => $viewport_height,
|
||||
'Original Location' => $original_location // Adicionado
|
||||
];
|
||||
|
||||
// Gerar PDF
|
||||
$pdf_path = generate_pdf($file_path, [
|
||||
'name' => basename($file_path),
|
||||
'creation_time' => $file_datetime['creation_time'] . ' ' . date("P", filectime($file_path)),
|
||||
'modification_time' => $file_datetime['modification_time'] . ' ' . date("P", filemtime($file_path)),
|
||||
'upload_time' => $access_time,
|
||||
'signature_time' => $signature_time
|
||||
], $checksums, $device_data, $ots_base64);
|
||||
|
||||
// Atualizar status para 'completed'
|
||||
$stmt_complete = $mysqli->prepare("UPDATE queue SET status = 'completed' WHERE id = ?");
|
||||
$stmt_complete->bind_param("i", $queue_id);
|
||||
$stmt_complete->execute();
|
||||
$stmt_complete->close();
|
||||
|
||||
log_message("Processo $process_id: Processamento concluído para arquivo ID $queue_id: $file_path", 'INFO');
|
||||
} else {
|
||||
// Atualizar status para 'error'
|
||||
$stmt_error = $mysqli->prepare("UPDATE queue SET status = 'error' WHERE id = ?");
|
||||
$stmt_error->bind_param("i", $queue_id);
|
||||
$stmt_error->execute();
|
||||
$stmt_error->close();
|
||||
|
||||
log_message("Processo $process_id: Erro ao processar arquivo ID $queue_id: " . $timestamp_result['message'], 'ERROR');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Atualizar status para 'error'
|
||||
$stmt_exception = $mysqli->prepare("UPDATE queue SET status = 'error' WHERE id = ?");
|
||||
$stmt_exception->bind_param("i", $queue_id);
|
||||
$stmt_exception->execute();
|
||||
$stmt_exception->close();
|
||||
|
||||
log_message("Processo $process_id: Exceção ao processar arquivo ID $queue_id: " . $e->getMessage(), 'ERROR');
|
||||
}
|
||||
|
||||
$mysqli->close();
|
||||
log_message("Processo $process_id: Fechou conexão com o banco de dados para o arquivo ID $queue_id.", 'INFO');
|
||||
}
|
||||
|
||||
// Funções auxiliares (generate_checksums, get_file_datetime, register_timestamp_opentimestamps, generate_pdf)
|
||||
// Mantenha estas funções como estão no seu código original, sem alterações. Certifique-se de que as funções não dependam de conexões globais de banco de dados.
|
||||
|
||||
require_once __DIR__ . '../../vendor/autoload.php';
|
||||
|
||||
// Função para gerar checksums
|
||||
function generate_checksums($file_path) {
|
||||
log_message("Gerando checksums para $file_path", 'INFO');
|
||||
$start_time = microtime(true);
|
||||
|
||||
// Carregar o conteúdo do arquivo uma única vez
|
||||
$file_content = file_get_contents($file_path);
|
||||
|
||||
$checksums = [
|
||||
'sha256' => hash('sha256', $file_content),
|
||||
'sha512' => hash('sha512', $file_content),
|
||||
'md5' => hash('md5', $file_content)
|
||||
];
|
||||
|
||||
$end_time = microtime(true);
|
||||
log_message("Checksums gerados em " . round($end_time - $start_time, 4) . " segundos", 'INFO');
|
||||
return $checksums;
|
||||
}
|
||||
|
||||
// Função para capturar data e hora do arquivo
|
||||
function get_file_datetime($file_path) {
|
||||
log_message("Obtendo data e hora do arquivo para $file_path", 'INFO');
|
||||
$start_time = microtime(true);
|
||||
$creation_time = date("d/m/Y H:i:s P", filectime($file_path));
|
||||
$modification_time = date("d/m/Y H:i:s P", filemtime($file_path));
|
||||
$end_time = microtime(true);
|
||||
log_message("Data e hora obtidas em " . round($end_time - $start_time, 4) . " segundos", 'INFO');
|
||||
return [
|
||||
'creation_time' => $creation_time,
|
||||
'modification_time' => $modification_time
|
||||
];
|
||||
}
|
||||
|
||||
// Função para registrar timestamp usando OpenTimestamps
|
||||
function register_timestamp_opentimestamps($file_path) {
|
||||
log_message("Registrando timestamp para $file_path", 'INFO');
|
||||
$start_time = microtime(true);
|
||||
|
||||
// Definir diretório de cache para OTS
|
||||
$ots_cache_dir = '/var/www/html/ots_cache';
|
||||
if (!is_dir($ots_cache_dir)) {
|
||||
log_message("Diretório de cache OTS não existe. Criando em $ots_cache_dir", 'INFO');
|
||||
if (!mkdir($ots_cache_dir, 0755, true)) {
|
||||
log_message("Erro ao criar diretório de cache OTS: $ots_cache_dir", 'ERROR');
|
||||
return ['success' => false, 'message' => "Erro ao criar diretório de cache OTS: $ots_cache_dir"];
|
||||
}
|
||||
chmod($ots_cache_dir, 0755); // Ajustar permissões
|
||||
}
|
||||
|
||||
// Definir a variável de ambiente antes de executar o comando
|
||||
$command_stamp = "OTS_CACHE_DIRECTORY=" . escapeshellarg($ots_cache_dir) . " ots stamp " . escapeshellarg($file_path) . " 2>&1";
|
||||
|
||||
log_message("Comando para executar: $command_stamp", 'INFO');
|
||||
|
||||
// Executar o comando
|
||||
exec($command_stamp, $output_stamp, $return_var_stamp);
|
||||
|
||||
// Verificar o resultado da execução
|
||||
if ($return_var_stamp !== 0) {
|
||||
log_message("Erro ao registrar timestamp: " . implode("\n", $output_stamp), 'ERROR');
|
||||
return ['success' => false, 'message' => 'Erro ao registrar timestamp: ' . implode("\n", $output_stamp)];
|
||||
}
|
||||
|
||||
// Definir o caminho do arquivo .ots gerado
|
||||
$ots_file = "{$file_path}.ots";
|
||||
|
||||
// Verificar se o arquivo .ots foi criado
|
||||
if (!file_exists($ots_file)) {
|
||||
log_message("Arquivo de timestamp não encontrado: $ots_file", 'ERROR');
|
||||
return ['success' => false, 'message' => "Arquivo de timestamp não encontrado: $ots_file"];
|
||||
}
|
||||
|
||||
// Codificar o arquivo .ots em base64
|
||||
$ots_base64 = base64_encode(file_get_contents($ots_file));
|
||||
$end_time = microtime(true);
|
||||
log_message("Timestamp registrado e codificado em " . round($end_time - $start_time, 4) . " segundos", 'INFO');
|
||||
|
||||
return ['success' => true, 'ots_base64' => $ots_base64];
|
||||
}
|
||||
|
||||
// Função para gerar PDF
|
||||
function generate_pdf($uploaded_file_path, $document_info, $checksums, $device_data, $ots_base64) {
|
||||
log_message("Gerando PDF para $uploaded_file_path", 'INFO');
|
||||
$start_time = microtime(true);
|
||||
// Criar uma nova instância do TCPDF
|
||||
$pdf = new TCPDF();
|
||||
|
||||
// Configurações iniciais do PDF
|
||||
$pdf->SetCreator(PDF_CREATOR);
|
||||
$pdf->SetAuthor('Seu Nome ou Empresa');
|
||||
$pdf->SetTitle('Prova de Autenticidade de Documento');
|
||||
$pdf->SetSubject('Timestamping e Checksums');
|
||||
|
||||
// Remover as margens padrão
|
||||
$pdf->SetMargins(10, 10, 10);
|
||||
$pdf->SetHeaderMargin(0);
|
||||
$pdf->SetFooterMargin(0);
|
||||
|
||||
// Desativar cabeçalhos e rodapés automáticos
|
||||
$pdf->setPrintHeader(false);
|
||||
$pdf->setPrintFooter(false);
|
||||
|
||||
// Configurar a fonte padrão uma vez
|
||||
$pdf->SetFont('helvetica', '', 10);
|
||||
|
||||
// Adicionar uma página para o documento
|
||||
$pdf->AddPage();
|
||||
|
||||
// Verificar o tipo de arquivo para incorporar no PDF
|
||||
$file_info = pathinfo($uploaded_file_path);
|
||||
$extension = strtolower($file_info['extension']);
|
||||
|
||||
// Configurar o diretório temporário para o ImageMagick
|
||||
$temp_dir = '/tmp/imagick';
|
||||
if (!is_dir($temp_dir)) {
|
||||
mkdir($temp_dir, 0777, true);
|
||||
}
|
||||
chmod($temp_dir, 0777); // Garantir permissões totais
|
||||
|
||||
// Configurar o diretório temporário para as imagens
|
||||
$tmp_dir = '/tmp/image';
|
||||
if (!is_dir($tmp_dir)) {
|
||||
mkdir($tmp_dir, 0777, true);
|
||||
}
|
||||
chmod($tmp_dir, 0777); // Garantir permissões totais
|
||||
|
||||
// Criar uma única instância de Imagick
|
||||
$imagick = new Imagick();
|
||||
// Configurar o ambiente para otimização
|
||||
putenv('MAGICK_TMPDIR=' . $temp_dir); // Defina um diretório temporário adequado
|
||||
$imagick->setResourceLimit(Imagick::RESOURCETYPE_MEMORY, 512); // Ajuste conforme necessário
|
||||
$imagick->setResourceLimit(Imagick::RESOURCETYPE_MAP, 512);
|
||||
$imagick->setResourceLimit(Imagick::RESOURCETYPE_THREAD, 2);
|
||||
|
||||
try {
|
||||
if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif'])) {
|
||||
log_message("Processando imagem $uploaded_file_path", 'INFO');
|
||||
|
||||
// Reduzir a resolução para 1200x900, mantendo a proporção
|
||||
log_message("Reduzindo resolução da imagem para melhor qualidade e menor tamanho", 'INFO');
|
||||
$imagick->readImage($uploaded_file_path);
|
||||
$imagick->resizeImage(1200, 900, Imagick::FILTER_LANCZOS, 1, true);
|
||||
|
||||
// Configurar a compressão usando PNG para melhor qualidade sem perder transparência
|
||||
if ($extension === 'png') {
|
||||
$imagick->setImageFormat('png');
|
||||
$imagick->stripImage(); // Remove metadados
|
||||
$image_blob = $imagick->getImageBlob();
|
||||
} else {
|
||||
// Para JPEG e outros, usar alta qualidade com compressão balanceada
|
||||
log_message("Configurando compressão da imagem para JPEG", 'INFO');
|
||||
$imagick->setImageCompression(Imagick::COMPRESSION_JPEG);
|
||||
$imagick->setImageCompressionQuality(85); // Maior qualidade
|
||||
$imagick->stripImage(); // Remove metadados para reduzir o tamanho
|
||||
$image_blob = $imagick->getImageBlob();
|
||||
}
|
||||
|
||||
// Salvar a imagem temporariamente
|
||||
$tmp_img = tempnam($tmp_dir, 'img_') . '.' . $extension;
|
||||
log_message("Salvando imagem temporária em $tmp_img", 'INFO');
|
||||
file_put_contents($tmp_img, $image_blob);
|
||||
chmod($tmp_img, 0666); // Ajustar permissões do arquivo temporário
|
||||
|
||||
// Adicionar a imagem ao PDF
|
||||
log_message("Adicionando imagem ao PDF", 'INFO');
|
||||
$pdf->Image('@' . $image_blob, 15, 40, 180, 160, '', '', 'C', false, 100, '', false, false, 1, false, false, false);
|
||||
log_message("Imagem adicionada ao PDF", 'INFO');
|
||||
|
||||
// Remover a imagem temporária
|
||||
if (file_exists($tmp_img)) {
|
||||
log_message("Removendo imagem temporária $tmp_img", 'INFO');
|
||||
unlink($tmp_img);
|
||||
} else {
|
||||
log_message("Imagem temporária $tmp_img não encontrada para remoção", 'WARN');
|
||||
}
|
||||
} elseif (in_array($extension, ['pdf'])) {
|
||||
log_message("Processando PDF $uploaded_file_path", 'INFO');
|
||||
|
||||
// Verificar se a extensão Imagick está carregada
|
||||
if (extension_loaded('imagick')) {
|
||||
log_message("Imagick está carregado", 'INFO');
|
||||
|
||||
// Inicializar Imagick
|
||||
try {
|
||||
log_message("Inicializando Imagick para $uploaded_file_path", 'INFO');
|
||||
$imagick = new Imagick();
|
||||
$imagick->setResolution(150, 150); // Ajuste a resolução conforme necessário
|
||||
$imagick->readImage($uploaded_file_path); // Ler todas as páginas do PDF
|
||||
log_message("PDF lido com sucesso", 'INFO');
|
||||
|
||||
// Processar cada página do PDF
|
||||
$page_count = $imagick->getNumberImages(); // Número total de páginas do PDF
|
||||
for ($i = 0; $i < $page_count; $i++) {
|
||||
$imagick->setIteratorIndex($i); // Define a página atual
|
||||
$imagick->setImageFormat("jpeg"); // Configura o formato como JPEG
|
||||
|
||||
// Reduz a resolução para 1600x1200, mantendo a proporção
|
||||
$imagick->resizeImage(1600, 1200, Imagick::FILTER_LANCZOS, 1, true);
|
||||
|
||||
// Configura as opções de compressão
|
||||
$imagick->setImageCompression(Imagick::COMPRESSION_JPEG);
|
||||
$imagick->setImageCompressionQuality(85);
|
||||
$imagick->stripImage(); // Remove metadados desnecessários
|
||||
|
||||
// Obter os dados da imagem
|
||||
$image_data = $imagick->getImageBlob();
|
||||
$tmp_img = tempnam($tmp_dir, 'pdf_page_') . '.jpg';
|
||||
file_put_contents($tmp_img, $image_data); // Salvar página como JPEG temporária
|
||||
chmod($tmp_img, 0666);
|
||||
|
||||
// Adicionar a página como imagem ao novo PDF
|
||||
$pdf->AddPage();
|
||||
$pdf->Image($tmp_img, 15, 40, 180, 160, '', '', 'C', false, 100, '', false, false, 1, false, false, false);
|
||||
|
||||
// Remover a imagem temporária
|
||||
unlink($tmp_img);
|
||||
}
|
||||
|
||||
// Limpar recursos do Imagick
|
||||
$imagick->clear();
|
||||
$imagick->destroy();
|
||||
} catch (Exception $e) {
|
||||
log_message("Erro ao inicializar ou processar imagem com Imagick: " . $e->getMessage(), 'ERROR');
|
||||
}
|
||||
} else {
|
||||
log_message("Imagick não está carregado", 'WARN');
|
||||
// Se Imagick não estiver disponível, apenas adicionar uma mensagem
|
||||
$pdf->SetFont('helvetica', '', 12);
|
||||
$pdf->Write(0, 'Visualização de PDF não suportada.');
|
||||
}
|
||||
} else {
|
||||
log_message("Tipo de arquivo não suportado: $extension", 'WARN');
|
||||
// Outros tipos de arquivo podem ser adicionados conforme necessidade
|
||||
$pdf->SetFont('helvetica', '', 12);
|
||||
$pdf->Write(0, 'Visualização deste tipo de arquivo não está disponível.');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
log_message("Erro ao processar imagem: " . $e->getMessage(), 'ERROR');
|
||||
}
|
||||
|
||||
// Adicionar uma nova página para as informações
|
||||
$pdf->AddPage();
|
||||
|
||||
// Conteúdo das informações
|
||||
$html = '<h2>Informações do Documento</h2>';
|
||||
$html .= '<p><strong>Nome do Arquivo:</strong> ' . htmlspecialchars($document_info['name']) . '</p>';
|
||||
$html .= '<p><strong>Data de Modificação:</strong> ' . htmlspecialchars($document_info['modification_time']) . '</p>';
|
||||
$html .= '<p><strong>Data de Envio ao Servidor:</strong> ' . htmlspecialchars($document_info['upload_time']) . '</p>';
|
||||
$html .= '<p><strong>Data e Hora da Assinatura:</strong> ' . htmlspecialchars($document_info['signature_time']) . ' (UTC-3)</p>';
|
||||
|
||||
$html .= '<h3>Checksums</h3>';
|
||||
$html .= '<ul>';
|
||||
$html .= '<li><strong>SHA-256:</strong> ' . htmlspecialchars($checksums['sha256']) . '</li>';
|
||||
$html .= '<li><strong>SHA-512:</strong> ' . htmlspecialchars($checksums['sha512']) . '</li>';
|
||||
$html .= '<li><strong>MD5:</strong> ' . htmlspecialchars($checksums['md5']) . '</li>';
|
||||
$html .= '</ul>';
|
||||
|
||||
$html .= '<h3>Dados do Dispositivo</h3>';
|
||||
$html .= '<ul>';
|
||||
foreach ($device_data as $key => $value) {
|
||||
$html .= '<li><strong>' . htmlspecialchars((string)$key) . ':</strong> ' . htmlspecialchars((string)$value) . '</li>';
|
||||
}
|
||||
$html .= '</ul>';
|
||||
|
||||
$orig_link= 'https://validar.martinsevieira.adv.br/uploads/';
|
||||
|
||||
$html .= '<h3>Arquivos Originais</h3>';
|
||||
$html .= '<ul>';
|
||||
$html .= '<li><a href="' . $orig_link . $document_info['name'] . '">Arquivo Original</a></li>';
|
||||
$html .= '<li><a href="' . $orig_link . $document_info['name'] . '.ots">Arquivo OTS</a></li>';
|
||||
$html .= '</ul>';
|
||||
|
||||
$html .= '<h3>Arquivo de Timestamp (OTS) em Base64</h3>';
|
||||
$html .= '<pre>' . htmlspecialchars($ots_base64) . '</pre>';
|
||||
|
||||
$pdf->writeHTML($html, true, false, true, false, '');
|
||||
|
||||
// Salvar o PDF no servidor
|
||||
$processed_dir = '/var/www/html/processed/';
|
||||
if (!is_dir($processed_dir)) {
|
||||
mkdir($processed_dir, 0777, true);
|
||||
}
|
||||
log_message("Salvando PDF no servidor", 'INFO');
|
||||
$pdf_output_path = $processed_dir . uniqid('prova_') . '.pdf';
|
||||
$pdf->Output($pdf_output_path, 'F');
|
||||
|
||||
$end_time = microtime(true);
|
||||
log_message("PDF gerado em " . round($end_time - $start_time, 4) . " segundos", 'INFO');
|
||||
|
||||
// Limpar recursos do Imagick
|
||||
$imagick->clear();
|
||||
$imagick->destroy();
|
||||
|
||||
return $pdf_output_path;
|
||||
}
|
||||
|
||||
// Recuperar todos os arquivos pendentes
|
||||
$mysqli = new mysqli("10.15.0.42", "root", "34641747", "valida");
|
||||
|
||||
if ($mysqli->connect_error) {
|
||||
log_message("Connection failed: " . $mysqli->connect_error, 'ERROR');
|
||||
die("Connection failed: " . $mysqli->connect_error);
|
||||
}
|
||||
|
||||
log_message("Conexão com o banco de dados estabelecida.", 'INFO');
|
||||
|
||||
// Recuperar todos os arquivos pendentes
|
||||
$result = $mysqli->query("SELECT q.*, cp.port, q.original_location FROM queue q LEFT JOIN client_ports cp ON q.id = cp.queue_id WHERE q.status = 'pending'");
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
log_message("Encontrados " . $result->num_rows . " arquivos pendentes para processar.", 'INFO');
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
// Verificar se o número de processos filhos atingiu o máximo permitido
|
||||
while (count($childProcesses) >= MAX_CHILDREN) {
|
||||
// Esperar por qualquer processo filho terminar
|
||||
$endedPid = pcntl_wait($status);
|
||||
if ($endedPid > 0) {
|
||||
unset($childProcesses[$endedPid]);
|
||||
log_message("Processo filho $endedPid finalizado.", 'INFO');
|
||||
}
|
||||
}
|
||||
|
||||
// Fork do processo
|
||||
$pid = pcntl_fork();
|
||||
|
||||
if ($pid == -1) {
|
||||
// Erro ao fork
|
||||
log_message("Erro ao criar processo filho.", 'ERROR');
|
||||
} elseif ($pid) {
|
||||
// Processo pai
|
||||
$childProcesses[$pid] = true;
|
||||
log_message("Criado processo filho $pid para o arquivo ID " . $row['id'] . ".", 'INFO');
|
||||
} else {
|
||||
// Processo filho
|
||||
// Fecha a conexão do processo pai antes de iniciar no filho
|
||||
$mysqli->close();
|
||||
|
||||
// Processa o arquivo
|
||||
process_file($row);
|
||||
|
||||
// Finaliza o processo filho
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Após forçar todos os filhos a serem criados, esperar que terminem
|
||||
while (count($childProcesses) > 0) {
|
||||
$endedPid = pcntl_wait($status);
|
||||
if ($endedPid > 0) {
|
||||
unset($childProcesses[$endedPid]);
|
||||
log_message("Processo filho $endedPid finalizado.", 'INFO');
|
||||
}
|
||||
}
|
||||
|
||||
log_message("Todas as tarefas foram submetidas para processamento.", 'INFO');
|
||||
} else {
|
||||
log_message("Nenhum arquivo pendente para processar.", 'INFO');
|
||||
}
|
||||
|
||||
$mysqli->close();
|
||||
log_message("Processamento da fila finalizado.", 'INFO');
|
||||
?>
|
||||
|
||||
Reference in new issue
Block a user