【问题标题】:Rails: thread_mattr_accessor randomly becoming `nil` in developmentRails:thread_mattr_accessor 在开发中随机变为“nil”
【发布时间】:2020-10-03 23:02:26
【问题描述】:

在 Rails 5.2.2.4 中,我遇到了这种莫名其妙的行为,其中 thread_mattr_accessor 随机变为 nil

鉴于此模块:

module Test

  thread_mattr_accessor :max_installments

  self.max_installments = 12

end

在 6 次寻呼机刷新中(在开发中使用 Puma),当将整数与该变量进行比较时,我得到一个 comparison of Integer with nil failed

在 Rails 红色异常页面上,我可以使用底部控制器来确认它实际上是 nil!

但是,只需刷新页面几次,我最终会在设置了该变量的情况下获得正常的页面加载。

什么可能将其设置为零?除了上面类定义中的 self.max_installments= 之外,没有任何代码可以将该变量设置为其他任何位置。

【问题讨论】:

  • 我会检查thread_mattr_accessor 的实现。可能是 Rails 中的错误。

标签: ruby-on-rails ruby


【解决方案1】:

模块测试

module Test
  thread_mattr_accessor :max_installments
  self.max_installments = 12
end

正常使用

puts "max_installments is: #{Test.max_installments.inspect}"
# max_installments is: 12

在线程中使用

Thread.new { puts "max_installments in thread is #{Test.max_installments.inspect}" }
# max_installments in thread is nil

在线程内部设置值

Thread.new do
  Test.max_installments = 99
  puts "max_installments in thread now is #{Test.max_installments.inspect}"
end
# max_installments in thread now is 99

Thread.new { puts "max_installments in another thread is #{Test.max_installments.inspect}" }
# max_installments in another thread is nil

puts "max_installments is: #{Test.max_installments}"
# max_installments is: 12

必须尽快释放this commit,我们可以设置一个默认值以在这样的线程中使用

module Test
  thread_mattr_accessor :max_installments, default: 12
  self.max_installments = 12
end

目前,如果你在线程内部使用,你需要在之前设置值以避免得到 nil。

【讨论】:

  • 感谢您指出可以设置default 的提交。虽然这没有出现,但您如何处理有时需要以线程安全的方式更改(例如,在并行测试期间)的类级设置?使用简单的类变量或类实例变量不是线程安全的,并且使用 thread_mattr_accessor 并不实用,因为我无法在类本身或初始化程序中设置它的值,因为新旋转的线程不会看到它的值。
  • 我也在寻找一个苗条又聪明的替代品@sandre89
猜你喜欢
  • 2019-03-25
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 2013-05-09
相关资源
最近更新 更多