Genie.jl
Genie.jl copied to clipboard
Code loading for Multi-file controller modules in Genie v5
Changes to code loading for Genie v5 seem to have broken support for multi-file modules in app/resources.
To reproduce, a simple templated Genie app with the following controller and routes.jl
routes.jl
using Genie.Router
using WatchTonight.TestController
import Random
const rng = Random.MersenneTwister()
route("/") do
serve_static_file("welcome.html")
end
route("/test") do
TestController.test_function(rng)
end
app/resources/TestController/TestController.jl
module TestController
import UUIDs, Random
include("a.jl")
end
app/resources/TestController/a.jl
test_function(rng::Random.AbstractRNG) = UUIDs.uuid4(rng)
This will throw during the "Loading resources" step: ERROR: UndefVarError: Random not defined
.
My guess is this is happening because code loading is trying to include (app/resources/TestController/a.jl
) as a standalone file, rather than through TestController.jl
, which means Random
hasn't been imported.
Moving all the code into a single-file module works fine (eg moving the contents of a.jl
into TestController.jl
). That's obviously fine for small examples like this, but for large, complex controllers it's nice to be able to break up into files. If that's just not possible to support, probably worth documenting in the v4 => v5 migration docs, as multi-file modules worked fine in v4 (eg this example works as expected with v4).
@angusmoore Currently working on a set of features to make auto-loading more powerful and flexible (configurable). It will allow setting the load order and ignoring files, among other things. What happens is that the Genie loader thinks that a.jl
is a model and attempts to load it.
What you can do right now to fix it is to:
a) create a folder inside app/resources/TestController/
, for ex includes/
b) inside this folder put the files like a.jl
c) also inside this folder create an empty .autoload_ignore
file - this will tell Genie to ignore all the files in the folder from auto-loading.
(Let's leave this open, it will be a good test for the upcoming features).
Alternatively you can host these files outside the app/resources/<resource>/
folder, for instance in app/includes
and they won't be auto-loaded.
Yet another optimisation we could do is to not autoload files that start with lowercase letters (as the Julia best practices recommend modules to start with uppercase letters). However, this would be a breaking change.
Great, thanks @essenciary, that's really helpful. I'll use that workaround with .autoload_ignore
. But, yes, happy to leave this open for discussion of upcoming features.
Closing this as .autoload_ignore
and the new .autoload
allow controlling the loading order.