php - sincronas - ¿Retrollamadas en funciones asíncronas de ahorro?
funciones sincronas javascript (4)
En Thrift es posible usar el modificador de oneway para especificar una llamada como asíncrona .
Aparentemente, no es posible definir una devolución de llamada , sin embargo, para ser ejecutada cuando se completa la ejecución de la función.
Parece que la única posibilidad que tengo es darle a mi cliente de Thrift ( PHP ) algunas capacidades de "servidor", de modo que, cuando se complete el cálculo pesado en el lado del servidor, pueda enviarle una notificación. Esto significa que debería tener un nuevo archivo .thrift, con nuevas definiciones, nuevos servicios y todo lo demás, y que debería generar el código del lado del servidor php con Thrift.
Incluso si esto es factible, me parece una exageración y me pregunto si hay una forma más inteligente de implementar la devolución de llamada.
Mirando hacia adelante para algunos comentarios de ustedes, chicos.
Bueno, Java tiene llamadas de mensajes asíncronos a través de la referencia de objetos futuros. Esto se puede implementar en un modelo RPC utilizando el paquete de mensajes . No estoy seguro si PHP tiene algo similar.
En lugar de intentar implementar devoluciones de llamada con Thrift (algo que hubiera hecho el protocolo mucho más pesado, supongo), utilizo un servicio de mensajería ligero (STOMP - http://stomp.github.com ) para informar al cliente de eventos asíncronos.
Mi enfoque es que el cliente Thrift se suscribe a un canal STOMP específico, y el servidor Thrift publicará en ese mismo canal cada vez que ocurra un evento asíncrono. El cliente puede consultar el servidor para obtener información adicional sobre el evento.
He recibido una respuesta en un canal diferente de . Dado que el autor me dio permiso para publicar aquí su respuesta, pensé que podría ser útil para alguien más en la comunidad.
Hola robert
Sí, esto ha aparecido en las listas de Apache antes. No hay una forma elegante de hacer lo que estás pidiendo con Thrift. Fundamentalmente, no está diseñado para mensajes bidireccionales.
Hay hacks alrededor de esto, como: - sondeo del lado del cliente - invocar send_method (), esperando en el lado del cliente, luego recv_method (), en lugar de solo método () - haciendo que el cliente también implemente un servidor Thrift
Pero obviamente ninguno de estos son verdaderos mensajes bidireccionales. Tratamos de mantener las interfaces de Thrift lo más simples posible y enfocadas en el caso de uso de RPC central, lo que ha significado dejar algunas cosas como esta.
Probablemente no sea la respuesta que esperabas.
Saludos, mcslee
Roberto, desafortunadamente el marco Thrift no tiene tal funcionalidad incorporada. Sin embargo, puede haber varias alternativas , dependiendo de lo que desee que haga su sesión de cliente PHP durante el tiempo que normalmente esperaría a que respondiera el servidor Thrift de computación intensiva (si no hubiera usado una oneway
).
Solo puedo imaginar, por ahora, que se encuentra en una situación en la que, después de codificar una aplicación web en la que un usuario (o varios usuarios en paralelo) puede desencadenar una tarea de computación intensiva, le gustaría proporcionar algunos comentarios a dichos usuarios. mientras que dichas tareas se agitan a lo largo.
Desde el principio, tiene toda la razón al tratar de evitar la solución que intenta evitar. Sus sesiones de cliente PHP no pueden atender una interfaz de devolución de llamada sin bloquear (a menos que profundice su agujero intentando usar pcntl_fork o alguna otra ayuda de banda de PHP ).
La forma más simple y la MEJOR de salir de esto es dos cambios de un modelo controlado por eventos ( quiero que se me notifique cuando el servidor esté listo ) a un modelo de sondeo ( preguntaré periódicamente al servidor si está hecho o no ). Hay varias formas de implementar un modelo de sondeo, con múltiples opciones de implementación en el servidor y en el lado del cliente, como:
durante la fase de invocación :
- la sesión del cliente PHP asigna un valor único de
job_id
; la sesión luego hace que la llamada asíncrona no seavoid compute(..., job_id)
al servidor Thrift de computación intensiva,
- o -
- la sesión del cliente PHP realiza una llamada síncrona
job_id start_compute(...)
al servidor Thrift de computación intensiva; el servidor asigna el valor único dejob_id
, luego genera la tarea real de computación intensiva en un subproceso / proceso separado, y regresa de inmediato a la sesión del cliente PHP con eljob_id
asignado
- la sesión del cliente PHP asigna un valor único de
durante la fase de cómputo :
- la sesión del cliente PHP continúa para verificar periódicamente el estado del trabajo intensivo en computación a través de una llamada
status get_status(job_id)
al servidor Thrift computacionalmente intensivo,
- o -
- la sesión del cliente PHP finaliza de inmediato para liberar recursos valiosos, después de pasar el
job_id
dejob_id
al navegador y también le indica al navegador que verifique periódicamente el estado deljob_id
trabajo intensivo enjob_id
(por ejemplo, a través deMETA REFRESH
o XHR). (AJAX) solicitud de Javascript, etc.); la verificación del navegador genera una breve sesión de cliente PHP que realiza la llamadastatus get_status(job_id)
al servidor Thrift de computación intensiva, que termina inmediatamente después de reenviar el estado (lo que sea) al navegador
- la sesión del cliente PHP continúa para verificar periódicamente el estado del trabajo intensivo en computación a través de una llamada