2014-03-13 19:35 GMT+01:00 Balan Victor <balan.vict...@gmail.com>: > Di recente ho letto un po di tornado, e in particolare mi sono soffermato > sul modulo tornado.httpserver(Non-blocking HTTP server). Stando a quello > che c'è scritto sulla documentazione ufficiale parla di "non-blocking, > single-threaded HTTP server" e di risolvere il problemi di tipo C10K. Qua > sembra interessante, anche se non ho la minima idea di come funzioni. Sono > rimasto perplesso quando ho provato a cercare qualche ORM da usare con > tornado e non ho trovato nulla. Dopo un po di ricerche, da quello che ho > capito, un orm non è fatto per lavorare in maniera asincrona. E non ho > neppure trovato una libreria per collegarsi a qualche tipo di database > relazione(a parte quella con MySql ma sembra non più supportata). > > Detto questo, non riesco a capire l'utilità di un HTTP Server con > performance elevatissime ma che non permetta una minima interazione con il > database. > > Probabilmente sopra ho scritto delle cavolate ma mi mancano completamente > le basi per questo tipo di argomenti e volevo capire meglio come funzionano > e quali sono i campi di applicazione di tecnologie simili. > > _______________________________________________ > Python mailing list > Python@lists.python.it > http://lists.python.it/mailman/listinfo/python > > Hai intravisto giusto a la domanda non è per niente stupida. I server asincroni performano e scalano enormemente meglio delle controparti basate su processi/thread multipli (un esempio lampante è pyftpdlib: https://code.google.com/p/pyftpdlib/wiki/Benchmarks - si guardi sopratutto l'utilizzo di memoria) a patto che, appunto, tu "non blocchi".
Quando arrivi al punto in cui sei costretto a bloccare (es: non hai uno strato apposito che interagisce col db in maniera asincrona) hai una sola possibilità: usare un thread (o un sottoprocesso). Fare questo significa essenzialmente ripassare la palla all'IO loop e quando il thread ha terminato prendere il risultato della funzione e processarlo. Fare questo a mano in maniera "sana" non è semplice, ed è infatti per questo che solitamente i framework ti mettono a disposizione interfacce apposite. Nel caso specifico di Tulip/asyncio il codice dovrebbe essere una cosa di questo tipo: from tulip import tasks, coroutine @coroutine def foo(): fut = self.run_in_executor(long_running_db_call) yield from tasks.wait(fut) ret = fut.result() La magia nel codice sopra sta nello "yield from" che letteralmente si legge come "lancia long_running_db_call in un thread, vai a fare altro e ritorna qui quando il thread è terminato". Con Twisted l'approccio è diverso in quanto anzichè le coroutines utilizzi le callback ma il concetto che sta alla base è il medesimo (lancia il thread, vai a fare altro e processa il risultato del thread quando ha terminato): https://twistedmatrix.com/documents/12.2.0/core/howto/threading.html Con Tornado casualmente non ho mai avuto a che fare con parti "bloccanti" ma dando un'occhiata qui pare sia possibile in maniera analoga a tulip/asyncio: http://www.tornadoweb.org/en/stable/concurrent.html L'unico caso in cui non sceglierei l'asincrono è dove TUTTE le tue richieste sono bloccanti per un motivo o per un altro, nel qual caso avresti prestazioni/scalabilità uguali o minori (più probabile) rispetto a soluzioni nate espressamente per utilizzare il modello di concorrenza "classico" (thread / multi processi, esempio classico: django + gunicorn). -- Giampaolo - http://grodola.blogspot.com
_______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python