¿Cuánto tiempo lleva completar la async_url_fetch y cuánto tiempo lleva su respuesta?
Aquí hay un posible enfoque para aprovechar la forma en que funciona la API en Python.
Algunos puntos a considerar.
Muchos servidores web y proxies inversos no cancelarán una solicitud una vez que se haya iniciado. Por lo tanto, si su servidor remoto que está haciendo ping envía la solicitud pero tarda mucho tiempo en repararla, use una fecha límite en su create_rpc (fecha límite = X) de modo que X regrese debido a un tiempo de espera excedido. El ping aún puede tener éxito. Esta técnica también funciona contra appengine.
GAE RPC
- RPC después de ser complementada a través de make_call/make_fetch_call son en realidad sólo enviados una vez que uno de ellos se atendió.
- También se llamará a cualquier archivo rpc recién terminado cuando finalice el esperado en ese momento.
- Puede crear un archivo async_urlfetch rpc y ponerlo en cola usando make_fetch_call tan pronto como sea posible en el manejo de su solicitud, no espere todavía.
- Realice el trabajo de publicación de la página real, como llamadas de Memcache/almacén de datos para iniciar el trabajo. La primera llamada a una de estas realizará una espera que enviará su async_urlfetch.
- Si el urlfetch se completa durante esta otra actividad, se llamará a la devolución de llamada en el urlfetch, lo que le permitirá manejar el resultado.
- Si llama a get_result() bloqueará en wait() hasta la fecha límite o se devolverá a menos que el resultado esté listo.
Para recapitular.
Prepare el url_fetch de larga ejecución con una fecha límite razonable y devolución de llamada. Encuéntralo usando make_fetch_call. Haz el trabajo que deseas para la página. Devuelva la página independientemente de si la url_fetch se completó o finalizó y sin esperarla.
La capa de RPC subyacente en GAE es totalmente asíncrona, parece haber una manera más sofisticada de elegir lo que desea esperar en el trabajo.
Estos ejemplos usan sleep y url_fetch en una segunda instancia de la misma aplicación.
Ejemplo de espera() enviar el trabajo RPC:
class AsyncHandler(RequestHandler):
def get(self, sleepy=0.0):
_log.info("create rpc")
rpc = create_rpc()
_log.info("make fetch call")
# url will generate a 404
make_fetch_call(rpc, url="http://<my_app>.appspot.com/hereiam")
_log.info("sleep for %r", sleepy)
sleep(sleepy)
_log.info("wait")
rpc.wait()
_log.info("get_result")
rpc.get_result()
_log.info("return")
return "<BODY><H1>Holla %r</H1></BODY>" % sleepy
Esperar llamada después de dormir durante 4 segundos muestra el envío de
2011-03-23 17:08:35.673 /delay/4.0 200 4093ms 23cpu_ms 0kb Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.151 Safari/534.16,gzip(gfe)
I 2011-03-23 17:08:31.583 create rpc
I 2011-03-23 17:08:31.583 make fetch call
I 2011-03-23 17:08:31.585 sleep for 4.0
I 2011-03-23 17:08:35.585 wait
I 2011-03-23 17:08:35.663 get_result
I 2011-03-23 17:08:35.663 return
I 2011-03-23 17:08:35.669 Saved; key: __appstats__:011500, part: 48 bytes, full: 4351 bytes, overhead: 0.000 + 0.006; link: http://<myapp>.appspot.com/_ah/stats/details?tim
2011-03-23 17:08:35.636 /hereiam 404 9ms 0cpu_ms 0kb AppEngine-Google; (+http://code.google.com/appengine; appid: s~<myapp>),gzip(gfe)
asíncrono envió llamada.
E 2011-03-23 17:08:35.632 404: Not Found Traceback (most recent call last): File "distlib/tipfy/__init__.py", line 430, in wsgi_app rv = self.dispatch(request) File "di
I 2011-03-23 17:08:35.634 Saved; key: __appstats__:015600, part: 27 bytes, full: 836 bytes, overhead: 0.000 + 0.002; link: http://<myapp>.appspot.com/_ah/stats/details?time
Mostrando un memcache RPC espera para iniciar el trabajo.
class AsyncHandler(RequestHandler):
def get(self, sleepy=0.0):
_log.info("create rpc")
rpc = create_rpc()
_log.info("make fetch call")
make_fetch_call(rpc, url="http://<myapp>.appspot.com/hereiam")
_log.info("sleep for %r", sleepy)
sleep(sleepy)
_log.info("memcache's wait")
memcache.get('foo')
_log.info("sleep again")
sleep(sleepy)
_log.info("return")
return "<BODY><H1>Holla %r</H1></BODY>" % sleepy
AppEngine Prod Log:
2011-03-23 17:27:47.389 /delay/2.0 200 4018ms 23cpu_ms 0kb Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.151 Safari/534.16,gzip(gfe)
I 2011-03-23 17:27:43.374 create rpc
I 2011-03-23 17:27:43.375 make fetch call
I 2011-03-23 17:27:43.377 sleep for 2.0
I 2011-03-23 17:27:45.378 memcache's wait
I 2011-03-23 17:27:45.382 sleep again
I 2011-03-23 17:27:47.382 return
W 2011-03-23 17:27:47.383 Found 1 RPC request(s) without matching response (presumably due to timeouts or other errors)
I 2011-03-23 17:27:47.386 Saved; key: __appstats__:063300, part: 66 bytes, full: 6869 bytes, overhead: 0.000 + 0.003; link: http://<myapp>.appspot.com/_ah/stats/details?tim
2011-03-23 17:27:45.452 /hereiam 404 10ms 0cpu_ms 0kb AppEngine-Google; (+http://code.google.com/appengine; appid: s~<myapp>),gzip(gfe)
asíncrono de extracción de URL distribuyen cuando memcache.get a wait()
E 2011-03-23 17:27:45.446 404: Not Found Traceback (most recent call last): File "distlib/tipfy/__init__.py", line 430, in wsgi_app rv = self.dispatch(request) File "di
I 2011-03-23 17:27:45.449 Saved; key: __appstats__:065400, part: 27 bytes, full: 835 bytes, overhead: 0.000 + 0.002; link: http://<myapp>.appspot.com/_ah/stats/details?time
Estoy suponiendo que esto es Python y Java no? – jiggy
Estás en lo correcto. He actualizado la pregunta. Buena atrapada. –
Debe instrumentar para determinar si la operación URLFetch se está completando, y si lo hace, si eso ocurre antes o después de que su solicitud regrese a la persona que llama. Creo que encontrará que * does * finish, y que 'wait' sucede implícitamente * después * de que la solicitud original devuelva su resultado. Sin embargo, no he encontrado documentación explícita para esto en ninguna parte, por lo que el comportamiento puede estar sujeto a cambios. – technomage