我的 Rails 4 应用程序使用了一个自定义 Rack 中间件。如果客户端未提供有效信息(我'正在开发 API)。因此,在每个请求之前它会更改这些 header ,并且在每个请求之后它会添加一个带有自定义媒体类型信息的自定义 X-Something-Media-Type header 。
我想切换到 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._call
对于处理线程安全问题真的有用吗?
除了 @app
实例变量,我只使用当前环境变量构建的当前请求:
request = Rack::Request.new(env)
然后我调用 env.update
来更新标题和表单信息。
当我从 Webrick
切换到并发 Web 服务器(例如 Puma
)时,预期该中间件会出现一些问题是否足够危险?
如果是,您是否知道一些方法来进行一些测试并隔离我的中间件的非线程安全部分?
谢谢。
最佳答案
是的,有必要dup
中间件是线程安全的。这样,您从 _call
设置的任何实例变量都将设置在被欺骗的实例上,而不是原始实例。您会注意到围绕 Rack 构建的 Web 框架以这种方式工作:
对此进行单元测试的一种方法是断言 _call
是在被欺骗的实例而不是原始实例上调用的。
关于ruby-on-rails - Rack 中间件和线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23028226/