reprise
reprise copied to clipboard
Reloading of nif modules
After a nif module is reloaded, all the nif functions are overwritten by elixir placeholders.
defmodule test_nif do
require Logger
@on_load :init
def init() do
:erlang.load_nif("./priv/test_nif", 0)
:ok
end
def test_a() do
Logger.error "NIF library not loaded"
end
end
After reloading test_a.beam, test_nif.test_a() will call the placeholder instead of nif functions.
One way I can think of to solve the glitch is to add an _on_reprise_reload() function to test_nif:
def _on_reprise_reload() do
init()
end
And have reprise call the function after reloading the module
But there might be better ways.
Hi!
I never worked with NIFs. So what I say is a good practice which comes to mind when handling corner cases like this one - assuming that there might be more similar corner cases around :)
More elegant solution would be to call some configured function on a reloaded NIF module (if it's exported). Name of such function - like _on_reprise_reload
would go to your app config.exs
.
The question is: how to detect that a module contains NIFs?
Are you able to come up with a prototype PR?
cheers,
W.
Hi, Thanks for your advice!
I've come up with a simple fix to support a "general reload hook", not made for NIFs. In that case people can do all the things in the hook function, I think it's more general and useful than targeting NIF use cases specifically.
Didn't come up with a unit test yet but I already use it in my project and it worked great.
For my previous example, now it can be fixed like this:
defmodule test_nif do
require Logger
@on_load :init
def init() do
:erlang.load_nif("./priv/test_nif", 0)
:ok
end
def _reprise_on_reload() do
init()
end
def test_a() do
Logger.error "NIF library not loaded"
end
end
Hi, turns out there is a built-in reload feature for erlang nifs.
Just implement the 'load', 'upgrade', 'unload' callbacks for ERL_NIF_INIT macro and erlang handles nif reload for you when the module is reloaded, there is no need to call load_nif() again in _reprise_on_reload()
That said, maybe there are other aspects people can use a _reprise_on_reload() callback on reprise. I kept reload mechanism in my project and worked fine.
Hello!
I hope you don't mind this project evolving rather slowly.. :)
I think you're right that _reprise_on_reload()
can be useful. I see no reason in blocking this going to master which then gets "hexified" with all good implications of it.
Still I'm tempted to have a simple regression test for this, as I said previously in the pull request comment. Do you have an idea or a skeleton of how such test for a callback might work?
cheers,
W.
Hi,
Sorry for the late reply! I was busy with the day jobs.
I've written a simple test to test calling hooks, not a very comprehensive one but I think it's better than nothing.
cheers, Lei