Where is the correct place to initialize BigDecimal limit when using Puma

Viewed 135

I have a rails initializer that sets the limit on Big Decimal

BigDecimal.limit(20)

This is executed and seems to set the limit properly.

But when a web request comes in (I am using Puma), the limit does not appear to be set on the thread that handles the request. The limit is set to 0 which is the default.

Is there somewhere else I should be setting the limit?

If you want to reproduce:

create a brand new rails app and add an initializer that sets limit

BigDecimal.limit(20)
puts "*** Set #{BigDecimal.limit}"

in your application controller add

before_action :check_big_decimal

def check_big_decimal
  puts "***request #{BigDecimal.limit}"
end

start your server, refresh page and make a request

You should see it set to 20 but then it is back to 0 when the request comes in.

2 Answers

I got an answer from the Rails community

Basic gist is:

This happens because Ruby stores the BigDecimal limit in thread local storage. When e.g. Puma starts a new thread to handle a request, the new thread can't access the BigDecimal limit set in the initial thread.

A hacky and not recommended way is by monkey patching the class. You can add this in an initializer

class BigDecimal
  def self.limit(val = 25)
    25
  end
end

The question is, do you really really want to limit to 25 everywhere? if yes, then you can try this as a LAST RESORT, because I'm not sure about the side effects of hardcoding that value (and overriding that method at all)

Related