线程安全的Rails控制器操作 - 设置实例变量?

Asf*_*azi 11 ruby-on-rails thread-safety

我必须编写一个线程化的Rails应用程序,因为我在Neo4j.rb上运行它,它在Rails进程中嵌入了一个Neo4j图形数据库,因此我必须提供来自同一进程的多个请求.是的,如果连接到像SQL数据库一样的Neo4j数据库会很酷,但事实并非如此,所以我会放弃抱怨而只是使用它.

我非常担心编写并发代码的含义(我应该这样做),并且只需要一些关于如何处理常见情况的建议 - 控制器在会话哈希中设置实例变量或变量,然后是一些东西发生.考虑以下粗略代码来证明我的意思:

# THIS IS NOT REAL PRODUCTION CODE
# I don't do this in real life, it is just to help me ask my question, I
# know about one-way hashing, etc.!

class SessionsController
  def create
    user = User.find_by_email_and_password(params[:email], params[:password])
    raise 'auth error' unless user
    session[:current_user_id] = user.id
    redirect_to :controller => 'current_user', :action => 'show'
  end
end

class CurrentUserController
  def show
    @current_user = User.find(session[:current_user_id])
    render :action => :show # .html.erb file that uses @current_user
  end
end
Run Code Online (Sandbox Code Playgroud)

问题:此代码中是否存在任何竞争条件?

在SessionsController中,session散列和params散列线程是本地的吗?假设同一个浏览器会话使用不同的凭据向/ sessions #crera(借用Rails路由语法)发出多个请求,登录的用户应该是session[:current_user_id] = user.id最后一行的请求?或者我应该在控制器操作周围包装一个互斥锁吗?

在CurrentUserController中,如果两个具有不同会话的请求同时命中show动作,那么两个都会设置相同的@current_user变量吗?即第一个请求,因为它正在处理.html.erb文件,发现它的@current_user实例变量突然被第二个线程更改了?

谢谢

Fre*_*ung 12

每个请求都会获得一个新的控制器实例.因此,控制器实例变量是线程安全的.params并且session还由控制器实例变量(或请求对象本身)支持,因此也是安全的.