Este pacote facilita a execução simultânea do PHP. Nos bastidores, a simultaneidade é alcançada bifurcando o processo PHP principal para uma ou mais tarefas filhas.
Neste exemplo, onde chamaremos uma API lenta imaginária, todos os três encerramentos serão executados ao mesmo tempo.
use Spatie Fork Fork ;
$ results = Fork:: new ()
-> run (
fn () => ( new Api )-> fetchData (userId: 1 ),
fn () => ( new Api )-> fetchData (userId: 2 ),
fn () => ( new Api )-> fetchData (userId: 3 ),
);
$ results [ 0 ]; // fetched data of user 1
$ results [ 1 ]; // fetched data of user 2
$ results [ 2 ]; // fetched data of user 3
Neste vídeo no YouTube explicamos como o pacote funciona internamente.
Investimos muitos recursos na criação dos melhores pacotes de código aberto. Você pode nos apoiar comprando um de nossos produtos pagos.
Agradecemos muito que você nos envie um cartão postal de sua cidade natal, mencionando qual(is) de nossos pacotes você está usando. Você encontrará nosso endereço em nossa página de contato. Publicamos todos os cartões postais recebidos em nosso mural virtual de cartões postais.
Este pacote requer PHP 8 e as extensões pcntl que são instaladas em muitos sistemas Unix e Mac por padrão.
pcntl funciona apenas em processos CLI, não em um contexto web. posix necessário para o tratamento correto do encerramento do processo para Alpine Linux.
Você pode instalar o pacote via compositor:
composer require spatie/fork
Você pode passar por quantos encerramentos desejar run
. Eles serão executados simultaneamente. A função run
retornará um array com os valores de retorno dos fechamentos executados.
use Spatie Fork Fork ;
$ results = Fork:: new ()
-> run (
function () {
sleep ( 1 );
return ' result from task 1 ' ;
},
function () {
sleep ( 1 );
return ' result from task 2 ' ;
},
function () {
sleep ( 1 );
return ' result from task 3 ' ;
},
);
// this code will be reached this point after 1 second
$ results [ 0 ]; // contains 'result from task 1'
$ results [ 1 ]; // contains 'result from task 2'
$ results [ 2 ]; // contains 'result from task 3'
Se você precisar executar algum código antes ou depois de cada callable passado para run
, você pode passar um callable para métodos before
ou after
. Este callable passado será executado no processo filho logo antes ou depois da execução do callable passado para run
.
before
e after
na tarefa filho Aqui está um exemplo onde obteremos um valor do banco de dados usando um modelo Laravel Eloquent. Para permitir que a tarefa filho utilize o banco de dados, é necessário reconectar-se ao banco de dados. O encerramento passado para before
será executado em ambas as tarefas filhas criadas para os encerramentos passados para run
.
use App Models User ;
use Illuminate Support Facades DB ;
use Spatie Fork Fork ;
Fork:: new ()
-> before ( fn () => DB :: connection ( ' mysql ' )-> reconnect ())
-> run (
fn () => User:: find ( 1 )-> someLongRunningFunction (),
fn () => User:: find ( 2 )-> someLongRunningFunction (),
);
Se precisar realizar alguma limpeza na tarefa filho após a execução do chamável, você pode usar o método after
em uma instância SpatieForkFork
.
before
e after
na tarefa pai. Se você precisar permitir que o callable seja passado before
ou after
da execução na tarefa pai, será necessário passar esse callable para o argumento parent
.
use App Models User ;
use Illuminate Support Facades DB ;
use Spatie Fork Fork ;
Fork:: new ()
-> before (
parent: fn () => echo ' this runs in the parent task '
)
-> run (
fn () => User:: find ( 1 )-> someLongRunningFunction (),
fn () => User:: find ( 2 )-> someLongRunningFunction (),
);
Você também pode passar encerramentos diferentes, para serem executados na tarefa filha e na tarefa pai
use Spatie Fork Fork ;
Fork:: new ()
-> before (
child: fn () => echo ' this runs in the child task ' ,
parent: fn () => echo ' this runs in the parent task ' ,
)
-> run (
fn () => User:: find ( 1 )-> someLongRunningFunction (),
fn () => User:: find ( 2 )-> someLongRunningFunction (),
);
Todos os dados de saída são reunidos em uma matriz e disponibilizados assim que todos os filhos terminam. Neste exemplo, $results
conterá três itens:
$ results = Fork:: new ()
-> run (
fn () => ( new Api )-> fetchData (userId: 1 ),
fn () => ( new Api )-> fetchData (userId: 2 ),
fn () => ( new Api )-> fetchData (userId: 3 ),
);
A saída também está disponível nos retornos de chamada after
, que são chamados sempre que um filho termina e não no final:
$ results = Fork:: new ()
-> after (
child: fn ( int $ i ) => echo $ i , // 1, 2 and 3
parent: fn ( int $ i ) => echo $ i , // 1, 2 and 3
)
-> run (
fn () => 1 ,
fn () => 2 ,
fn () => 3 ,
);
Finalmente, os valores de retorno das tarefas filhas são serializados usando o método serialize
integrado do PHP. Isso significa que você pode retornar qualquer coisa que normalmente serialize em PHP, incluindo objetos:
$ result = Fork:: new ()
-> run (
fn () => new DateTime ( ' 2021-01-01 ' ),
fn () => new DateTime ( ' 2021-01-02 ' ),
);
Por padrão, todos os callables serão executados em paralelo. No entanto, você pode configurar uma quantidade máxima de processos simultâneos:
$ results = Fork:: new ()
-> concurrent ( 2 )
-> run (
fn () => 1 ,
fn () => 2 ,
fn () => 3 ,
);
Neste caso, as duas primeiras funções serão executadas imediatamente e assim que uma delas terminar, a última também será iniciada.
composer test
Consulte CHANGELOG para obter mais informações sobre o que mudou recentemente.
Consulte CONTRIBUINDO para obter detalhes.
Revise nossa política de segurança sobre como relatar vulnerabilidades de segurança.
A licença MIT (MIT). Consulte Arquivo de licença para obter mais informações.