Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check availability of optional dependencies in Elixir

Tags:

elixir

I made a hex package (Channels) that optionally depends on another one (AMQP). My implementation is based on Ecto's optional dependency on Mariaex.

In Channels' mix.exs:

defp deps do
  [{:amqp, "0.1.4", optional: true}]
end

In the Channels' file that depends on AMQP:

if Code.ensure_loaded?(AMQP) do

  defmodule Channels.Adapter.AMQP do
    ...
  end

end

The application is starting properly on dev and test are also passing (including those that depend on AMQP mix test --include amqp_server).

But when I try to use the package from another project some problems arise:

In my project I'm adding the following to my mix.exs file:

def application do
  [applications: [:amqp, :channels, ...],
   ...]
end

defp deps do
  [{:amqp, "0.1.4"},
   {:channels, "~> 0.1.1"},
   ...]
end

When I try to start the application or run the tests I'm getting the following error:

=INFO REPORT==== 27-May-2016::10:28:35 ===
application: logger
exited: stopped
type: temporary
** (Mix) Could not start application channels: Channels.start(:normal, []) returned an error: shutdown: failed to start child: Channels.Monitor.Supervisor
  ** (EXIT) shutdown: failed to start child: :main
    ** (EXIT) an exception was raised:
      ** (UndefinedFunctionError) undefined function Channels.Adapter .AMQP.connect/1 (module Channels.Adapter.AMQP is not available)
          Channels.Adapter.AMQP.connect([])
          (channels) lib/channels/monitor.ex:42: Channels.Monitor.init/1
          (stdlib) gen_server.erl:328: :gen_server.init_it/6
          (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3

I'm adding AMQP as a dependency but it seems that Code.ensure_loaded?(AMQP) is returning false and therefore Channels.Adapter.AMQP is not being defined.

I've noticed that in the compilation process Channels is being compiled before AMQP:

...
==> channels
...
Generated channels app
==> rabbit_common (compile)
==> amqp_client (compile)
==> amqp
...
Generated amqp app
...

May this be the cause of my problem? If so, is there a way to decide the compilation order of my dependencies?

like image 473
jcabot Avatar asked May 27 '16 08:05

jcabot


1 Answers

As Dogbert pointed out it was my mistake because I forgot to push the latest version of the package to hex. I've done it and worked properly.

Specifying the dependency as optional does change the compilation order.

like image 57
jcabot Avatar answered Sep 19 '22 06:09

jcabot