9

我的 Rails 4 应用程序使用了一个自定义机架中间件。如果客户端未提供有效信息(我正在处理 API) ,则中间件本身只是默认设置AcceptContent-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._call为了处理线程安全问题真的有用吗?

除了那个@app实例变量,我只使用当前环境变量构建的当前请求:

request      = Rack::Request.new(env)

我打电话env.update来更新标题和表单信息。

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

如果是,您是否知道一些方法来进行一些测试以隔离我的中间件的非线程安全部分?

谢谢。

4

1 回答 1

6

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

对此进行单元测试的一种方法是断言_call在受骗实例而不是原始实例上调用。

于 2014-10-30T20:01:43.683 回答