GithubHelp home page GithubHelp logo

Comments (13)

fxn avatar fxn commented on July 24, 2024 3

I think I have it.

Essentially, what is happening is that eager loading is implemented as a breadth-first recursion calling require, and that is not consistent with the logic while setting autoloads that discards late files with the same relative name mimicking $LOAD_PATH semantics.

The reason is that by design we use only absolute file names, and both require calls succeed because the file names are different, so the one in devise wins because it runs later.

The gist of the problem is shown here:

$ cat a/foo.rb
Foo = :a
$ cat b/foo.rb
Foo = :b
$ cat test.rb
require "zeitwerk"

$VERBOSE = nil

lA = Zeitwerk::Loader.new
lA.push_dir("a")
lA.setup

lB = Zeitwerk::Loader.new
lB.push_dir("b")
lB.setup

p Foo

lA.reload
lB.reload

lA.eager_load
lB.eager_load

p Foo

The output of the test is

:a
:b

which is not consistent, it should print :a twice.

In the early prototypes of Zeitwerk I mantained a structure with constants to be loaded, and triggered autoloads instead of using require, it could be the case that I might need to go back to that initial implementation.

I'll think how to address it, but we'll do something.

from zeitwerk.

fxn avatar fxn commented on July 24, 2024 1

Could you please try branch eager-load-skip? I have drafted a fix.

from zeitwerk.

fxn avatar fxn commented on July 24, 2024

I deleted the previous comment. I have been able to reproduce now the steps above and the DeviseHelper module from the app gets the autoload set first. Need to investigate with the real thing.

from zeitwerk.

excid3 avatar excid3 commented on July 24, 2024

Thanks for checking it out @fxn! My first assumption was that basically that I was doing thing module override wrong, like you mentioned in your previous comment. Then we found it strange that things were different with eager_load on and off since it wasn't consistent. Curious to learn what's going on. 👍

from zeitwerk.

cj avatar cj commented on July 24, 2024

@fxn that works for me!

@excid3 did you want to give it a try?

from zeitwerk.

excid3 avatar excid3 commented on July 24, 2024

Worked perfect. Thanks @fxn, that was quick!

from zeitwerk.

cj avatar cj commented on July 24, 2024

I think I may have found another "bug".

If you set config.eager_load = false run it in development with 'foreman start' and once it starts up add this line after_action { pp 'foo' } to app/controllers/application_controller.rb; refresh the page and you will notice foo does not get logged.

If you repeat the previous steps (delete that line added to application.rb first) and before running foreman start set config.autoloader = :classic, when you add that line in now and refresh the page it will print out foo just fine.

from zeitwerk.

fxn avatar fxn commented on July 24, 2024

Regarding eager loading, I'll polish the code and publish a new version of the gem.

The issue @cj mentions seems different (and surprising!), maybe deserves a different ticket. Did you restart the server after changing the configuration? If yes, could you please enable logging in config/application.rb:

Rails.autoloaders.logger = method(:puts)

reproduce, and share the entire log specifying at which point did you change and reload?

from zeitwerk.

fxn avatar fxn commented on July 24, 2024

@cj just in case... do you have config.cache_classes set to false? It should be for reloading to work.

from zeitwerk.

cj avatar cj commented on July 24, 2024

@fxn I can open up a new ticket if you would like.

I'm using the same template as used in this issue which is rails new myapp -d postgresql -m https://raw.githubusercontent.com/excid3/jumpstart/c6c0de0/template.rb it creates a standard config/environments/development.rb file with the contents of https://gist.github.com/cj/45d48da8b7bfbd11bbaaacb04abd6ff8 where config.cache_classes is indeed false.

When I say, "it does not get logged", I mean it does not get printed out in the console where the command foreman start was ran.

I am adding this line after_action { pp 'foo' } to app/controllers/application_controller.rb after the rails server has started and finished loading from running foreman start. When I refresh the browser I should see foo printed to the console where foreman is running, but I do not. If however I kill foreman, remove the line I added after_action { pp 'foo' } and add config.autoloader = :classic to config/environments/development.rb, start the server back up with foreman start and add back in the line after_action { pp 'foo' } to app/controllers/application_controller.rb; refresh the browser, I see foo printed out to the console as expected.

I hope this makes sense, if you need me to record a screencast or go in to more detail let me know.

from zeitwerk.

cj avatar cj commented on July 24, 2024

One other thing to note is I have spring disabled (http://fuzzyblog.io/blog/rails/2017/03/20/disabling-spring-in-rails.html).

from zeitwerk.

fxn avatar fxn commented on July 24, 2024

@cj did you see the comment above re printing Zeitwerk traces?

Yeah, better create a new ticket for this one please.

from zeitwerk.

fxn avatar fxn commented on July 24, 2024

The just published 1.3.4 has this solved, thanks for the bug report!

from zeitwerk.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.