Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FormBuilder.attempt_mapping is taking > 1 second #1790

Closed
egeek opened this issue Sep 27, 2022 · 0 comments
Closed

FormBuilder.attempt_mapping is taking > 1 second #1790

egeek opened this issue Sep 27, 2022 · 0 comments

Comments

@egeek
Copy link

egeek commented Sep 27, 2022

Environment

  • Ruby 3.1.2
  • Rails 7.0.4
  • Simple Form 5.1.0

Current behavior

This may be related to our Gemfile, and some additional gems that are extending the exception message processing, however what we are seeing is that in FormBuilder

    def attempt_mapping(mapping, at)
      return if SimpleForm.inputs_discovery == false && at == Object

      begin
        at.const_get(mapping)
      rescue NameError => e
        raise if e.message !~ /#{mapping}$/
      end
    end

the raise if e.message !~ /#{mapping}$/ is taking over 1000ms for the first lookup of that type of field (e.g. NumericInput) on a form. I believe that it's attempting to check if the exception message contains the name of the class that was searched for, e.g. (from my hacking about earlier to see what the issue was)

14:54:44 web.1                        | "NumericInput"
14:54:44 web.1                        | Object
14:54:44 web.1                        | #<NameError: uninitialized constant NumericInput
14:54:44 web.1                        | 
14:54:44 web.1                        |         res = at.const_get(mapping)
14:54:44 web.1                        |                 ^^^^^^^^^^>
14:54:44 web.1                        | 
14:54:44 web.1                        | 
14:54:44 web.1                        | SJH attempt_mapping RAISE TIME = 1159.357387

If I change the above line of code to raise unless e.is_a? NameError then the execution time drops to < 1 ms, e.g.

15:42:17 web.1                        | SJH attempt_mapping RAISE TIME = 0.008567

I believe that this keeps the same behaviour, as it will raise the exception if there's anything other than the NameError that was being checked for.

I don't believe the slow down is due to simple_form, the line of code in question hasn't changed in 10 years, and we can see the same slow down if we just log out the exception message in the function, e.g.

puts "SJH attempt_mapping #{e.inspect}"

also takes 1000 ms. But I believe the change from raise if e.message !~ /#{mapping}$/ to raise unless e.is_a? NameError should be relatively low risk to implement in simple_form and would prevent others from tripping over this. We aren't experiencing this behaviour elsewhere in our application as we handling exceptions based on their type rather than their contents.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant