On behalf of the RabbitMQ team, I’m proud to announce the Horus library!
Horus is a library that extracts an anonymous function’s code and creates a standalone version of it in a new module at runtime. The goal is to get a storable and transferable function which does not depend on the availability of the module that defined it.
This library is born from the
khepri_fun module which was moved out of the Khepri library to make an independent library, easier to maintain and test. We need this in Khepri to extract transactions and store/transfer standalone functions as part of Ra/Raft cluster work.
%% Here is the function we want to transfer or store. Fun = fun() -> do_something_fancy() end, %% Extract the function and create the standalone module. StandaloneFun = horus:to_standalone_fun(Fun), %% Later, execute the extracted standalone function. horus:exec(StandaloneFun, ).
How does it work?
To achieve the goal, Horus extracts the assembly code of the anonymous function and creates a standalone Erlang module based on it. This module can be stored, transfered to another Erlang node and executed anywhere without the presence of the initial anonymous function’s module.
One caveat is that the created module will only work with the same version of Erlang/OTP as the one used to compile the original module, or a later version.
Documentation is already available. It describes the concepts and the API in greater detail, though it is far from complete.
The implementation is alpha at this stage. The internal design should not change drastically now but the API and ABI might.
Release 0.1.0 is now available from Hex.pm. This should make it easier for anyone to test it.
I know this is a very narrow and specific use case, but I would still be very happy to get some feedback on this What do you think of it?