2014-04-12 15 views
6

Ich habe eine benutzerdefinierte Rack Middleware von meiner Rails 4-Anwendung verwendet. Die Middleware selbst ist nur hier zum Standard Accept und Content-Type Header zu application/json, wenn der Client keine gültigen Informationen zur Verfügung gestellt (ich arbeite an einer API). Vor jeder Anforderung werden diese Header geändert und nach jeder Anforderung wird ein benutzerdefinierter Kopf vom Typ "X-Somethy-Media-Type" mit benutzerdefinierten Informationen zum Medientyp hinzugefügt.Rack Middleware und Thread-Sicherheit

Ich würde gerne zu Puma wechseln, deshalb bin ich ein bisschen besorgt über die Thread-Sicherheit einer solchen Middleware. Ich habe nicht mit Instanzen Variablen spielen, außer einmal für die gemeinsame @app.call, dass wir in jeder Middleware begegnen, aber auch hier wiedergegebenen ich etwas, das ich in Railscasts Kommentare gelesen habe:

def initialize(app) 
@app = app 
end 

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

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

Ist dup._call wirklich nützlich, um Thread-Sicherheitsprobleme behandeln?

Außer dass @app Instanzvariable ich nur mit der aktuellen Anforderung mit dem aktuellen env Variable gebaut spielen:

request  = Rack::Request.new(env) 

Und ich rufe env.update Informationen Kopf- und Formulare zu aktualisieren.

Ist es gefährlich genug, einige Probleme mit dieser Middleware zu erwarten, wenn ich von Webrick zu einem gleichzeitigen Webserver wie Puma wechseln werde?

Wenn ja, können Sie einige Tests durchführen, um Teile meiner Middleware zu isolieren, die nicht Thread-sicher sind?

Danke.

Antwort

2

Ja, es ist notwendig, die Middleware dup Thread-sicher zu sein. Auf diese Weise werden alle Instanzvariablen, die Sie unter _call festgelegt haben, für die überspielte Instanz festgelegt, nicht für das Original. Sie werden feststellen, dass Web-Frameworks bemerken, die sich um Rack-arbeiten auf diese Weise gebaut:

Ein Weg, um Unit-Test ist dies zu behaupten, dass _call auf einer betrogenen Instanz aufgerufen wird anstatt das Original.

+0

Wenn Sie also keine Instanzvariablen setzen/aktualisieren, ist es nicht notwendig, 'dup' auf der Middleware aufzurufen. Alternativ können threadsichere Datenstrukturen verwendet werden, z. die Cache-Map von Concurrent-Ruby für einen gemeinsamen Cache. – ioquatix