Pregunta sobre Developing with WordPress de Wordpress:

wp_remote_request () muere silenciosamente

Un usuario preguntó 👇

Hola,

¿Se pregunta si hay casos en los que wp_remote_*() sabe salir de funciones silenciosamente?

Estoy usando wp_remote_request() como parte de una publicación de fondo, solicitada en WP_Cron), para vincular a la API de MailChimp.

Después de mucho seguimiento y depuración para tratar de averiguar por qué esta publicación de fondo parece morir silenciosamente por ciertas solicitudes, obtén eso wp_remote_request() parece morir en silencio y tomar el proceso del proceso PHP con él (no puedo recibir mensajes de error, advertencias, notificaciones).

El gestor de trabajos incluye un código de fondo para salir elegantemente previamente max_execution_time para superar.

Esto funciona como se esperaba en muchos otros lugares donde utilizo esta biblioteca de correo en segundo plano, por lo que no creo que el controlador de correo en segundo plano sea el problema aquí.

Pasé unas horas con una búsqueda en Google, pero no obtengo ejemplos de esto, así que pensé que lo probaría aquí.

(@ ochenta20 adultos)

Hace 2 años, 1 mes


private function execute( $url, $request ) {
		
		$utils = Utilities::get_instance();
		$utils->log("Executing remote request..."); // See this
		
		$start_of_request = current_time( 'timestamp' );
		$response         = wp_remote_request( $url, $request );
		$end_of_request   = current_time( 'timestamp' );
		
		$current_timeout_limit = floor( ( isset( $request['timeout'] ) ? $request['timeout'] : 60 ) * 0.8 );
		$time_of_request       = ( $end_of_request - $start_of_request );
		$max_php_execution     = ( intval( ini_get( 'max_execution_time' ) ) * 0.5 );
		
		$utils->log( "Request took {$time_of_request} seconds..." ); // Not seeing this!?!
		
		if ( $current_timeout_limit >= $max_php_execution ) {
			$msg = __( 'Error: Timeout >= half of PHP Max Execution Time!', Controller::plugin_slug );
			$utils->log( $msg );
			$utils->add_message( $msg, 'error', 'backend' );
		}
		
		// Extend the timeout value (dynamically)?
		if ( $current_timeout_limit < $time_of_request && $current_timeout_limit < $max_php_execution ) {
			$utils->log( "Have to extend the timeout value ({$time_of_request}) by 50%" );
			$this->url_args['timeout'] = $time_of_request + ceil( $time_of_request * .5 );
		}
		
		return $response;
	}

(@bcworkz)

Hace 2 años, 1 mes

Le recomiendo que verifique la respuesta wp_remote_request () para un objeto WP_Error. Puede enviar mensajes más detallados sobre lo que salió mal. Verifique con is_wp_error (). Si comete un error, puede usar WP_Error :: get_error_messages () y devolverlos a su esquema de inicio de sesión.

Sugerencia: Evite publicar respuestas a su propio contenido hasta que obtenga una respuesta. Cuando vuelves a publicar, tu contenido se cae de la lista «sin respuesta» que utilizan muchos controladores para encontrar a aquellos que todavía necesitan ayuda. Puede editar su OP durante 30 minutos si piensa en algo que deba agregarse.

(@ ochenta20 adultos)

Hace 2 años, 1 mes

Le recomiendo que verifique la respuesta wp_remote_request () para un objeto WP_Error.

Afortunadamente, es algo que ya hago (y no doy ninguna información en el caso anterior).


$resp = $this->execute( $url, $request ); // $resp = wp_remote_get( $url, $request );
$code = wp_remote_retrieve_response_code( $resp );
		
if ( is_wp_error( $resp ) || 200 > $code || 300 <= $code ) {
			
	$errors = $this->process_error( $resp );			
	$msg    = "Error getting info for {$user_data->ID}: {$errors->title} - {$errors->detail}";

	$utils->log( $msg );
						
	return false;
}

FWIW, no tenía una opción de «editar» después de enviar, así que el seguimiento subconsciente de mi trabajo.

(@bcworkz)

Hace 2 años, 1 mes

Verificar WP_Error no es lo mismo que verificar códigos de respuesta. Se puede obtener información más específica de la llamada a la función en lugar de una respuesta del servidor remoto.

Lamento que no hayas podido editar tu OP. Algo no está bien que debemos investigar.

(@ ochenta20 adultos)

Hace 2 años, 1 mes

Hola de nuevo.

Verificar WP_Error no es lo mismo que verificar códigos de respuesta

