Manlio Perillo wrote:
Come vedi diventa molto complicato, specialmente se ad esempio devi fare il parsing di un protocollo come HTTP (puoi vedere il codice di Twisted se ti interessa).
Twisted non si limita alle callback lisce ma ne gestisce esplicitamente i flusso (con i Deferred), e supporta anche la sintassi pseudo sincrona, stile coroutine, tramite le inline callbacks (opzioni 1, 2 e 3 sotto). Lo stesso fa Tornado.
Tra l'altro il motivo perchè tornado va di moda è perchè permette di avere il codice che è praticamente lo stesso di quello "normale", ma che si comporta in modo completamente diverso.
Cioè la sintassi pseudo sincrona. Tornado supporta anche la sintassi a callback "gestita" (tramite i Future).
Twisted offre un framework per la programmazione asincrona da anni, ma non è mai stato di moda, perchè molto più difficile.
Non ha avuto grande successo per vari altri motivi: avanti sui suoi tempi, documentazione carente, e anche insistenza sulla sintassi a callback preferita alle inline callback.
Considerato tutti i problemi che gli utenti hanno con tornado e friends (e che nemmeno sanno di sapere), direi che, come sempre, "explicit is better than implicit".
Poco ma sicuro. Creare punti impliciti di cambio di contesto, come fanno gevent ed eventlet, e come fanno i thread preemptive, è ingestibile. Un linguaggio recente come Go usa solo la sintassi pseudo sincrona, tramite goroutine e channel. Però lo scheduler è preemptive e il runtime fa un mapping N-to-M delle goroutine ai thread di sistema, permettendo di usare in modo trasparente tutti i core di CPU disponibili. Quest'approccio consente di mischiare in modo trasparente codice sincrono e asincrono. Devo invocare un adapter db sincrono, cioè bloccante? Non devo preoccuparmi di incapsulare manualmente la chiamata in un thread o processo separato: il runtime si accorgerà che il thread assegnato è bloccato, e sposterà automaticamente le altre goroutine assegnate a quel thread su altri thread. Essendo comunque un sistema preemptive a stato condiviso, rimane al programmatore la responsabilità di non reintrodurre i problemi del multithreading classico. Il linguaggio incoraggia l'approccio robusto, ma non lo rende obbligato. Approfondimenti: The Go scheduler <http://morsmachine.dk/go-scheduler> Why is this Go code blocking? <http://stackoverflow.com/questions/12413510/why-is-this-go-code-blocking>
Il mio suggerimento è sempre quello di imparare prima le basi (vicino a quello che realmente succede) e solo dopo utilizzare cose che rendono la programmazione e manutenzione più semplice.
Se con questo intendi passare per la sintassi a callback prima di usare la pseudo sincrona, non sono d'accordo. Non si tratta di basi, è semplicemente un modo diverso, molto meno leggibile, di scrivere codice asincrono. Ormai le Promises ci sono anche in Javascript, non ha senso insistere col vecchio modello. Però andare troppo oltre e rinunciare agli yield, che marcano i punti di cambio di contesto, significa andarsela a cercare. Glyph Lefkowitz, cioè Mr. Twisted, fa un'ottima panoramica delle opzioni disponibili, ed illustra bene i pericoli di usare una sintassi implicita: "1. Straight callbacks: Twisted’s IProtocol, JavaScript’s on<foo> idiom, where you give a callback to something which will call it later and then return control to something (usually a main loop) which will execute those callbacks, 2. “Managed” callbacks, or Futures: Twisted’s Deferred, JavaScript’s Promises/A[+], E’s Promises, where you create a dedicated result-that-will-be-available-in-the-future object and return it for the caller to add callbacks to, 3. Explicit coroutines: Twisted’s @inlineCallbacks, Tulip’s yield from coroutines, C#’s async/await, where you have a syntactic feature that explicitly suspends the current routine, 4. and finally, implicit coroutines: Java’s “green threads”, Twisted’s Corotwine, eventlet, gevent, where any function may switch the entire stack of the current thread of control by calling a function which suspends it. One of these things is not like the others; one of these things just doesn’t belong." Unyielding - Deciphering Glyph <https://glyph.twistedmatrix.com/2014/02/unyielding.html> L'opzione fuori posto è ovviamente la quarta. -- Nicola Larosa - http://www.tekNico.net/ A plus sign is just a square with collapsed sides, after passing through a hash sign: ◽ # + (Where are my medications when I need them?) - Nicola Larosa, February 2014 _______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python