Re: [Python] Non blocking http server e integrazione con database relazionali
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
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
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-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 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 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
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
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
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
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
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
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