Tienes toda la razón, por supuesto.

Es por eso que el $this->process_error() llamar cheques para ambos. Una llamada devuelta con estado 4xx sigue siendo una devolución válida, solo contiene información útil en el cuerpo de la devolución de algunos servicios web (incluido mailchimp). Entonces wp_remote_request() no regresa WP_Error() protesté en esos casos y tuve que comprobar el estado también wp_is_error().

En cambio, cuando regresa, devuelve un estado que no es uno de los estados 2xx o 3xx (sin error / redireccionamiento).

El problema que estoy tratando de lograr tiene que ver con estas 3 líneas de código de mi seguimiento original:


$start_of_request = current_time( 'timestamp' );
$response         = wp_remote_request( $url, $request );
$end_of_request   = current_time( 'timestamp' );

El es $response = wp_remote_request(); a veces _NOT_ pasará a $end_of_request = current_time( 'timestamp' ); y sale del proceso por completo (código _NO_ después de la wp_remote_request() ejecutar. ¡Nunca!).

Esto no sucede con todas las llamadas, pero ocasionalmente, y esa es la parte extraña.

Estaba pensando que podría estar relacionado con la gestión de procesos en el servidor o con un límite de tiempo de conexión.

Sin embargo, la teoría del límite de tiempo de conexión parece poco probable porque ningún intento previo dura más de <1 go dtí idir 1-2 shoicind. Is cosúil nach dócha go mbeidh nasc amháin - tar éis 30+ nasc rathúil ag 1-2 shoicind - ag glacadh> 1 _minuto_ de repente, el límite de tiempo que establecí en el encabezado de la solicitud. Independientemente del entorno del servidor.

Según la documentación de Mailchimp, es poco probable que se deba a la limitación de enlaces, ya que estoy haciendo un máximo de 1 conexión simultánea por segundo y su límite es de 10 conexiones simultáneas a la vez.

(@bcworkz)

Hace 2 años, 1 mes

Gracias por la explicación. Me recordó que inicialmente dijiste que murió en silencio. Olvidé ese detalle entre respuestas, mis disculpas. Es difícil imaginarse esta muerte sin registrar algún tipo de error. Los errores incluso deberían restaurar el tiempo libre de WP_Error. Sin ningún tipo de pista me faltan sugerencias.

¿Conoce una solicitud específica que desencadenaría de manera confiable este error? Como proceso activo, no como trasfondo. Puede profundizar en el código central y concentrarse en qué tan lejos llega el código antes de fallar. Sería una gran pista si no estuviera señalando el problema directamente.

Puede probar un comportamiento HTTP diferente. WP usa cURL cuando está disponible; de ​​lo contrario, transporta socket. Puede implementar un socket cambiando el nombre del archivo de clase de transporte cURL en /wp-includes/Requests/Transport/cURL.php

(@ ochenta20 adultos)

Hace 2 años, 1 mes

Creo que sé lo que está pasando …

Parece que me estoy encontrando con una configuración de «edición» en el servidor web frente a PHP max_execution_timeout.

El PHP max_execution_timeout vale 120 segundos.

Sin embargo, creo que el proveedor de alojamiento web está utilizando tanto FcgidBusyTimeout o el apache Timeout configurando y teniendo lo que esté configurado en 60 segundos.

Como resultado, el servidor web mata mi proceso en segundo plano, pensando que puede ejecutarse durante el doble de esa cantidad de tiempo.

Es «silencioso» porque probablemente no puedo ver los registros de errores globales (el host parece pensar que puedo, pero la mayoría de los servidores web que conozco registrarán el estado 500 cuando terminan un proceso y no tengo 500 entradas en «mis» registros).

Lo más probable es que la aleatoriedad del problema se pueda atribuir al trabajo que se ejecuta en un escenario compartido, por lo que la carga del servidor aumenta el tiempo que lleva todo (lo que provoca la solicitud # emitida por el enviar).

Lo probaré durante unos días antes de cerrar este tema, por si acaso.

¡Gracias por ayudarme a resolver esto!

(@ ochenta20 adultos)

Hace 2 años, 1 mes

Propuesto: configurar FcgidBusyTimeout y / o Timeout para el servidor web terminará el proceso PHP.

La finalización del proceso es silenciosa (no visible en los registros de errores que veo) porque estoy en un entorno de alojamiento compartido con acceso limitado a los registros de errores de Apache.

¿Solucionó tu problema??

0 / 0

Deja una respuesta 0

Tu dirección de correo electrónico no será publicada.