Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Nicola Larosa

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 onfoo 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


Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Daniele Varrazzo

On 2014-03-15 05:54, Nicola Larosa wrote:

Daniele Varrazzo wrote:
Purtroppo tulip non si integra bene con il supporto green di 
psycopg,

perché è basato su yield


Chissà come mai Guido ci tiene tanto a questa seccatura dello 
yield...




con tutti gli yeldini al posto loro.


E non solo lui, a quanto pare. Ecco ben spiegata la prospettiva di
noi comuni mortali che bizzarramente ci teniamo così tanto ad avere
tutti gli yeldini al posto loro.


Quello di essere espliciti è senz'altro un modello superiore. Il modo 
green è solo un truccazzo per avere interfacce bloccanti in un ambiente 
asincrono, il che ci ha permesso di arrivare al 2014. Ovvero: vuoi usare 
django in maniera asincrona? Prova a farlo con yield... Vuoi usare 
SQLAlchemy? Uhmm, ritenta, sarai più fortunato. Ho conosciuto comuni 
mortali che avevano bisogno di queste cose (twisted tendevano a usarlo 
i semidei e altri impiegati olimpici). Il futuro è quello? Non c'è 
problema per me. Ma `questo http://python.org/dev/peps/pep-0249/`__ va 
riscritto, come tutti i programmi che ci sono progettati ed implementati 
sopra, e non so se tu ci avevi pensato. La mia non era una nota polemica 
come hai letto tu: le interfacce sono state rotte: vanno riprogettate e 
i programmi dovranno essere riscritti; questo è un dato di fatto.




Unyielding - Deciphering Glyph
https://glyph.twistedmatrix.com/2014/02/unyielding.html

Che è poi il motivo per cui ho usato Twisted per anni, apprezzo
Tornado (e Go), e non mi vedrete tanto presto a usare gevent, 
eventlet

e compagnia, per non dire mai.


È fico essere duri e puri. Io invece mi sono trovato nella posizione di 
scrivere software che altri devono usare: a volte nella maniera in cui 
lo userei anche io, a volte no. Sono sicuro che il supporto a librerie 
di coroutine abbia aiutato più di qualche persona, e questo mi fa 
piacere nonostante ci siano sempre gli odiatori di professione 
(gironzolare su twitter per cercare feedback sul proprio lavoro è come 
andare sulle montagne russe).



-- Daniele

___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Escape stringa con char speciali

2014-03-15 Per discussione Enrico Bianchi

On 03/12/2014 04:23 PM, Fabrizio Soppelsa wrote:

Ogni suggerimento ben accetto:)


