线程安全的 Rails 控制器操作 - 设置实例变量? [英] Thread-safe Rails controller actions - setting instance variables?
问题描述
我必须编写一个线程化的 Rails 应用程序,因为我在 Neo4j.rb 之上运行它,它在 Rails 进程中嵌入了一个 Neo4j 图形数据库,因此我必须为来自同一进程的多个请求提供服务.是的,如果连接到 Neo4j 数据库像 SQL 数据库一样工作会很酷,但事实并非如此,所以我不再抱怨,直接使用它.
I have to write a threaded Rails app because I am running it atop of Neo4j.rb, which embeds a Neo4j graph database inside the Rails process, and thus I have to serve multiple requests from the same process. Yeah, it'd be cool if connecting to a Neo4j database worked like SQL databases, but it doesn't, so I'll quit complaining and just use it.
我非常担心编写并发代码的影响(正如我应该的那样),并且只需要一些关于如何处理常见场景的建议 - 控制器在会话哈希中设置实例变量或变量,然后会发生一些事情.考虑以下粗略的代码来演示我的意思:
I'm quite worried about the implications of writing concurrent code (as I should be), and just need some advice on how to handle common a common scenario - a controller sets an instance variable or a variable in the session hash, then some stuff happens. Consider the following crude code to demonstrate what I mean:
# 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
问题:这段代码中是否存在竞争条件?
The question: Are there any race conditions in this code?
在 SessionsController 中,session
哈希和 params
哈希是线程本地的吗?假设同一个浏览器会话使用不同的凭据向/sessions#create(借用 Rails 路由语法)发出多个请求,登录的用户应该是命中该行的请求 session[:current_user_id] = user.id
最后?或者我应该在控制器动作周围包裹一个互斥锁?
In SessionsController, are the session
hash and the params
hash thread-local? Say the same browser session makes multiple requests to /sessions#create (to borrow Rails route syntax) with different credentials, the user that is logged in should be the request that hit the line session[:current_user_id] = user.id
last? Or should I wrap a mutex lock around the controller action?
在 CurrentUserController 中,如果两个不同会话的请求同时触发 show 动作,是否会设置相同的 @current_user 变量?IE.第一个请求在处理 .html.erb 文件时会发现它的 @current_user 实例变量突然被第二个线程改变了吗?
In the CurrentUserController, if the show action is hit simultaneously by two requests with different sessions, will the same @current_user variable be set by both? I.e. will the first request, as it is processing the .html.erb file, find that it's @current_user instance variable has suddenly been changed by the second thread?
谢谢
推荐答案
每个请求都有一个 控制器的新实例.因此控制器实例变量是线程安全的.params
和 session
也由控制器实例变量(或请求对象本身)支持,因此也是安全的.
Each request gets a new instance of your controller. As a consequence controller instance variables are thread safe. params
and session
are also backed by controller instance variables (or the request object itself) and so are also safe.
这篇关于线程安全的 Rails 控制器操作 - 设置实例变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!