<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2014-03-13 19:35 GMT+01:00 Balan Victor <span dir="ltr"><<a href="mailto:balan.victor0@gmail.com" target="_blank">balan.victor0@gmail.com</a>></span>:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">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). <div>


<br></div><div>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.</div><div><br></div><div>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.</div>


</div>
<br>_______________________________________________<br>
Python mailing list<br>
<a href="mailto:Python@lists.python.it">Python@lists.python.it</a><br>
<a href="http://lists.python.it/mailman/listinfo/python" target="_blank">http://lists.python.it/mailman/listinfo/python</a><br>
<br></blockquote></div><br>Hai intravisto giusto a la domanda non è per niente stupida.</div><div class="gmail_extra">I server asincroni performano e scalano enormemente meglio delle controparti basate su processi/thread multipli (un esempio lampante è pyftpdlib: <a href="https://code.google.com/p/pyftpdlib/wiki/Benchmarks">https://code.google.com/p/pyftpdlib/wiki/Benchmarks</a> - si guardi sopratutto l'utilizzo di memoria) a patto che, appunto, tu "non blocchi".</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">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).</div>

<div class="gmail_extra">Fare questo significa essenzialmente ripassare la palla all'IO loop e quando il thread ha terminato prendere il risultato della funzione e processarlo.</div><div class="gmail_extra"><br></div>

<div class="gmail_extra">Fare questo a mano in maniera "sana" non è semplice, ed è infatti per questo che solitamente i framework ti mettono a disposizione interfacce apposite.</div><div class="gmail_extra">Nel caso specifico di Tulip/asyncio il codice dovrebbe essere una cosa di questo tipo:</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">from tulip import tasks, coroutine</div><div class="gmail_extra"><br></div><div class="gmail_extra">@coroutine</div><div class="gmail_extra">def foo():</div><div class="gmail_extra">

        fut = self.run_in_executor(long_running_db_call) </div><div class="gmail_extra">        yield from tasks.wait(fut)</div><div class="gmail_extra">        ret = fut.result()</div><div class="gmail_extra"><br></div>
<div class="gmail_extra">
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".</div><div class="gmail_extra">

<br></div><div class="gmail_extra">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):</div>

<div class="gmail_extra"><a href="https://twistedmatrix.com/documents/12.2.0/core/howto/threading.html">https://twistedmatrix.com/documents/12.2.0/core/howto/threading.html</a><br></div><div class="gmail_extra"><br></div>

<div class="gmail_extra">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:</div><div class="gmail_extra">

<a href="http://www.tornadoweb.org/en/stable/concurrent.html">http://www.tornadoweb.org/en/stable/concurrent.html</a><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">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).</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">-- <br><div dir="ltr"><div>Giampaolo - <a href="http://grodola.blogspot.com" target="_blank">http://grodola.blogspot.com</a></div><div><br></div></div>
</div></div>