shahryarjb
Elixir developer `iex` does not load module that uses macro, when it is compiled
Hello friends, I do not think this problem of mine exists in production build ( I did not test it), but in developer mode iex -S mix.
imagine you have this module
defmodule PluginWorker do
use Worker, concurrency: 1
def perform(event: event, type: :start) do
....
end
end
If I run my iex, and call it inside the function_exported? it returns true.
but when I use it like this:
@impl true
# The task completed successfully
def handle_info({ref, _answer}, %{ref: ref} = state) do
Process.demonitor(ref, [:flush])
# HERE
function_exported?(PluginWorker, :worker?, 0)
|> IO.inspect(label: "=-==-=-=>") # false
Queue.new(%{
worker: PluginWorker,
error: %{type: :continuously, max_try: 5, delay: 1000}
})
{:noreply, %{state | ref: nil}, {:continue, :start_service_restoring}}
end
As you see it returns false my question is, how can have this builded in iex developer env and test, and the other problem is, it is a problem in production build? like release
Test mode
In test mode I am forced to call some modules in test_helper.exs file before testing, because without it inside my tests they are no be compiled before
for example:
ExUnit.start()
# Help to compile workers
MishkaInstallerTest.Support.MisWorkerOne.worker?()
WorkerTwo.worker?()
WorkerThree.worker?()
PluginWorker.worker?()
Thank you in advance
Marked As Solved
03juan
In dev and test modes the system is running in interactive mode, so the module may not be available before you try to use it. You can use ensure_loaded!/1 before function_exported?/3 to force the BEAM to load it. You wouldn’t have this problem in production because all modules are loaded at start-up in embedded mode.
Also Liked
03juan
Great!
Just 2 things to keep in mind.
You don’t need to test for the environment.
If the module is already loaded, this works as no-op. If the module was not yet loaded, it tries to load it.
Maybe use the ! version so the compiler fails in case the module isn’t found, otherwise you’ll only find out at runtime like you saw in your failing tests.
03juan
I think you can use it in the module declaration just above the handle callback, then it’s only run once during compilation
shahryarjb
Yes after your help, I put it like this
defmodule MishkaInstaller.PluginsManagement.Event do
use GuardedStruct
use GenServer
...
import MnesiaAssistant, only: [er: 1, erl_fields: 4]
if Mix.env() in [:dev, :test] do
Code.ensure_loaded(PluginWorker)
end
def ... do
....
end
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








