[Python] web: sync vs. async

Daniele Varrazzo piro a develer.com
Ven 2 Dic 2011 19:31:01 CET


On Fri, 2 Dec 2011 19:03:19 +0100, Alessandro Dentella wrote:
> On Fri, Dec 02, 2011 at 04:04:05PM +0000, Daniele Varrazzo wrote:

>> Scusa, per curiosità...
>>
>> come fa il magicamente asincrono tornado ad accedere al database?
>
> ok, questo è per me il nocciolo. Attualmente usano SqlAlchemy 0.6.8 +
> psycopg2 2.0.3.  La mia lettura è che mettono una chiamata che non è
> asincrona in un RequestHandler, il risultato è di serializzare la 
> risposta
> invece che parallelizzarla usando chiamate asincrone.

Esatto.


> Credo che dovrei venirne fuori o rendendo asincrona la chiamata via
> SqlAlchemy (come?) o aumentando i thread della risposta. Sbaglio?

Il problema è a valle di sqlalchemy: la dbapi è bloccante: 
cur.execute() blocca finchè non ottieni una risposta.

Le soluzioni sono 2: quella twisted è di cambiare l'interfaccia della 
dbapi, inventarsi la ADBAPI, dove passi un callback quando verrà 
eseguito. tx_postgres wrappa psycopg e usa questa soluzione. Ovviamente 
devi riscrivere tutto il mondo, perché niente deve essere bloccante.

Ma la soluzione più figa (sono di parte, me la sono inventata io) è 
quella di aggiungere un hook a psycopg, passargli un callback che viene 
invocato quando la chiamata bloccherà. Con questo callback psycopg 
"chiede di essere bloccato" passando la palla allo scheduler dei 
greenlet che può schedulare un thread switch. Il singolo greenlet resta 
bloccato ma gli altri continuano. L'hook è implementato per gevent, 
eventlet e uWSGI che io sappia. Dettagli su 
<http://initd.org/psycopg/docs/advanced.html#support-to-coroutine-libraries>.

Se tornado ha un metodo per mettere un file descriptor in attesa allora 
puoi scrivere un hook per rendere psycopg non bloccante. Altrimenti sei 
fregato.

Ho googlato e tornado sembra essere implementato a callback come 
twisted 
(http://golubenco.org/2009/09/19/understanding-the-code-inside-tornado-the-asynchronous-web-server-powering-friendfeed/), 
quindi mi sa che la wait callback non può essere usata, Vedi se questo 
<http://61924.nl/03-09-2011/async-psycopg-for-tornado.html> sa quello 
che fa...


-- 
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com


Maggiori informazioni sulla lista Python