Abbiamo una coda di lavori e i lavoratori elaborano questi lavori uno alla volta. Ogni lavoro ci richiede di formattare alcuni dati ed emettere una richiesta HTTP POST, con i dati come carico utile della richiesta.Come si inviano richieste HTTP asincrone in python uno alla volta?
In che modo è possibile che ciascun worker emetta queste richieste POST HTTP in modo asincrono in modo a thread singolo e senza blocco? Non ci interessa la risposta della richiesta: tutto ciò che vogliamo è che la richiesta venga eseguita il prima possibile e quindi che il lavoratore passi immediatamente al lavoro successivo.
Abbiamo esplorato utilizzando gevent
e la libreria grequests
(vedere Why does gevent.spawn not execute the parameterized function until a call to Greenlet.join?). Il nostro codice operaio sembra qualcosa di simile:
def execute_task(worker, job):
print "About to spawn request"
greenlet = gevent.spawn(requests.post, url, params=params)
print "Request spawned, about to call sleep"
gevent.sleep()
print "Greenlet status: ", greenlet.ready()
La prima istruzione print esegue, ma le dichiarazioni secondo e il terzo di stampa non vengono mai stampate e l'URL viene mai colpito.
Come possiamo ottenere queste richieste asincrone da eseguire?
C'è una lib standard chiamata [asyncore] (http://docs.python.org/2/library/asyncore.html) ma è forse troppo di basso livello per il tuo caso d'uso. – lucasg
Dovrei essere d'accordo con @georgesl su questo, asyncore sarebbe un ottimo posto per migrare perché ti darà una migliore flessibilità sull'applicazione per uno sviluppo successivo. Inoltre, 'http: // stackoverflow.com/questions/15753901/python-asyncore-client-socket-can-not-determaine-connection-status/15754244 # 15754244' ecco un buon inizio e un esempio di come può essere utilizzato (vedi la risposta alla mia domanda). In caso contrario, dovresti effettivamente farlo in più processi, anche le librerie "sub" di python molto probabilmente lo collegheranno per te se puoi inviare richieste paralell, questo è il problema del multi-processo – Torxed
Il tuo codice gevent sembra okay (e un test rapido mi dice che funziona bene, io uso gevent 1.0b3). Immagino che dipenda dal contesto in cui viene chiamato execute_task'. – robertklep