Domanda

In un po 'di codice sto scrivendo per GAE, devo eseguire periodicamente un URL su un altro sistema, in sostanza "pinging" e non sono terribilmente preoccupato se la richiesta fallisce, si scatena o ci riesce.

Dato che fondamentalmente voglio "sparare e dimenticare" e non rallentare il mio codice aspettando la richiesta, sto usando un urlfetch asincrono e non chiamando get_result ().

Nel mio registro ricevo un avvertimento:

Ho trovato 1 richiesta / i RPC senza risposta corrispondente (presumibilmente dovuta a timeout o altri errori)

Mi manca un modo ovviamente migliore per farlo? Una coda di attività o un'attività differita mi sembra (per me) come eccessiva in questo caso.

Qualsiasi input sarebbe apprezzato.

È stato utile?

Soluzione

Un'attività di coda di attività è la migliore opzione qui. Il messaggio che stai vedendo nel registro indica che la richiesta sta aspettando che il tuo UrlFetch si completi prima di tornare, quindi questo non aiuta. Dici che un compito è "eccessivo", ma in realtà sono molto leggeri e sicuramente il modo migliore per farlo. Deferred ti permetterà persino di differire direttamente la chiamata di recupero, piuttosto che dover scrivere una funzione da chiamare.

Altri suggerimenti

Quanto tempo ci vuole per il completamento di Async_url_fetch e quanto tempo ci vuole per fornire la tua risposta?

Ecco un possibile approccio per sfruttare il modo in cui l'API funziona in Python.

Alcuni punti da considerare.

  • Molti Webservers e Reverse Proxy non annulleranno una richiesta una volta che è stata avviata. Quindi, se il tuo server remoto stai eseguendo segnali nella richiesta ma impiega molto tempo per servirla, usa una scadenza sul tuo create_rpc (scadenza = x) in modo tale che X tornerà a causa del timeout. Il ping potrebbe ancora avere successo. Questa tecnica funziona anche contro Appengine stesso.

  • GAE RPCS

    • Gli RPC dopo essere stati inseriti tramite make_call/make_fetch_call vengono effettivamente spediti solo una volta che uno di loro viene atteso.
    • Inoltre, qualsiasi RPC appena finito avrà il suo callback chiamato quando attualmente atteso di uno.
    • È possibile creare un async_urlfetch rpc e accusarlo usando make_fetch_call il più presto possibile nella gestione della tua richiesta, non attendere ancora.
    • Fai il lavoro effettivo che serve il lavoro, come le chiamate Memcache/DataStore per far funzionare il lavoro. La prima chiamata a una di queste eseguirà un'attesa che spedirà il tuo async_urlfetch.
    • Se l'urlfetch si completa durante questa altra attività, verrà chiamato il callback sull'urlfetch, permettendoti di gestire il risultato.
    • Se si chiama get_result () bloccerà su wait () fino alla scadenza o restituirà a meno che il risultato non sia pronto.

Per ricapitolare.

Prepara l'URL_fetch a lungo in esecuzione con una scadenza e un callback ragionevoli. Accendi usando make_fetch_call. Fai il lavoro che volevi per la pagina. Restituisci la pagina indipendentemente da URL_FETCH completato o stanziato e senza aspettarlo.

Lo strato RPC sottostante in GAE è tutto asincrono, sembra esserci un modo più sofisticato per scegliere ciò che desideri aspettare nelle opere.

Questi esempi usano il sonno e un URL_fetch a una seconda istanza della stessa app.

Esempio di wait () che spedisce il lavoro 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

Aspettare chiamato dopo aver dormito per 4 secondi mostra la spedizione di

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)

Chiamata spedita asincrica.

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 l'uso di una Memcache RPC Wait di dare il via al lavoro.

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

Registro prod AppEngine:

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)

Asincr URL Fetch spedito quando memcache.get chiama 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top