Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom mix task in Phoenix app

When I run custom Mix task in my Phoenix app (I think it's not even related to Phoenix but still) that uses some external library (e.g https://github.com/knrz/geocoder) I get

** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
    :erlang.send(:geocoder_workers, {:"$gen_cast", {:cancel_waiting, #Reference<0.0.1.13074>}}, [:noconnect])

until I add

Application.ensure_all_started(:geocoder)

to the Mix task. So my question is why all my dependencies are not started automatically? Is it me who's doing something wrong?

like image 624
Vasiliy Ermolovich Avatar asked Dec 10 '22 11:12

Vasiliy Ermolovich


2 Answers

You're right, your application's dependencies are not started by default in a Mix task. They need to be started manually. The simplest way to start all of your application's dependencies is to call Mix.Task.run("app.start") (or Application.ensure_all_started(:my_app) if Mix is not available). With this, all applications listed in your mix.exs file will be started if they're not already running.

This is documented near the end of the Mix Tasks page on the Phoenix Framework site:

If you want to make your new mix task to use your application's infrastructure, you need to make sure the application is started when mix task is being executed. This is particularly useful if you need to access your database from within the mix task. Thankfully, mix makes it really easy for us:

def run(_args) do
  Mix.Task.run "app.start"
  Mix.shell.info "Now I have access to Repo and other goodies!"
  ...
end
like image 57
Dogbert Avatar answered Dec 18 '22 09:12

Dogbert


In Elixir 1.11 you can use the @requirements module attribute as described in the docs for Mix.Task:

@requirements ["app.start"]

This is equivalent to calling Mix.Task.run "app.start" in your run function.

like image 21
balexand Avatar answered Dec 18 '22 11:12

balexand