Solicitação de HTTP sem bloqueio com Guzzle

Sep 16 2020

Existe uma maneira do Drupal 8 de fazer uma solicitação de cliente HTTP sem bloqueio usando o Guzzle? Não preciso esperar pela resposta do post HTTP, pois isso está deixando o site mais lento.

Já vi solicitações HTTP assíncronas sem bloqueio , mas gostaria de saber se alguém tem uma solução Drupalier.

Respostas

1 ShawnConn Sep 20 2020 at 12:37

Não existe um "caminho Drupal 8". O Drupal 8 conta com o Guzzle como sua biblioteca cliente HTTP, portanto não possui uma solução embutida para isso.

Embora a biblioteca cliente Guzzle tenha GuzzleHttp\Client::requestAsync(), não é um método assíncrono sem bloqueio; o método será bloqueado assim que iniciar a solicitação de rede, pois precisa de dados de resposta para métodos de promessa.

Para fazer algo semelhante à sua pergunta vinculada (usando fsockopen()/ fwrite()para abrir um soquete, enviar cabeçalhos HTTP e fechar) com o Guzzle, você precisará usar um manipulador diferente dos fornecidos pelo Guzzle . Guzzle tem alguma documentação para fazer isso .

Deve-se observar que mesmo a solução vinculada não é bloqueadora no caso de haver problemas de conexão de rede (por exemplo, se o host estiver inacessível, fsockopen()foi $timeoutdefinido como 30, portanto, bloquearia por 30s antes de atingir o tempo limite). O PHP sendo de thread único evita a verdadeira execução assíncrona sem bloqueio no código PHP.

DavidThomas Sep 20 2020 at 16:34

Uma solução para este tipo de processamento é a seguinte:

Coloque o item na fila para um trabalhador de fila assíncrona para processamento, onde os itens estão sendo processados ​​constantemente. Nesse caso, usando RabbitMQ, que melhora a fila cron principal com um recurso de processamento de fila imediato.

  1. Instale RabbitMQ ehttps://www.drupal.org/project/rabbitmq
  2. Adicionar o item à fila (incluir settings.php $settings['queue_service_my_queue_name'] = 'queue.rabbitmq.default';)
// Some data to send to the queue
$data = ['nid' => 12, 'url' => 'https://example.com/api'];
// Get the queue config
$queue_factory = \Drupal::service('queue'); $queue = $queue_factory->get('my_queue_name'); // Send data to the queue $queue->createItem($data);
  1. Defina seu plug- in QueueWorker (observação: não há necessidade de cronanotação do trabalhador na fila)

  2. Processe a fila com drush rabbitmq-worker my_queue_name

  3. Adicione um gerenciador de processo, como supervisord, ou você pode usar kubernetes, para manter o drushprocesso de trabalho da fila.

Essa abordagem é bem dimensionada e os itens da fila podem ser processados ​​imediatamente e de forma assíncrona, em outro processo de trabalho da fila.