Rails Thread.current []&线程安全

时间:2015-09-18 01:54:42

标签: ruby-on-rails ruby thread-safety

所以我就是,对吧。只是看一些代码,突然研究点点滴滴,我的眼受体被陌生人攻击了。我当时想:

  

什么!那是什么意思!

无论如何,我看到的是(source):

def authenticate_user!
  if doorkeeper_token
    Thread.current[:current_user] = User.find(doorkeeper_token.resource_owner_id)
  end

  # ...
end

所以看了一会儿之后,想一想:

  

Wtf是Thread.current[]这种疯狂吗?这甚至是必要的吗?它甚至试图做什么?

在我看来,它有点像向后戴棒球帽:你可能看起来很酷,但太阳眩光正在赢得。然后我决定到谷歌周围,阅读一些文章和一些SO。

似乎没有简洁地回答我的问题:鉴于代码的上下文,它是否与以下内容不同:

def authenticate_user!
  if doorkeeper_token
    @current_user = User.find(doorkeeper_token.resource_owner_id)
  end

  # ...
end

如果没有,那么什么情况/场景有用/防范?

我希望你喜欢我的故事,并希望贡献一个很棒的结局。

2 个答案:

答案 0 :(得分:5)

您可以使用不同的公告板来固定信息。发布local variables的公告牌隐藏在树篱后面,居住在下一个院子里的观点无法看到:

current_user = User.find(doorkeeper_token.resource_owner_id)

张贴@variables的公告牌被钉在梯子的顶部,因此视图可以无遮挡地看到对冲顶部的@variables:

@current_user = User.find(doorkeeper_token.resource_owner_id)

但是其他方法,住在街对面的班级,看不到@variables发布在梯子顶部的公告牌上,因为一排树正在挡路。

Thread variables,例如:

Thread.current[:current_user] = User.find(doorkeeper_token.resource_owner_id)
发射一只比树高的风筝,放在风筝上的变量可以通过街对面的方法看到。

为什么不创建红宝石global variable,例如$ current_user,而不是?因为不同用户同时发起的请求将写入相同的全局变量,可能会搞砸了。

  

给出代码的上下文

没有足够的上下文来说明为什么需要(线程)全局变量。

答案 1 :(得分:0)

来自作者:

  

我使用Thread来存储当前用户能够透明   验证用户并在以后扩展。目前这段代码给出了   通过Doorkeepr优先进行基于令牌的身份验证,您可以   将其扩展到任何其他算法。我不是Devise的忠实粉丝   不想使用它提供的基于令牌的身份验证策略。

     

在Thread.currrent [:current_user]中编写用户信息后,任何   其他服务可以独立阅读并用于任何目的   这是必需的。例如,正如我上面提到的,检查   授权,记录谁做了系统中发生的事件等

     

至于将其写入@current_user,我不确定是否会这样   在所有情况下均可访问。但我还没有真正检查过这个

参考:https://github.com/rilian/devise-doorkeeper-cancan-api-example/issues/1#issuecomment-143479288