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

Incompatibility with Ruby 3.0.0 #98

Closed
luizkowalski opened this issue Feb 8, 2021 · 11 comments
Closed

Incompatibility with Ruby 3.0.0 #98

luizkowalski opened this issue Feb 8, 2021 · 11 comments

Comments

@luizkowalski
Copy link

I'm running Rails (6.1.1) and Valvat (1.1.0) on Ruby 2.7.2 and it works fine.
Now I'm trying to upgrade to Ruby 3.0.0 and get this weird issue where the main thread appears to be blocked by something. Nothing happens, no output, no log in the console, nothing. I can't even ctrl-c to stop the process, I have to kill Ruby. I tracked it down to Valvat: removing the allows the app to run fine.

@yolk
Copy link
Owner

yolk commented Feb 8, 2021

Hi Luiz,

thanks for reporting the issue! Some questions:

  • Could you post your Gemfile.lock?
  • Does it occur when making a request?
  • Does the request call any parts of valvat?

@luizkowalski
Copy link
Author

luizkowalski commented Feb 8, 2021

This is my Gemfile.lock: https://gist.github.com/luizkowalski/eb77a463fe13c0bd0a847b20b3d1d5b3

I might have missed some information here, sorry:

So, as it is, if try to start the app or run the specs I get this error:

An error occurred while loading rails_helper.
Failure/Error: require File.expand_path('../config/environment', __dir__)

SystemStackError:
  stack level too deep
# ./config/initializers/doorkeeper.rb:3:in `<top (required)>'
# ./config/environment.rb:7:in `<top (required)>'
# ./spec/rails_helper.rb:5:in `require'
# ./spec/rails_helper.rb:5:in `<top (required)>'
No examples found.

At first, I thought the issue was on Doorkeeper, so I completely removed it from the application. What I got, then, was nothing: webserver didn't boot and running RSpec actually created a ruby process that was just hanging, doing nothing. In both cases, the main thread appears to be waiting for something.

I kept removing gems here and there until I dropped valvat from the application and suddenly everything was working fine: server, doorkeeper, tests, etc.

Answering your questions:

Does it occur when making a request?
Does the request call any parts of valvat?

I couldn't even get to make a request

That's all that I know for now. Let me know if you need anything else

@yolk
Copy link
Owner

yolk commented Feb 8, 2021

Thanks for the details.
Sadly I couldn't reproduce the issue within a new rails app and the gemversions from your Gemfile.lock. Maybe you could try to reproduce it yourself with a minimal rails app?

@luizkowalski
Copy link
Author

well, I will keep digging it, maybe I find something else then because I doubt I could reproduce if you couldn't

Thanks for your help! 🤗

@luizkowalski
Copy link
Author

luizkowalski commented Feb 10, 2021

hey @yolk!

yesterday I spent hours and hours debugging this and I found a couple of things (and even made it work).

So this is what I found: valvat wasn't the only thing causing this issue on my code. I had two initializers that were loading classes that now need to happen in a block, like this:

Rails.application.reloader.to_prepare do
  MyClass.
    prepend(FakeMixin)
end

I did this for some initializers, restarted and it worked but again when I added valvat back, the main thread hanged. then, I checked out valvat locally and started to debug what was going on with it, and found another issue:

https://github.com/yolk/valvat/blob/master/lib/active_model/validations/valvat_validator.rb#L102

this line, when commented/removed, completely stops this issue and valvat can be used again.

I have no idea why but I assume it has something to do with class loading on Ruby 3/Rails 6.1.x? What do you think can be done here?

For testing this, I wrapped this code with reloader:

if defined?(ActiveSupport)
  ActiveSupport::Reloader.to_prepare do
    I18n.load_path += Dir["#{File.dirname(__FILE__)}/../../valvat/locales/*.yml"]
  end
end

and this also worked but I'm not sure if this could be done

@yolk
Copy link
Owner

yolk commented Feb 10, 2021

Thanks a lot for all the hours! I'll dig into it as soon as possible.

@yolk
Copy link
Owner

yolk commented Feb 10, 2021

I found a similar issue: heartcombo/simple_form#1724
The reason seems to be that ruby 3 already implements Hash#except and the current version of I18n overwrites this method, what causes the SystemStackError on SimpleForm (but only in combination with other gems like ancestry).

But I am still not able to reproduce the issue with valvat. Maybe you could try this patch of I18n in your app: ruby-i18n/i18n#557

Thanks!

@luizkowalski
Copy link
Author

this is really interesting! really nice find! thanks a lot for this

right now I put the migration on hold because Ruby 3 also introduced a new regression and I will have to wait for a new release but I'll follow these issues and play with this in my free time

thanks again! if you want to close it I guess it is fine with me

@yolk
Copy link
Owner

yolk commented Feb 10, 2021

Thanks for the update. I'll guess I keep the issue open till it is resolved in I18n.

@yolk
Copy link
Owner

yolk commented Feb 15, 2021

@luizkowalski Seems to be resolved with I18n 1.8.9: ruby-i18n/i18n#557 (comment)

@yolk yolk closed this as completed Feb 15, 2021
@luizkowalski
Copy link
Author

perfect, @yolk! thanks a lot for your help here

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

No branches or pull requests

2 participants