简体   繁体   中英

using melpon/memoize in elixir mix task

I am using melpon/memoize for cache in my phoenix aplication. It is working very well in runtime.

However, I have a few mix tasks in my application, which I execute sparingly. Now these tasks eventually call a memoized function, for example:

defmodule Mix.Tasks.MyTask do
  use Mix.Task
  alias MemoizedModule
  require Logger;
  use Memoize

  def run(_) do
    MemoizedModule.get_value()
  end
end

defmodule MemoizedModule do
  use Memoize
  defmemo get_value() do
    1
  end
end

and it crashes with:

/opt/app # mix my_task
** (ArgumentError) errors were found at the given arguments:

  * 1st argument: no persistent term stored with this key

    :persistent_term.get(:memoize_cache_strategy)
    (memoize 1.4.0) lib/memoize/config.ex:29: Memoize.Config.cache_strategy/0
    (memoize 1.4.0) lib/memoize/cache.ex:11: Memoize.Cache.tab/1
    (memoize 1.4.0) lib/memoize/cache.ex:103: Memoize.Cache.do_get_or_run/3
    (mix 1.12.3) lib/mix/task.ex:394: anonymous fn/3 in Mix.Task.run_task/3
    (mix 1.12.3) lib/mix/cli.ex:84: Mix.CLI.run_task/2
    (elixir 1.12.3) lib/code.ex:1261: Code.require_file/2

If I try to execute the code inside IEx, it works as expected:

/opt/app # iex -S mix
Interactive Elixir (1.12.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Mix.Tasks.MyTask.run()
1

I know it has something to do with some initialization that is not done in mix tasks, but I can´t figure out what it is.

We need to start applications explicitly in mix tasks.

Codes are loaded, but applications are not started when running mix commands.

Mix does not automatically start our application or any of its dependencies... Ref

So we need to start the it explicitly:

def run(_) do
  {:ok, _} = Application.ensure_all_started(:memoize)

  MemoizedModule.get_value()
end

You may need to change :memoize to :my_otp_app if you have other initialization tasks in the app.

Why does it work inside iex -S mix ?

That's because iex -S mix [run] has started your application for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM