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

Rispondere a