sandre89
sandre89

Reputation: 5908

Rails: thread_mattr_accessor randomly becoming `nil` in development

In Rails 5.2.2.4, I'm getting this inexplicable behavior where a thread_mattr_accessor is becoming nil randomly.

Given this module:

module Test

  thread_mattr_accessor :max_installments

  self.max_installments = 12

end

Out of 6 pager refreshes (using Puma in development), I get a comparison of Integer with nil failed when comparing an integer with that variable.

On the Rails red exception page, I can use the bottom controller to confirm it's actually nil!

However, simply refreshing the page some times, I will eventually get a normal page load with that variable being set.

What might be setting that to nil? There's no code at all that sets that variable anywhere else other than the self.max_installments= in the class definition above.

Upvotes: 0

Views: 721

Answers (1)

thiaguerd
thiaguerd

Reputation: 847

Module Test

module Test
  thread_mattr_accessor :max_installments
  self.max_installments = 12
end

Normal use

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

In Thread use

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

Set value inside the thread

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

ASAP this commit must be released and we can set a default value to use in threads like this

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

For now, if you go use inside threads, you need set value before to avoid get nil.

Upvotes: 1

Related Questions