【发布时间】:2012-08-17 10:04:01
【问题描述】:
我必须编写一个线程化的 Rails 应用程序,因为我在 Neo4j.rb 上运行它,它在 Rails 进程中嵌入了一个 Neo4j 图形数据库,因此我必须处理来自同一进程的多个请求。是的,如果连接到 Neo4j 数据库像 SQL 数据库一样工作,那就太酷了,但事实并非如此,所以我不再抱怨,直接使用它。
我非常担心编写并发代码的影响(我应该这样做),并且只需要一些关于如何处理常见场景的建议 - 控制器在会话哈希中设置实例变量或变量,然后发生了一些事情。考虑以下粗略的代码来说明我的意思:
# 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
问题:这段代码中是否存在竞争条件?
在 SessionsController 中,session 哈希和 params 哈希是线程本地的吗?假设同一个浏览器会话使用不同的凭据向 /sessions#create 发出多个请求(借用 Rails 路由语法),登录的用户应该是最后击中session[:current_user_id] = user.id 行的请求?或者我应该在控制器动作周围加上一个互斥锁?
在 CurrentUserController 中,如果 show action 被两个不同会话的请求同时触发,是否会同时设置相同的 @current_user 变量? IE。第一个请求在处理 .html.erb 文件时会发现它的 @current_user 实例变量突然被第二个线程更改了吗?
谢谢
【问题讨论】:
标签: ruby-on-rails thread-safety