我必须编写一个线程化的 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 操作,两者是否会设置相同的 @current_user 变量?即第一个请求在处理 .html.erb 文件时会发现它的@current_user 实例变量突然被第二个线程更改了吗?
谢谢