【问题标题】:Re-entrant subrequests in Rack/RailsRack/Rails 中的重入子请求
【发布时间】:2010-12-11 10:20:07
【问题描述】:

我有几个带有金属端点的引擎插件,它们实现了一些非常简单的 Web 服务,我打算在多个应用程序之间共享。它们按原样工作得很好,但显然,在本地加载它们以进行开发和测试时,向 Net::HTTP 发送 get_response 消息以从当前执行的控制器对象内部向 localhost 请求另一个页面会导致即时死锁。

所以我的问题是,Rails (或 Rack 的)路由系统是否提供了一种安全使用 Web 服务的方法,该 Web 服务可能是也可能不是同一服务器实例下同一应用程序的一部分,还是我必须破解当 URI 中的主机名与我自己的匹配时,与 render_to_string 一起的特殊情况?

【问题讨论】:

  • 您可以使用 Mock 对象:“使用 Rails 2 进行敏捷 Web 开发”一书中的第 13 章,基本上只是存根 :) 碰巧忽略了它(所以我不是这方面的专家)

标签: ruby-on-rails rack


【解决方案1】:

这实际上是可能的。但是,您需要确保您调用的服务不会以递归方式相互调用。

一个非常简单的“可重入”Rack 中间件可以像这样工作:

class Reentry < Struct.new(:app)
  def call(env)
    @current_env = env
    app.call(env.merge('reentry' => self)
  end

  def call_rack(request_uri)
    env_for_recursive_call = @current_env.dup
    env_for_recursive_call['PATH_INFO'] = request_uri # ...and more
    status, headers, response = call(env_for_recursive_call)
    # for example, return response as a String
    response.inject(''){|part, buf| part + buf }
  end
end

然后在调用代码中:

env['reentry'].call_rack('/my/api/get-json')

一个非常有效的用例是在 JSON 中侧载 API 响应 在您的主页中设置格式。

显然,这项技术的成功将取决于复杂程度 你的机架堆栈(因为机架环境的某些部分不喜欢被重用)。

【讨论】:

    【解决方案2】:

    它在开发中不起作用,因为它一次只处理一个请求,并且控制器的请求被卡住了。如果你需要这个,你可以在负载均衡器后面本地运行多个服务器。我推荐使用 Passenger 甚至用于开发(如果你在 OS X 上,则使用 prefpane)。

    我对您的建议是将内部 Web 服务和使用它们的应用程序分开。这样您就不会重复代码,并且可以轻松地单独扩展和控制它们。

    【讨论】:

      猜你喜欢
      • 2013-02-19
      • 2019-11-08
      • 2012-04-13
      • 1970-01-01
      • 1970-01-01
      • 2011-07-21
      • 2012-09-16
      • 1970-01-01
      • 2020-09-03
      相关资源
      最近更新 更多