【问题标题】:Is there one Rack app instance per HTTP request?每个 HTTP 请求是否有一个 Rack 应用程序实例?
【发布时间】:2011-02-13 08:47:15
【问题描述】:

我正在构建一个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.facebookLovers 模块中的任何位置访问Facebook::Application 实例,例如从Lovers::User

这有意义吗,或者我应该让Lovers::Application 的所有实例(如果不止一个)共享同一个Facebook::Application 实例,即Lovers.facebook。这就是我们为 Redis 所做的事情:Lovers.redis,这对我来说很有意义。我想我倾向于将其更改为后者,但我想在更改之前确定。你怎么看?

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

更新:

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

  @@hit_count = 0

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

【问题讨论】:

    标签: ruby design-patterns facebook sinatra rack


    【解决方案1】:

    “最后,每个 HTTP 请求都有一个 Lovers::Application 实例吗?”

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

    “假设每次请求主页时我都会增加@@hit_count”

    是的,如果您需要全局状态,则必须将状态保留在您的进程/测功机之外。有许多不同的方法可以做到这一点,您选择哪种方法取决于您的应用程序的详细信息和您的流量水平。如果您没有获得大量流量,您可以做一些简单的事情,例如将其保存在数据库中。您可以在 postgres 或 mysql 中为 hit_count 之类的东西做原子增量。但是,如果您有大量流量,这种方法可能会成为瓶颈。

    【讨论】:

    • 您能否详细说明一些将状态保持在流程之外的可能想法?我目前正在尝试提出一个好的解决方案,以避免将值存储在数据库中 - 在高流量环境中不会出现这种情况。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 2012-01-04
    • 2014-01-23
    • 1970-01-01
    • 2021-11-16
    • 2011-08-22
    相关资源
    最近更新 更多