Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 机架中间件与线程安全_Ruby On Rails_Ruby_Thread Safety_Rack_Puma - Fatal编程技术网

Ruby on rails 机架中间件与线程安全

Ruby on rails 机架中间件与线程安全,ruby-on-rails,ruby,thread-safety,rack,puma,Ruby On Rails,Ruby,Thread Safety,Rack,Puma,我的Rails 4应用程序使用了一个定制的机架中间件。如果客户端没有提供有效的信息(我正在使用API),中间件本身就是默认的Accept和Content-Type头文件到application/json。因此,在每个请求之前,它会更改这些头,在每个请求之后,它会添加一个带有自定义媒体类型信息的自定义X-Something-Media-Type头 我想切换到Puma,因此我有点担心这样一个中间件的线程安全性。除了在每个中间件中遇到的常见@app.call之外,我没有使用实例变量,但即使在这里,我也

我的Rails 4应用程序使用了一个定制的机架中间件。如果客户端没有提供有效的信息(我正在使用API),中间件本身就是默认的
Accept
Content-Type
头文件到
application/json
。因此,在每个请求之前,它会更改这些头,在每个请求之后,它会添加一个带有自定义媒体类型信息的自定义X-Something-Media-Type头

我想切换到Puma,因此我有点担心这样一个中间件的线程安全性。除了在每个中间件中遇到的常见
@app.call
之外,我没有使用实例变量,但即使在这里,我也复制了我在RailsCasts评论中读到的内容:

def initialize(app)
 @app = app
end

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

def _call(env)
 ...
 status, headers, response = @app.call(env)
 ...
为了处理线程安全问题,
dup.\u调用
真的有用吗

除了
@app
实例变量之外,我只使用当前env变量生成的当前请求:

request      = Rack::Request.new(env)
我调用
env.update
来更新标题和表单信息

当我从
Webrick
切换到并发web服务器(如
Puma
)时,期待中间件出现一些问题是否足够危险

如果是的话,您知道一些方法来隔离我的中间件中非线程安全的部分吗


谢谢。

是的,必须
dup
中间件才是线程安全的。这样,您在
\u call
中设置的任何实例变量都将在被复制的实例上设置,而不是在原始实例上设置。您会注意到,围绕机架构建的web框架是这样工作的:


单元测试的一种方法是断言
\u call
是在被复制的实例上而不是在原始实例上调用的。

作为推论,如果不设置/更新实例变量,则不必在中间件上调用
dup
。或者,使用线程安全的数据结构,例如并发ruby的缓存映射,用于共享缓存。从这里可以找到一个很好的解释: