Ruby 在基于机架的应用程序中为每个HTTP请求创建新的控制器实例更好还是使用相同的实例更好?

Ruby 在基于机架的应用程序中为每个HTTP请求创建新的控制器实例更好还是使用相同的实例更好?,ruby,rack,Ruby,Rack,我正在创建一个非常简单的基于机架的应用程序,因为我希望它能够完成一项非常具体的任务 server.rb看起来像这样: Path= File.expand_path("#{File.dirname __FILE__}/../../") require "bundler/setup" require "thin" require "rack" %w(parser auth controller).each do |file| require "#{Path}/app/server/#{fi

我正在创建一个非常简单的基于机架的应用程序,因为我希望它能够完成一项非常具体的任务

server.rb
看起来像这样:

Path= File.expand_path("#{File.dirname __FILE__}/../../")

require "bundler/setup"
require "thin"
require "rack"

%w(parser auth controller).each do |file| 
  require "#{Path}/app/server/#{file}.rb"
end


builder = Rack::Builder.app do
  use Auth
  run Parser.new    
end

Rack::Handler::Thin.run(builder, :Port => 8080, :threaded => true)
parser.rb
看起来像:

class Parser

  def initialize
    @controller = Controller.new
  end

  def call(env)
    req = Rack::Request.new(env).params
    res = Rack::Response.new
    res['Content-Type'] = "text/plain"

    command= req[:command]

    if command =~ /\A(register|r|subscribe|s)\z/i
      @controller.register     
    end


    res.write command
    res.finish 

  end
end
现在我的问题是,从设计的角度来看,创建一个
Controller
实例并将其用于每个请求(就像上面代码中的Idid一样),还是为每个请求创建新的控制器实例(将
@Controller.register
更改为
Controller.new.register
)更好?使用哪一种更好?为什么


提前感谢

每个请求创建一个新控制器的开销可能不会太大

如果将状态存储在控制器(实例变量等)中并重用它,则可能会遇到并发问题,例如在加载时出现争用条件或死锁

如果注意确保控制器对象不存储任何状态,则可以重用它。如果它对每个请求执行任何类型的状态存储,则需要确保共享资源的属性同步


My 2c-为每个请求创建一个新控制器,直到您确认为每个请求创建一个新控制器对性能有影响为止。它更简单、更干净,更不容易出现奇怪的bug。

每个请求创建一个新控制器的开销可能不会太大

如果将状态存储在控制器(实例变量等)中并重用它,则可能会遇到并发问题,例如在加载时出现争用条件或死锁

如果注意确保控制器对象不存储任何状态,则可以重用它。如果它对每个请求执行任何类型的状态存储,则需要确保共享资源的属性同步


My 2c-为每个请求创建一个新控制器,直到您确认为每个请求创建一个新控制器对性能有影响为止。它更简单、更干净,更不容易出现奇怪的bug。

非常感谢,有意义。我认为压力测试可以给我一个表现的指标。但我完全同意,每个请求的新控制器更简单,更干净。我假设GC在新对象完成工作后会清理它们,我希望我可以通过信号捕获之类的方式来跟踪它们,这样我就可以检查对象的状态以及清理的时间,如果你知道我应该怎么做那就太好了。一旦对象超出范围,GC应该清理它们。我使用JRuby,所以我利用了JVM的GC,但我无法想象ruby GC会留下过时的对象。非常感谢,这很有意义。我认为压力测试可以给我一个表现的指标。但我完全同意,每个请求的新控制器更简单,更干净。我假设GC在新对象完成工作后会清理它们,我希望我可以通过信号捕获之类的方式来跟踪它们,这样我就可以检查对象的状态以及清理的时间,如果你知道我应该怎么做那就太好了。一旦对象超出范围,GC应该清理它们。我使用JRuby,所以我利用了JVM的GC,但我无法想象ruby GC会留下过时的对象。