Perche` non ti connetti direttamente al database con il driver apposito?

Enrico
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Manlio Perillo
2014-03-14 23:33 GMT+01:00 Balan Victor balan.vict...@gmail.com:

 Il giorno 14 marzo 2014 18:12, Manlio Perillo manlio.peri...@gmail.comha 
 scritto:




 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.

  [...]

 L'argomento è complesso.

 hai da consigliare qualche post/documento/libero che spiega bene
 l'argomento?(Italiano/Inglese) ? Su google ne ho trovato alcuni ma  non
 sono il massimo della chiarezza


Purtroppo no.


  Nel caso di un server C10K ready ci sono due aspetti principali.
 Il primo riguarda tutto quel codice che esegue una richiesta ed aspetta
 una risposta.
 Il secondo riguarda il paradigma utilizzato per gestire il flusso del
 codice.

 Il 97.7% delle librerie disponibili fa qualcosa del tipo:

status = send_request(data)
resp = recv_response()

 Entrambe le funzioni potrebbero metterci molto tempo a completare, ma
 questo codice blocca l'intero thread fino a quando resp non è disponibile.

 Quello che fa tornado è di usare quelle che si chiamano coroutine, o
 threading cooperativo.
 In questo caso sia send_request che recv_response bloccano il flusso
 corrente del codice (la coroutine corrente), ma non l'intero thread perchè
 usando le coroutine viene effettuato un salto (simile al goto) che va ad
 eseguire altre funzioni coroutine.

 e se dentro recv_response ho una chiamata al db perché mi dovrebbe
 bloccare?


Se usi la libreria giusta non blocca.
Ad esempio la libpq ha un API scritta come si deve (una delle poche,
purtroppo, almeno per quello che so) e che permette di fare richieste
asincrone.

se sono eseguiti in coruotine la chiamata al db non dovrebbe andare a
 girare in qualche modo in background?


Come detto, devi usare la libreria giusta.
PostgreSQL usa libpq che offre un API asincrona, e psycopg usa questa API e
le coroutine per fornire una API semplice.  Vedi la documentazione


sa: gevent (l'implementazione delle coroutine) sembra risolva tutti i
 problemi, ma in realtà tutto quello che fa ha un costo.  Non è un caso che
 i web server C10K usano la programmazione tramite callback e macchina a
 stati; questo perchè è molto più efficiente nella gestione della memoria.
  Ogni coroutine è come un thread ed ha bisogno di memoria per lo stack,
 oltre poi al costo per il context switch.

E i multiprocessing?

Quello che fanno le implementazioni delle coroutine più avanzate, come GHC,
Erlang e Go è di reimplementare in user space quello che fa il kernel con i
processi, in modo più semplice (perchè il contesto associato ad un green
thread è più piccolo rispetto a quello associato ad un processo) ed
efficiente, oltre che più prevedibile.


Ciao  Manlio
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Manlio Perillo
2014-03-15 0:54 GMT+01:00 Giampaolo Rodola' g.rod...@gmail.com:


 2014-03-14 18:12 GMT+01:00 Manlio Perillo manlio.peri...@gmail.com:

 Ogni coroutine è come un thread ed ha bisogno di memoria per lo stack,
 oltre poi al costo per il context switch.


 Rispetto ad un thread il costo è però pressochè nullo.


Roberto tempo fa ha scritto che ha visto applicazioni con gevent con
utilizzo pesante della CPU, nel caso di molte coroutine.

Ciao  Manlio
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Roberto De Ioris

 2014-03-15 0:54 GMT+01:00 Giampaolo Rodola' g.rod...@gmail.com:


 2014-03-14 18:12 GMT+01:00 Manlio Perillo manlio.peri...@gmail.com:

 Ogni coroutine è come un thread ed ha bisogno di memoria per lo stack,
 oltre poi al costo per il context switch.


 Rispetto ad un thread il costo è però pressochè nullo.


 Roberto tempo fa ha scritto che ha visto applicazioni con gevent con
 utilizzo pesante della CPU, nel caso di molte coroutine.



purtroppo si, le greenlet hanno comunque uno stack e gevent comunque in
media chiama molte piu' syscall rispetto ad un uso classico (per svariati
motivi).

E' un prodotto/progetto che adoro, ma va' usato nei posti e nel modo giusto.

Oggi ho buttato giu' questo:

http://uwsgi-docs.readthedocs.org/en/latest/articles/OffloadingWebsocketsAndSSE.html

... bisogna farla finita di credere alla favola che django gira gratis
su gevent (tantomeno su tornado)...

Non c'e' niente da fare, il vantaggio di nodejs, Go ecc. ecc. e' che TUTTE
le librerie di terze parti sono non-blocking-friendly (passatemi il
termine) e quindi gli utenti (piu' o meno) non devono preoccuparsi di
nulla... questo non puo' avvenire (facilmente) con i linguaggi che sono
nati in un mondo multiprocess/multithread  e che gia' hanno una libreria
sconfinata di moduli di terze parti (costruita in decenni)..

In ogni caso il passaggio non potra' essere indolore (e gia' ci sono le
prime vittime, senza contare quelli che hanno proprio disertato cambiando
bandiera...)


-- 
Roberto De Ioris
http://unbit.it
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Nicola Larosa

Roberto De Ioris wrote:

Non c'e' niente da fare, il vantaggio di nodejs, Go ecc. ecc. e'
che TUTTE le librerie di terze parti sono non-blocking-friendly
(passatemi il termine) e quindi gli utenti (piu' o meno) non devono
preoccuparsi di nulla...


No, questo per Go non è vero. Vedi la mia risposta a Manlio di stamattina.

--
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


Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Roberto De Ioris

 Roberto De Ioris wrote:
 Non c'e' niente da fare, il vantaggio di nodejs, Go ecc. ecc. e'
 che TUTTE le librerie di terze parti sono non-blocking-friendly
 (passatemi il termine) e quindi gli utenti (piu' o meno) non devono
 preoccuparsi di nulla...

 No, questo per Go non è vero. Vedi la mia risposta a Manlio di stamattina.



In che senso ? nella peggiore delle ipotesi Go fa' l'offloading su un
pthread, quindi comunque l'utente e' salvo.

O intendi altro ?


-- 
Roberto De Ioris
http://unbit.it
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Nicola Larosa

Roberto De Ioris wrote:

Non c'e' niente da fare, il vantaggio di nodejs, Go ecc. ecc. e'
che TUTTE le librerie di terze parti sono non-blocking-friendly
(passatemi il termine) e quindi gli utenti (piu' o meno) non
devono preoccuparsi di nulla...



Nicola Larosa wrote:

No, questo per Go non è vero. Vedi la mia risposta a Manlio di
stamattina.



In che senso? nella peggiore delle ipotesi Go fa l'offloading su
un pthread, quindi comunque l'utente e' salvo.

O intendi altro ?


È vero che l'utente non deve preoccuparsi di nulla, ma non perché le
librerie siano tutte non bloccanti bensì perché, come dicevo, Go
consente di mischiare in modo trasparente codice sincrono e asincrono.

Credo che offloading su pthread corrisponda a quello che descrivevo
come mapping N-to-M delle goroutine ai thread di sistema. Giusto?

--
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


Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Roberto De Ioris

 Roberto De Ioris wrote:
 Non c'e' niente da fare, il vantaggio di nodejs, Go ecc. ecc. e'
 che TUTTE le librerie di terze parti sono non-blocking-friendly
 (passatemi il termine) e quindi gli utenti (piu' o meno) non
 devono preoccuparsi di nulla...

 Nicola Larosa wrote:
 No, questo per Go non è vero. Vedi la mia risposta a Manlio di
 stamattina.

 In che senso? nella peggiore delle ipotesi Go fa l'offloading su
 un pthread, quindi comunque l'utente e' salvo.

 O intendi altro ?

 È vero che l'utente non deve preoccuparsi di nulla, ma non perché le
 librerie siano tutte non bloccanti bensì perché, come dicevo, Go
 consente di mischiare in modo trasparente codice sincrono e asincrono.

ah ok giustissimo, ma calcola anche che praticamente tutta la standard
library di Go e' non-bloccante, il che lo mette in posizione di vantaggio
(e anche di tanto) rispetto a python (o a perl o a ruby)

anche se gli ultimi progetti che ho rilasciato sono in go, ancora non mi
sono innamorato, ma sarei ingiusto a dire che non e' fantastico nella
maggior parte delle cose che fa...


 Credo che offloading su pthread corrisponda a quello che descrivevo
 come mapping N-to-M delle goroutine ai thread di sistema. Giusto?


si esatto, anche la nomenclatura che usano e' piu' fica di quella degli
altri :)


-- 
Roberto De Ioris
http://unbit.it
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Daniele Varrazzo

On 2014-03-15 18:08, Roberto De Ioris wrote:


Oggi ho buttato giu' questo:


http://uwsgi-docs.readthedocs.org/en/latest/articles/OffloadingWebsocketsAndSSE.html


Grazie, me lo rileggo domani con un tasso di sangue nell'alcol più 
alto. Ma, domanda veloce:



This is the whole point of this article: do not use the Django ORM in 
your gevent apps
unless you know what you are doing !!! (read, you have a django 
database adapter that

supports gevent and does not sucks compared to the standard ones...)


Con questo dici:

1. impossibile usare django+gevent+psycopg2 in maniera realmente non 
blocking
2. gevent+psycopg2 funzionerebbe se avesse un wrapper django 
diverso/migliore

3. django+gevent+psycopg2 funzionano, altri driver/database no
4. vai a letto piro, non c'hai capito niente ed è tardi

Grazie ancora :)

-- Daniele

___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Non blocking http server e integrazione con database relazionali

2014-03-15 Per discussione Roberto De Ioris

 On 2014-03-15 18:08, Roberto De Ioris wrote:

 Oggi ho buttato giu' questo:


 http://uwsgi-docs.readthedocs.org/en/latest/articles/OffloadingWebsocketsAndSSE.html

 Grazie, me lo rileggo domani con un tasso di sangue nell'alcol più
 alto. Ma, domanda veloce:

 
 This is the whole point of this article: do not use the Django ORM in
 your gevent apps
 unless you know what you are doing !!! (read, you have a django
 database adapter that
 supports gevent and does not sucks compared to the standard ones...)
 

 Con questo dici:

 1. impossibile usare django+gevent+psycopg2 in maniera realmente non
 blocking
 2. gevent+psycopg2 funzionerebbe se avesse un wrapper django
 diverso/migliore
 3. django+gevent+psycopg2 funzionano, altri driver/database no
 4. vai a letto piro, non c'hai capito niente ed è tardi

 Grazie ancora :)



Nessuna di queste :) ci sono adapter che hanno funzionato (notare il
passato), altri che funzionano il 90% delle volte e cosi' via. Il mio
obiettivo e' insinuare il dubbio, perche' se usi queste tecnologie devi
porti delle domande, e non solo sui db, su ogni punto della tua
applicazione.

Mi rendo conto che non e' un approccio molto tecnico, ma francamente
sentirmi dire che cazzo dici !!! ho letto sul blog di topogigio che si
puo' fare e senza sforzo, beh un pochino mi rode...

Ad esempio la funzione di entropia di openssl e' ultra-bloccante, e guarda
un po' l'ho vista usata in un app django-gevent...

(comunque, questo, basato su psycogreen, funziona molto bene:
https://github.com/jneight/django-db-geventpool)

Dei tutorial (quelli diciamo piu' famosi), che ci sono su django + gevent,
solo uno riporta psycogreen, gli altri glissano o consigliano di usare
adapter pure-python (che sono spesso lontani dall'essere full-featured)



-- 
Roberto De Ioris
http://unbit.it
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python