Solicitud HTTP sin bloqueo con Guzzle
¿Existe una forma de Drupal 8 para realizar solicitudes de cliente HTTP sin bloqueo usando Guzzle? No necesito esperar la respuesta de la publicación HTTP, ya que eso ralentiza el sitio.
Ya vi solicitudes HTTP asincrónicas sin bloqueo , pero quiero saber si alguien tiene una solución Drupalier.
Respuestas
No hay "Drupal 8 way". Drupal 8 se basa en Guzzle como su biblioteca de cliente HTTP, por lo que no tiene una solución incorporada para esto.
Si bien la biblioteca cliente de Guzzle tiene GuzzleHttp\Client::requestAsync(), no es un método asincrónico sin bloqueo; el método se bloqueará una vez que haya iniciado la solicitud de red, ya que necesita datos de respuesta para los métodos de promesa.
Para hacer algo similar a su pregunta vinculada (usar fsockopen()/ fwrite()para abrir un socket, enviar encabezados HTTP y cerrar) con Guzzle, deberá usar un controlador diferente a los que proporciona Guzzle por defecto . Guzzle tiene algo de documentación para hacer esto .
Cabe señalar que incluso la solución vinculada no es sin bloqueo en caso de que haya problemas de conexión de red (por ejemplo, si el host no está disponible, se fsockopen()ha $timeoutconfigurado en 30, por lo que se bloqueará durante 30 segundos antes de que se agote el tiempo de espera). PHP, que es de un solo subproceso, evita una verdadera ejecución asíncrona sin bloqueo dentro del código PHP.
Una solución para este tipo de procesamiento es la siguiente:
Ponga el elemento en cola a un trabajador de cola asíncrono para su procesamiento, donde los elementos se procesan constantemente. En este caso, se utiliza RabbitMQ, que mejora la cola cron central con una función de procesamiento de cola inmediato.
- Instale RabbitMQ yhttps://www.drupal.org/project/rabbitmq
- Agregar el artículo a la cola (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);
Defina su complemento QueueWorker (nota: no es necesario incluir una
cronanotación de trabajador en cola)Procesar la cola con
drush rabbitmq-worker my_queue_nameAgregue un administrador de procesos, como
supervisord, o puede usarkubernetes, para mantener eldrushproceso de trabajo en cola.
Este enfoque se escala bien y los elementos de la cola se pueden procesar tanto de forma inmediata como asincrónica, en otro proceso de trabajo de la cola.