2014-04-12 15 views
6

Ho un middleware rack personalizzato utilizzato dall'applicazione Rails 4. Il middleware stesso è solo qui per default Accept e Content-Type intestazioni a application/json se il cliente non ha fornito una informazione valida (sto lavorando su un'API). Quindi, prima di ogni richiesta, modifica le intestazioni e, dopo ogni richiesta, aggiunge una testa X-Something-Media-Type personalizzata con informazioni sul tipo di supporto personalizzato.middleware rack e sicurezza thread

Vorrei passare a Puma, quindi sono un po 'preoccupato per la sicurezza del thread di un tale middleware. Non ho giocato con le variabili istanze, tranne una volta per il comune @app.call che incontriamo in ogni middleware, ma anche qui ho riprodotto una cosa che ho letto nei commenti Railscasts':

def initialize(app) 
@app = app 
end 

def call(env) 
dup._call(env) 
end 

def _call(env) 
... 
status, headers, response = @app.call(env) 
... 

È il dup._call veramente utile al fine gestire i problemi di sicurezza dei thread?

Tranne quella variabile @app esempio io gioco solo con la richiesta corrente costruito con la variabile ENV corrente:

request  = Rack::Request.new(env) 

E io chiamo env.update di aggiornare le intestazioni e forme informazioni.

È abbastanza pericoloso prevedere alcuni problemi con questo middleware quando passerò da Webrick a un server Web simultaneo come Puma?

In caso affermativo, si conosce un modo semplice per eseguire alcuni test e isolare alcune parti del mio middleware che non sono thread-safe?

Grazie.

risposta

2

Sì, è necessario dup il middleware essere thread-safe. In questo modo, tutte le variabili di istanza impostate da _call verranno impostate sull'istanza duplicata, non sull'originale. Noterete che i quadri web che sono costruiti intorno a cremagliera funziona in questo modo:

Un modo per unit test è quello di affermare che _call viene chiamato su un'istanza ingannato piuttosto che l'originale.

+0

Come corollario, se non si impostano/aggiornano le variabili di istanza non è necessario chiamare 'dup' sul middleware. In alternativa, utilizzare strutture di dati thread-safe, ad es. mappa cache di concurrent-ruby, per una cache condivisa. – ioquatix