Publicado em: 17, março 2025
No desenvolvimento de aplicações web, é comum enfrentar tarefas demoradas, como a importação de grandes arquivos CSV para um banco de dados. Executar essas tarefas de forma sequencial pode resultar em tempos de resposta longos e uma experiência ruim para o usuário. Felizmente, o Laravel oferece a facade Concurrency (atualmente em beta) para executar processos em concorrência, permitindo que várias tarefas sejam realizadas simultaneamente, otimizando a performance. Neste artigo, vamos explorar como usar essa funcionalidade com um exemplo prático: importar grandes arquivos CSV.
A facade Concurrency do Laravel fornece uma API simples para executar closures (funções anônimas) em processos PHP separados, de forma concorrente. Isso é especialmente útil quando você tem tarefas independentes e lentas, como consultas a bancos de dados ou processamento de arquivos. A funcionalidade está em fase beta, mas já é poderosa o suficiente para casos reais.
Para começar, se você atualizou do Laravel 10.x para o 11.x, pode ser necessário adicionar o ConcurrencyServiceProvider ao arquivo config/app.php:
'providers' => ServiceProvider::defaultProviders()->merge([ Illuminate\\Concurrency\\ConcurrencyServiceProvider::class, App\\Providers\\AppServiceProvider::class, *// Outros providers...* ])->toArray(),
O Laravel serializa as closures fornecidas e as despacha para um comando Artisan oculto, que as executa em processos PHP separados. Os resultados são então serializados de volta ao processo principal. Há três drivers disponíveis:
Para usar o driver fork, instale o pacote necessário:
composer require spatie/fork
Imagine que você precisa importar um arquivo CSV com milhares de linhas contendo dados de usuários. Vamos dividir o arquivo em partes e processá-las em concorrência.
Aqui está um exemplo de código:
use Illuminate\\Support\\Facades\\Concurrency; use Illuminate\\Support\\Facades\\DB; public function importLargeCsv() { $filePath = storage_path('app/large_file.csv'); $rows = array_map('str_getcsv', file($filePath)); $chunks = array_chunk($rows, 1000); *// Divide em blocos de 1000 linhas* $tasks = array_map(function ($chunk) { return function () use ($chunk) { foreach ($chunk as $row) { DB::table('users')->insert([ 'name' => $row[0], 'email' => $row[1], 'created_at' => now(), 'updated_at' => now(), ]); } }; }, $chunks); *// Executa as tarefas em concorrência* Concurrency::run($tasks); return response()->json(['message' => 'Importação concluída com sucesso!']); }
Nesse exemplo:
Se preferir o driver fork para melhor performance em CLI:
Concurrency::driver('fork')->run($tasks);
Se a importação não precisa retornar um resultado imediato ao usuário, você pode usar o método defer. Ele executa as tarefas em concorrência após o envio da resposta HTTP, ideal para processos em segundo plano:
Concurrency::defer($tasks); return response()->json(['message' => 'Importação iniciada em segundo plano!']);
A facade Concurrency do Laravel é uma ferramenta poderosa para lidar com tarefas pesadas, como a importação de grandes arquivos CSV. Ao dividir o trabalho em processos concorrentes, você pode reduzir significativamente o tempo de execução e melhorar a experiência do usuário. Experimente os drivers disponíveis e ajuste conforme o contexto da sua aplicação (web ou CLI). Com essa abordagem, suas importações nunca mais serão um gargalo!
Mais de 10 anos de experiência com Laravel e sólidos conhecimentos em frameworks front-end, como ReactJS, React Native e Vue JS. Experiência em Design de Serviço. No primeiro projeto profissional como júnior, desenvolveu em e-commerce para a maior indústria de equipamentos odontológicos da América Latina. Atualmente, atua como Full Stack Engineer Specialist em uma grande multinacional. Lidera decisões técnicas e é um suporte fundamental para a equipe de desenvolvimento.