Ottimizzare Ruby On Rails (parte 2): Il codice

5 11 2007

Gestire in maniera ottimizzata le sessioni.
Di default Ruby On Rails gestisce le sessioni scrivendo i dati sul disco (ne trovate traccia nella directory /tmp/sessions dell’applicazione rails).

Nonostante questo sistema sia comodo ed immediato, non è molto veloce.

La soluzione migliore è utilizzare SQLSessionStore, un sistema di gestione delle sessioni che utilizza come backend il database.

Il funzionamento è simile ad ActiveRecordStore (altra modalità di gestione delle sessioni su database) ma evita il sovraccarico di lavoro dovuto all’utilizzo degli oggetti ActiveRecord, utilizzando direttamente delle query SQL ed evitando le transazioni, inutili in questo caso.

SqlSessionStore richiede la presenza di mysql-ruby installato, il che potrebbe prevenire il fatto che questo sistema funzioni ovunque (raro, i migliori provider hanno già installato questa gem di default), ma tenetene conto per quando lavorate in locale.

Ottimizzare l’accesso alle risorse su una base “per richiesta”.

In pratica vuol dire evitare di ricalcolare più volte la stessa informazione all’interno della stessa chiamata.

Un esempio potrebbe essere preparare delle informazioni su un utente che dovranno essere riprodotte più volte all’interno della stessa pagina.

Spostate le informazioni cui dovete accedere spesso in un helper e fate in modo che siano memorizzate “per richiesta”, in modo che vengano preparate la prima volta che sono usate, ma poi siano disponibili senza ulteriore carico di lavoro.
def dati_dell_utente (utente)
@dati_dell_utente ||=
begin
...operazione per recuperare e preparare i dati dell'utente...
end
end

Così facendo, i dati dell’utente vengono caricati la prima volta che servono all’interno di una pagina, dalla seconda volta vengono forniti direttamente i dati memorizzati nella variabile @dati_dell_utente.

Il concetto può essere ulteriormente esteso a tutte le risorse che non cambiano durante il normale uso, come dati di configurazione dell’applicazione o simili, per le quali può essere giustificato un riavvio del server in caso di modifica.

In questo caso può essere comodo storare le informazioni in una variabile globale, all’interno di una classe “di comodo”:
class DatiVari
@@dati_vari = nil
def self.dati_vari
@@dati_vari ||= ...qualunque processo per recuperare i dati...
end
end

In questo modo, per accedere all’informazione @@dati_vari basta istanziare la classe DatiVari e dopo la prima richiesta, i dati verrano forniti senza essere ricalcolati, almeno fino al successivo riavvio del server.

Questo tecnica verrà utile soprattutto in combinazione con gli oggetti ActiveRecord per il “piggyBanking”.

Evitare gli helpers, quando possibile.

L’utilizzo degli helpers che si basano sulle regole di routing (primo fra tutti “link_to” e tutte le sue varie forme), è l’origine di notevoli problemi di performance, soprattutto in pagine in cui siano presenti un notevole numero di links (pagine di cataloghi prodotti ad esempio).

Per questo, per quanto possibile sarebbe meglio sostituire:
<%= link_to "testo",:action => "my_action", :controller => "my_controller", :id = @my.id %>

con
<a href="/my_controller/my_action<%= @my.id %>">testo</a>

Conclusioni.

Dalla mia esperienza su AlfaOmega, ho potuto constatare quanto in effetti l’utilizzo di un sistema di gestione delle sessioni migliori e un utilizzo corretto della cache delle variabili migliori in maniera drastica le prestazioni (soprattutto il secondo). Nel prossimo articolo parlerò dell’ottimizzazione dell’accesso al database e degli inconvenienti più frequenti che si incontrano nell’utilizzo degli oggetti ActiveRecord.


Actions

Informations

Leave a comment

You must be logged in to post a comment