[Python] web2py: lo conoscete -> sessioni su db

Daniele Varrazzo piro a develer.com
Mar 13 Dic 2011 11:26:57 CET


On Tue, 13 Dec 2011 00:42:59 +0100, Alessandro Dentella wrote:
> Comincio dal fondo, forse risulta più chiaro il tutto.
>
> On Mon, Dec 12, 2011 at 10:13:48PM +0000, Daniele Varrazzo wrote:
>> A proposito, poi com'è andata con la storia di tornado e psycopg?
>
> bene! con 10 processi tornado i tempi si sono azzerati

Ah, la soluzione "se va bene a FriendFeed va bene anche a me" :) ok.


>> E perché vorresti impedire di leggere? Uno fa tanto per progettare
>> un database che consenta letture e scritture concorrenti e tu infili
>> gli un ombrello nella ruota davanti? :)
>
> come la metti giù dura! Quelli che fanno tutta quella fatica a 
> progettare i
> db hanno anche pensato alla utilità del "SELECT FOR UPDATE", quelli 
> di
> postgresql poi l'hanno fatto selettivo al singolo record, ed in 
> lettura mica
> mi si blocca se non uso "FOR UPDATE". L'update della sessione lo 
> blocco dove
> mi serve!

Sì, ma il blocco serve a coordinare la scrittura consistente di diversi 
record: usare il lock per serializzare nel tempo è un noto anti-pattern 
sui database. Nel tuo caso, siccome vuoi applicarlo alle sessioni, il 
lock viene preso molto presto e rilasciato molto tardi nel tempo di vita 
di una richiesta, quindi stai effettivamente serializzando tutte le 
richieste di un utente, come tutte le chiamate ajax di una pagina.

Quello che vorrei farti capire, ma non sono bravo è che c'è qualcosa 
che *puzza*. Avete un ambiente concorrente per definizione (diversi 
utenti contemporaneamente, diverse richieste per utente via ajax). Avete 
un framework concorrente (lasciamo perdere che è usato male: più viene 
usato meglio più lo diventa). Avete un database che supporta la 
concorrenza... e qual'è il problema: che è troppo concorrente?!?! E lo 
volete serializzare?

Allora, non vedi che in questo disegno qualcosa non va?

Da quello che descrivi, avete stato in memoria, stato in postgres, 
stato in redis, più le sessioni, e tutte devono essere coordinate... Mi 
sembra un grosso problema farlo. Perchè tutta questa isteria?

Quanta roba ci dovete scrivere nelle sessioni, che le richieste ajax si 
inciampano a vicenda? Nella sessione scrivici l'id dell'utente e basta, 
lo scrivi al login e lo usi solo per leggere. Mi sembra di capire che 
ogni richiesta ci scriva qualcosa: perché lo scrivi nella sessione e non 
lo tieni in memoria o in redis?


>> Controindicazioni dei lock espliciti? Quante ne vuoi. Non è una
>
> Dai dammene qualcuna di convincente...

Googla "database ipc antipattern".

Diciamo che la prevedo così: se sei fortunato, noti immediatamente un 
rallentamento di prestazioni dovuto alla serializzazione di ogni 
richiesta. Se non lo sei, la serializzazione resta latente: a un certo 
punto ci sarà un cambiamento non collegato nelle richieste al database 
che litigherà coi lock presi sulla sessione e vi trovate con qualcosa 
che non cammina più, e se non avete sviluppato strategie di debug dei 
lock sul database, se non vi ricordate nemmeno che avete messo i lock 
sulle sessioni... in bocca al lupo a capire perché.

Se hai richieste concorrenti che devono essere processate in serie, 
fallo in memoria, visto che stai già pagando il prezzo di avere session 
affinity e quindi una certa garanzia che tutte le rihcieste l'utente 
vadano sullo stesso server. Voi avete in pratica un programma web che 
dialoga con un application server: ormai, tieni la consistenza nel 
server. Almeno serializzi solo quello che ti serve, non tutte le 
richieste che mai passeranno per il web server e che non hanno bisogno 
di serializzazione. Altrimenti serializzi anche servire file statici o 
cazzate del genere. Questo è un esempio: immagino i file statici siano 
serviti dal web server, ma qualcos'altro che non necessita di essere 
serializzato, che non fa parte dello spreadsheet, di sicuro ci sarà, e 
se serializzi le sessioni anche quello prende il suo share di tempo 
esclusivo.


-- 
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com


Maggiori informazioni sulla lista Python