2011-09-22 7 views
6

La mia webapp deve crittografare i suoi dati di sessione. Quello che ho impostato è:Rails 3.1: come eseguire un inizializzatore solo per l'app Web (server di rails/unicorno/ecc.)

config/initializers/encryptor.rb: 

require 'openssl' 
require 'myapp/encryptor' 

MyApp::Encryptor.config[ :random_key ] = OpenSSL::Random.random_bytes(128) 
Session.delete_all 

app/models/session.rb: 

require 'attr_encrypted' 

class Session < ActiveRecord::Base 
    attr_accessible :session_id, :data 
    attr_encryptor :data, :key => proc { MyApp::Encryptor.config[ :random_key ] }, :marshal => true 

    # Rest of model stuff 
end 

Che tutto funzioni alla grande e mantiene i dati della sessione protetti. Ecco il problema: quando eseguo le mie attività personalizzate di rake carica l'inizializzatore e cancella tutte le sessioni. Non bene!

Cosa posso inserire nel mio inizializzatore per assicurarsi che venga eseguito SOLO per l'inizializzazione dell'app Web? Oppure, cosa posso inserire nel mio inizializzatore per far sì che NON venga eseguito per le attività di rake?

Aggiornamento: OK, quello che ho fatto per il momento è aggiungere MYAPP_IN_RAKE = true unless defined? MYAPP_IN_RAKE al mio file .rake. E poi nel mio inizializzatore:

unless defined?(MYAPP_IN_RAKE) && MYAPP_IN_RAKE 
    # Web only initialization 
end 

Sembra funzionare. Ma sono aperto ad altri suggerimenti.

+0

Questo sembra suscettibile di mordere in altri modi in futuro. Ogni volta che il server viene riavviato, perderai tutte le tue sessioni (il che sembra essere il comportamento previsto), ma ciò include il server che sta eseguendo l'auto-auto utilizzando troppa memoria, una richiesta eseguita troppo a lungo, ecc. –

+0

I capire gli aspetti negativi, ma penso che ne valga la pena. App riavviate le sessioni di ripristino: accettabile. Troppa memoria o troppo lunga di una richiesta? Sotto unicorno queste situazioni dovrebbero accadere solo in un processo di lavoro. E poiché ho impostato 'preload_app = true', l'inizializzazione avviene solo nel master. Quindi l'unicorno può rigenerare i lavoratori senza causare una reinizializzazione. – sbutler

+0

Possibile duplicato di [inizializzatori Rails 3 eseguiti solo su \ 'rails server \' e non \ 'rails generate \, ecc.] (Http://stackoverflow.com/questions/8660019/rails-3-initializers-that- run-only-on-rails-server-and-not-rails-generate-e) – davmac

risposta

8

Si potrebbe fare una modifica alla propria applicazione in `config/application.rb' in questo modo:

module MyApp 
    def self.rake? 
    [email protected] 
    end 

    def self.rake=(value) 
    @rake = !!value 
    end 

Poi, nel tuo Rakefile dovreste aggiungere questo:

MyApp.rake = true 

E' bello usa metodi piuttosto che costanti poiché a volte preferiresti cambiarli o ridefinirli in un secondo momento. Inoltre, non inquinano lo spazio dei nomi di root.

Ecco un config/initializers/rake_environment_test.rb script di esempio:

if (MyApp.rake?) 
    puts "In rake" 
else 
    puts "Not in rake" 
end 

La natura programmabile del Rakefile vi offre una notevole flessibilità.

+0

OK, mi piace. Ho modificato il setter su '@rake = !! valore se non definito? @ rake' per assicurarti che sia impostato solo una volta. Poi ho anche aggiunto a environment.rb 'MyApp.rake = false'.Sembra ragionevole? – sbutler

+0

Perché dovresti preoccuparti di impostarlo solo una volta? Una pratica migliore del semplice ignorare il set duplicato è di emettere almeno un avviso, o meglio, di lanciare un'eccezione in modo da poter rintracciare la fonte del problema. – tadman

+0

Immagino di essere preoccupato che mentre si esegue come codice webapp in qualche modo il Rakefile verrà caricato. Sto pensando in modo simmetrico: come rake, l'ambiente webapp è caricato, quindi dovrei anche gestire il caso in cui come webapp viene caricato il rake. – sbutler

2

C'è un altro lavoro intorno:

unless ENV["RAILS_ENV"].nil? || ENV["RAILS_ENV"] == 'test' 

Quando si avvia con il rastrello tua ENV [ "RAILS_ENV"] sarà pari a zero. Il test per 'test' è di evitare l'esecuzione quando si utilizza rspec.

So che è necessario utilizzare Rails.env ma restituisce "sviluppo" quando non è inizializzato.

http://apidock.com/rails/Rails/env/class

# File railties/lib/rails.rb, line 55 
def env 
    @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] 
    || ENV["RACK_ENV"] || "development") 
end 
+0

Grazie! Proprio quello di cui avevo bisogno! –