# Errore variabile globale

**URL:** <https://www.ruby-forum.com/t/errore-variabile-globale/137855>\
**Category:** IT\
**Created:** [May 16, 2008, 10:38pm UTC](https://www.ruby-forum.com/t/errore-variabile-globale/137855 "2008-05-16T22:38:27Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![sdpurtill](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@sdpurtill](https://www.ruby-forum.com/u/sdpurtill)\
**Post date:** [May 16, 2008, 10:38pm UTC](https://www.ruby-forum.com/t/errore-variabile-globale/137855/1 "2008-05-16T22:38:27Z")

</div>

Salve a tutti.

Ho un problema un po’ strano, vorrei sapere se vi Ã¨ mai capitato.

Nella mia applicazione ho una variabile $variabileglobale che assume  
certi valori che valgono per tutti.

$variabileglobale viene aggiornata in determianti metodi, e letta poi da  
altri metodi. Non posso metterla in session[variabile] perchÃ¨ deve  
essere leggibile anche dalle sessioni che non l’hanno creata.

Ora nel development environment va tutto OK, ma quando passo in  
production  
in alcune circostanze (non sempre) questa variabile non viene aggiornata  
immediatamente ma dopo un po’ di azioni.

faccio un esempio

In DEVELOPMENT:

Controller1Azione1 --\> $variabileglogale =“1”  
Controller1Azione2 --\> leggi $variabileglogale restituisce “1”  
Controller1Azione3 --\> $variabileglogale =“2”  
Controller1Azione4 --\> leggi $variabileglogale restituisce “2”  
Controller2Azione5 --\> leggi $variabileglogale restituisce “2”  
Controller2Azione6 --\> leggi $variabileglogale restituisce “2”

. . .

invece in PRODUCTION accade questo:

Controller1Azione1 --\> $variabileglogale =“1”  
Controller1Azione2 --\> leggi $variabileglogale restituisce “1”  
Controller1Azione3 --\> $variabileglogale =“2”  
Controller1Azione4 --\> leggi $variabileglogale restituisce “2”  
Controller2Azione5 --\> leggi $variabileglogale restituisce “1”  
Controller2Azione6 --\> leggi $variabileglogale restituisce “2”

. . .

Come si vede Azione5, quando si passa ad un altro controller, il valore  
di $variabileglobale Ã¨ quello vecchio, ma poi nell’azione successiva  
viene aggiornato.

Ora dopo averci perso la testa mi sono fatto l’idea che la cosa possa  
dipendere dalle istanze mongrel del proxy balance (che ho in production  
ma non ho in development)

In production il server apache fa il proxy balance tra due server  
mongrel che girano su due porte diverse.  
Potrebbe darsi che $variabileglobale assuma 2 valori diversi nelle 2  
istanze di mongrel?

Se Ã¨ cosÃ¬ si spiegherebbe anche perchÃ¨ alle volte funziona: dipende da  
quale istanza mongrel il server apache va a prendere $variabileglobale  
in quel momento.

Pero’ la cosa mi pare davvero strana.

Voi che ne dite?

Grazie a tutti!

---

<div class="post-metadata">

**Author:** ![sdpurtill](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@sdpurtill](https://www.ruby-forum.com/u/sdpurtill)\
**Post date:** [May 17, 2008, 11:31am UTC](https://www.ruby-forum.com/t/errore-variabile-globale/137855/2 "2008-05-17T11:31:24Z")

</div>

Sam P. wrote:

> Salve a tutti.
> 
> Ho un problema un po’ strano, vorrei sapere se vi Ã¨ mai capitato.
> 
> Nella mia applicazione ho una variabile $variabileglobale che assume  
> certi valori che valgono per tutti.
> 
> $variabileglobale viene aggiornata in determianti metodi, e letta poi da  
> altri metodi. Non posso metterla in session[variabile] perchÃ¨ deve  
> essere leggibile anche dalle sessioni che non l’hanno creata.
> 
> Ora nel development environment va tutto OK, ma quando passo in  
> production  
> in alcune circostanze (non sempre) questa variabile non viene aggiornata  
> immediatamente ma dopo un po’ di azioni.
> 
> […]
> 
> In production il server apache fa il proxy balance tra due server  
> mongrel che girano su due porte diverse.  
> Potrebbe darsi che $variabileglobale assuma 2 valori diversi nelle 2  
> istanze di mongrel?
> 
> Se Ã¨ cosÃ¬ si spiegherebbe anche perchÃ¨ alle volte funziona: dipende da  
> quale istanza mongrel il server apache va a prendere $variabileglobale  
> in quel momento.

E’ esattamente quello che succede. I due mongrel sono processi separati  
che non comunicano in nessun modo (non consideriamo per ora il  
database). Le variabili al loro interno non sono condivise e pertanto  
devi progettare l’applicazione di conseguenza, senza assumere che una  
variabile sia giÃ stata preparata dall’altro server: ogni mongrel  
dev’essere completamente autonomo. L’alternativa sarebbe memorizzare le  
variabili globali in un qualche sistema centralizzato, magari usando  
DRb, ma mi pare una sovraingegnerizzazione oltre che un  
ammazza-performance…

Tieni presente che ci sono problemi pure con session[]. In particolare  
fai attenzione alle race conditions, soprattutto in applicazioni Ajax  
dove ci sono tante richieste contemporanee dallo stesso browser al  
server. PuÃ² capitare che due richieste vadano a due mongrel differenti e  
le modifiche alla sessione fatte da uno siano sovrascritte da quelle  
fatte dall’altro.

Avevo avuto questo problema su SkipperMania (ricordate?) e l’ho risolto  
in parte usando un plugin chiamato SmartSessionStore, una versione piÃ¹  
evoluta di SqlSessionStore, che aggiorna la sessione nel db solo se Ã¨  
stata modificata, e in parte con una riprogettazione che evitasse  
situazioni in cui tante richieste debbano aggiornare la sessione.  
Un’alternativa sarebbe configurare il proxy in modo che mandi tutte le  
richieste di una sessione allo stesso mongrel.

Come regola perÃ² meno si usa session[] e meglio Ã¨…

---

<div class="post-metadata">

**Author:** ![sdpurtill](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@sdpurtill](https://www.ruby-forum.com/u/sdpurtill)\
**Post date:** [May 18, 2008, 7:09pm UTC](https://www.ruby-forum.com/t/errore-variabile-globale/137855/3 "2008-05-18T19:09:20Z")

</div>

Paolo M. wrote:  
[cut]

> Come regola perÃ² meno si usa session[] e meglio Ã¨…

Buonanotte!!

Ma scusa un po’, allora io ho l’esigenza di trasferire dei dati da un  
controller all’altro (per cui utilizzo session[]) e tra due sessioni  
diverse ( per cui utilizzo $variabileglobale).

Ora, se non posso piu’ utilizzare nÃ¨ session[] nÃ¨ $variabileglobale,  
come faccio?

Li potrei scrivere tutti nel DB, ma le performance?  
Alcuni di questi dati vengono letti in tutte le azioni, il che  
significherebbe continui accessi al DB…

Grazie di tutto.

---

<div class="post-metadata">

**Author:** ![sdpurtill](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@sdpurtill](https://www.ruby-forum.com/u/sdpurtill)\
**Post date:** [May 19, 2008, 1:16am UTC](https://www.ruby-forum.com/t/errore-variabile-globale/137855/4 "2008-05-19T01:16:19Z")

</div>

Sam P. wrote:

> Paolo M. wrote:  
> [cut]
> 
> > Come regola perÃ² meno si usa session[] e meglio Ã¨…

> Ora, se non posso piu’ utilizzare nÃ¨ session[] nÃ¨ $variabileglobale,  
> come faccio?

Ha detto che meno lo usi meglio Ã¨, non ha detto di non usarlo. Il punto  
Ã¨ che le session in realtÃ sono una cosa “finta”, non esistono. Se uno  
disattiva i cookie non funzionano piÃ¹. Meno ne fai uso meglio Ã¨, e se  
non ne dipendi per niente sarebbe meglio ancora.

> Li potrei scrivere tutti nel DB, ma le performance?

Che db hai? Puoi cachare tutto in memcached se il db diventa un collo di  
bottiglia.

> Alcuni di questi dati vengono letti in tutte le azioni, il che  
> significherebbe continui accessi al DB…

si… quindi? il db sta li a posta. Sinceramente dubito che tu abbia  
tanti utenti da non poter fare una mezza dozzina di query per request.

---

<div class="post-metadata">

**Author:** ![sdpurtill](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@sdpurtill](https://www.ruby-forum.com/u/sdpurtill)\
**Post date:** [May 18, 2008, 11:45pm UTC](https://www.ruby-forum.com/t/errore-variabile-globale/137855/5 "2008-05-18T23:45:59Z")

</div>

Capisco lo scorcerto. Le sessioni sembrano una cosa cosÃ¬ intuitiva ma in  
realtÃ possono essere piuttosto complesse da gestire. Il problema Ã¨ che  
Rails dÃ molte scelte 🙂

I dati nella sessione di Rails sono affidati ad un container, che in  
Rails 2.0.2 per default mi pare le memorizzi in un cookie del browser  
(sÃ¬, ci mette dentro proprio tutti i dati). Questo  
significa che puoi usare al massimo 4k di dati serializzati e  
codificati, quindi in pratica un po’ di meno.

Se non ti va bene usare un cookie o il limite sui dati Ã¨ troppo basso  
per le tue necessitÃ , potresti usare il file  
store (il default dell’environment di sviluppo di Rails 1.2), che  
memorizza  
i dati in un file in tmp/sessions. Il problema Ã¨ che all’aumentare delle  
sessioni le performance decrescono enormemente perchÃ© la directory si  
riempie e il sistema operativo ci mette tanto tempo a trovare i file.  
Inoltre se hai piÃ¹ macchine server senza un file system in comune, le  
sessioni rimangono visibili solo all’interno di ogni singola macchina.

Per questa ragione normalmente i dati di sessione si memorizzano  
proprio nel database, nella tabella sessions. Come container si usa o  
l’ActiveRecord session store o con il Sql session store (piÃ¹ veloce).  
Di conseguenza, se le sessioni non sono fatte da troppi dati, non Ã¨  
molto diverso leggere i dati da sessions e decodificarli o rifare le  
query all’inizio di ogni richiesta. Tra l’altro le query magari sono giÃ  
in cache a memcached, se lo usi di fronte al db.

Ecco perchÃ© l’approccio raccomandato Ã¨ tenere in sessione al piÃ¹ gli id  
dei record e poi rileggere tutto dal db.

Ti consiglio queste letture:

Introduzione alle sessioni:  
[http://wiki.rubyonrails.org/rails/pages/sessions](http://wiki.rubyonrails.org/rails/pages/sessions)

Performance dei session container:  
[http://scott.elitists.net/sessions.html](http://scott.elitists.net/sessions.html)

Ottimizzazioni:  
[http://www.texperts.com/2007/05/01/race-conditions-in-rails-sessions-and-how-to-fix-them/](http://www.texperts.com/2007/05/01/race-conditions-in-rails-sessions-and-how-to-fix-them/)  
[http://code.google.com/p/rails-fast-sessions/](http://code.google.com/p/rails-fast-sessions/)

Ciao  
Paolo

Sam P. wrote:

> Paolo M. wrote:  
> [cut]
> 
> > Come regola perÃ² meno si usa session[] e meglio Ã¨…
> 
> Buonanotte!!
> 
> Ma scusa un po’, allora io ho l’esigenza di trasferire dei dati da un  
> controller all’altro (per cui utilizzo session[]) e tra due sessioni  
> diverse ( per cui utilizzo $variabileglobale).
> 
> Ora, se non posso piu’ utilizzare nÃ¨ session[] nÃ¨ $variabileglobale,  
> come faccio?
> 
> Li potrei scrivere tutti nel DB, ma le performance?  
> Alcuni di questi dati vengono letti in tutte le azioni, il che  
> significherebbe continui accessi al DB…
> 
> Grazie di tutto.

---

<div class="post-metadata">

**Author:** ![sdpurtill](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@sdpurtill](https://www.ruby-forum.com/u/sdpurtill)\
**Post date:** [May 19, 2008, 9:39am UTC](https://www.ruby-forum.com/t/errore-variabile-globale/137855/6 "2008-05-19T09:39:51Z")

</div>

S2 akira wrote:

> Ha detto che meno lo usi meglio Ã¨, non ha detto di non usarlo. Il punto  
> Ã¨ che le session in realtÃ sono una cosa “finta”, non esistono. Se uno  
> disattiva i cookie non funzionano piÃ¹. Meno ne fai uso meglio Ã¨, e se  
> non ne dipendi per niente sarebbe meglio ancora.

Va detto che per fare cosÃ¬ bisogna progettare l’applicazione in un certo  
modo. Visto che il contesto non c’Ã¨ piÃ¹, ci si deve affidare unicamente  
alle URL.  
Le letture consigliate sono quelle sul cosiddetto RESTful Rails, magari  
iniziando dal tutorial [http://www.railsforum.com/viewtopic.php?id=1068](http://www.railsforum.com/viewtopic.php?id=1068)

L’autenticazione perÃ² di solito si appoggia proprio ai cookie, a meno di  
mettere un’autenticazione HTTP davanti all’applicazione e poi leggere  
gli user passati dal web server o realizzare qualcosa con i certificati  
SSL. Non mi vengono in mente altre possibilitÃ .

Ciao  
Paolo

---

<div class="post-metadata">

**Author:** ![sdpurtill](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@sdpurtill](https://www.ruby-forum.com/u/sdpurtill)\
**Post date:** [May 19, 2008, 10:48am UTC](https://www.ruby-forum.com/t/errore-variabile-globale/137855/7 "2008-05-19T10:48:11Z")

</div>

Paolo M. wrote:

> S2 akira wrote:
> 
> > Ha detto che meno lo usi meglio Ã¨, non ha detto di non usarlo. Il punto  
> > Ã¨ che le session in realtÃ sono una cosa “finta”, non esistono. Se uno  
> > disattiva i cookie non funzionano piÃ¹. Meno ne fai uso meglio Ã¨, e se  
> > non ne dipendi per niente sarebbe meglio ancora.
> 
> Va detto che per fare cosÃ¬ bisogna progettare l’applicazione in un certo  
> modo.

BÃ¨, ovvio 🙂

> Visto che il contesto non c’Ã¨ piÃ¹, ci si deve affidare unicamente  
> alle URL.

Oppure autenticare gli utenti con certificati, oppure ancora usare ldap,  
oppure kerberos, o… le opzioni non mancano, anche ovviamente andranno  
a impattare sulle performance. chiaramente ci sono sempre pro e contro,  
e personalmente uso sempre le session per memorizzarci una user\_id.

> L’autenticazione perÃ² di solito si appoggia proprio ai cookie, a meno di  
> mettere un’autenticazione HTTP davanti all’applicazione e poi leggere  
> gli user passati dal web server o realizzare qualcosa con i certificati  
> SSL. Non mi vengono in mente altre possibilitÃ .

Concordo 🙂

---

<div class="post-metadata">

**Author:** ![sdpurtill](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@sdpurtill](https://www.ruby-forum.com/u/sdpurtill)\
**Post date:** [May 19, 2008, 10:04am UTC](https://www.ruby-forum.com/t/errore-variabile-globale/137855/8 "2008-05-19T10:04:02Z")

</div>

Paolo M. wrote:

[cut]

Grazie delle informazioni, provero’ ad utilizzare i vostri suggerimenti.

Tanto per puntualizzare il database Ã¨ il DB2 della IBM e si trova su un  
server diverso da quello in cui si trova il web server (con rails).  
Quindi ogni accesso al DB viaggia tramite rete.

Come autenticazione utente utilizzo il plugin RESTful authentication.

Ora provero’ a scrivere tutto nel DB anche perchÃ¨ non avevo pensato che  
l’utente poteva disattivare i cookie: poi non funziona piu’ niente!

Non penso di avere problemi di performance per il mio attuale numero di  
utenti, poi in futuro si vedra’.

L’unica cosa Ã¨ che avendo il DB su una macchina diversa dal server web,  
forse sarebbe il caso di scrivere questi dati nel file system di  
quest’ultimo anzichÃ¨ sul DB.

Con pochi utenti (come ora) Ã¨ sicuramente piÃ¹ veloce, ma all’aumentare  
del numero di utenti diventa piÃ¹ veloce l’utilizzo del DB2, anche se via  
rete, perchÃ¨ indicizza i record.

La cosa che mi pesa un po’ Ã¨ il dover riscrivere tutto quello che avevo  
gia’ fatto con $variabileglobale e session[] . . . .

Grazie di tutto.
