每个HTTP请求是否有一个Rack应用程序实例?

时间:2011-02-07 02:21:39

标签: ruby design-patterns facebook sinatra rack

我正在使用Facebook app called Lovers构建Sinatra app on Heroku。它在Heroku's bamboo-mri-1.9.2 stack上的Ruby 1.9.2上运行。

这是一个modular Sinatra app,在Lovers source code中,我为Sinatra应用的每个实例(Lovers::Application)提供Facebook::Application的实例:

require 'sinatra/base'

class Lovers::Application < Sinatra::Base
  attr_reader :facebook

  def initialize(app=nil)
    @facebook = Facebook::Application.new(
      Lovers::Conf.fb_app_id,
      Lovers::Conf.fb_app_secret,
      Lovers::Conf.fb_canvas_name)
    super(app)
  end
  # ...
end

这样,您可以Lovers.application.facebookFacebook::Application模块中的任何位置访问Lovers实例,例如Lovers::User

这是否有意义,或者我是否只有Lovers::Application的所有实例(如果有多个实例)共享相同的Facebook::Application实例,即Lovers.facebook。这就是我们为Redis做的事情:Lovers.redis,这对我来说很有意义。我想我倾向于将它改为后者,但我想在改变它之前确定它。你觉得怎么样?

最后,每个HTTP请求是否有Lovers::Application个实例?

更新:

我读了Heroku Dynos。显然,每个dyno(进程)都运行Lovers::Application的实例。因此,在阅读了sharing a global variable among processes之后,我认为这意味着如果我在@@hit_count类中定义类变量Lovers::Application,它将具有不同的值,具体取决于哪个dyno接收请求,假设每次请求主页时我都会增加@@hit_count,即:

  @@hit_count = 0

  get "/" do
    @@hit_count += 1
  end

1 个答案:

答案 0 :(得分:2)

“最后,每个HTTP请求是否有一个Lovers :: Application的实例?”

每个进程/ dyno有一个实例。

“它将具有不同的值,具体取决于哪个dyno收到请求,假设每次请求主页时我都会增加@@ hit_count”

是的,如果您需要全局状态,则必须将状态保持在进程/ dyno之外。有许多不同的方法可以执行此操作,您选择的方法取决于应用的详细信息和流量级别。如果您没有获得大量流量,您可以执行一些简单的操作,只需将其保留在数据库中即可。你可以在postgres或mysql中为hit_count之类的东西做原子增量。但是,如果您有大量流量,这种方法可能会成为瓶颈。