Ruby on rails 线程的安全性。当前[]在rails中的使用
在Ruby on rails 线程的安全性。当前[]在rails中的使用,ruby-on-rails,thread-safety,Ruby On Rails,Thread Safety,在线程.current散列(例如,当前用户、当前子域等)中存储信息的做法上,我不断收到相互矛盾的意见。该技术被认为是一种简化模型层中后期处理(查询范围、审核等)的方法 许多人认为这种做法是不可接受的,因为它打破了MVC模式。 其他人对该方法的可靠性/安全性表示担忧,我的问题分为两部分,主要关注后一个方面 线程.current哈希是否保证在其整个周期内对一个且仅一个响应可用且私有 我知道,在响应结束时,一个线程很可能会被移交给其他传入请求,从而泄漏thread.current中存储的任何
线程.current
散列(例如,当前用户、当前子域等)中存储信息的做法上,我不断收到相互矛盾的意见。该技术被认为是一种简化模型层中后期处理(查询范围、审核等)的方法
线程.current
哈希是否保证在其整个周期内对一个且仅一个响应可用且私有thread.current
中存储的任何信息。在响应结束之前清除此类信息(例如,通过在控制器的过滤器之后执行线程.current[:user]=nil
)是否足以防止此类安全漏洞
Giuseppe没有特定的理由远离线程局部变量,主要问题是:
- 测试它们比较困难,因为在测试使用线程局部变量的代码时,必须记住设置线程局部变量
- 使用线程局部变量的类需要知道这些对象对它们来说不是可用的,而是在线程局部变量中,这种间接寻址通常会破坏
- 如果框架重用线程,则不清理线程局部变量可能是一个问题(线程局部变量可能已经启动,依赖|124;=调用初始化变量的代码可能会失败)
around_filter :do_with_current_user
def do_with_current_user
Thread.current[:current_user] = self.current_user
begin
yield
ensure
Thread.current[:current_user] = nil
end
end
这确保了线程局部变量在循环使用之前被清理干净。这个小宝石确保线程/请求局部变量不会在请求之间粘滞:接受的答案在技术上是准确的,但正如回答中所指出的,在“不那么温和”中: 不要使用线程本地存储,
thread.current
,如果您不一定非得使用
gem for是另一个解决方案(更好),但请阅读其中的自述文件,了解更多远离线程本地存储的原因
几乎总是有更好的方法。公认的答案涵盖了这个问题,但Rails 5现在提供了一个使用Thread.current的“抽象超类” 我想我会提供一个链接,作为一个可能的()解决方案
查看“线程变脏。当前”这是Jruby的一位作者写的。#1 ROR代码本身使用Thread.current表示I18N和时区。这是否说明了它的保证?#2.如果#1为真,那么就足够了。谢谢,我添加了参考。在您链接的帖子中,示例专门处理控制器层,建议的解决方案是obvi非常合适。不过,我怀疑,大多数人会感兴趣的是一种干净的方式,让模型访问通常不允许他们访问的1-2条信息,而不向每个模型调用添加额外的参数。在这方面,所有那些大的可怕的“远离线程。当前”到目前为止,没有具体原因的警告标志让我感到不确定。感谢使用带有“确保”块的环绕过滤器,如果您不十分小心,它将干扰异常处理/日志记录。请查看Dejan答案中的RequestStore,以获得一个基于中间件的更干净的解决方案。可能是我解决问题的方法,因为我正在拯救exc先期验收(而不仅仅是如上所述的确保)。异常的调用堆栈被重置到我重新引发的位置,弄乱了Rails错误日志和其他地方。我最终手动将捕获的异常转储到日志文件中以保留它,但这很难看。使用基于中间件的方法更干净。这就是为什么上面的代码只有一个
确保阻止,不尝试捕获异常。当您看到它时很简单:)我正在使用Unicorn with Rails多租户应用程序。你能举一个“更好的方式”的例子吗?您发布的链接引发应用程序错误。谢谢