-3

I've got a couple Engine plugins with metal endpoints that implement some extremely simple web services I intend to share across multiple applications. They work just fine as they are, but obviously, while loading them locally for development and testing, sending Net::HTTP a get_response message to ask localhost for another page from inside the currently executing controller object results in instant deadlock.

So my question is, does Rails' (or Rack's) routing system provide a way to safely consume a web service which may or may not be a part of the same app under the same server instance, or will I have to hack a special case together with render_to_string for those times when the hostname in the URI matches my own?

4

2 回答 2

3

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

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

于 2009-11-03T18:04:15.640 回答
0

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

一个非常简单的“可重入”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 响应。

显然,这种技术的成功将取决于您的 Rack 堆栈的复杂程度(因为 Rack env 的某些部分不喜欢被重用)。

于 2015-06-05T19:28:29.730 回答