在 elixir 混合任务中使用 melpon/memoize
using melpon/memoize in elixir mix task
我在我的 phoenix 应用程序中使用 melpon/memoize 作为缓存。它在运行时运行良好。
但是,我的应用程序中有一些混合任务,我很少执行这些任务。
现在这些任务最终会调用一个 memoized 函数,例如:
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
它崩溃了:
/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
如果我尝试在 IEx 中执行代码,它会按预期工作:
/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
我知道它与混合任务中未完成的一些初始化有关,但我无法弄清楚它是什么。
我们需要在混合任务中显式启动应用程序。
代码已加载,但应用程序在 运行 混合命令时未启动。
Mix does not automatically start our application or any of its dependencies ...
Ref
所以我们需要明确地启动它:
def run(_) do
{:ok, _} = Application.ensure_all_started(:memoize)
MemoizedModule.get_value()
end
如果您需要在应用程序中执行其他初始化任务,您可能需要将 :memoize
更改为 :my_otp_app
。
为什么它在iex -S mix
里面起作用?
那是因为 iex -S mix [run]
已经为您启动了申请。
我在我的 phoenix 应用程序中使用 melpon/memoize 作为缓存。它在运行时运行良好。
但是,我的应用程序中有一些混合任务,我很少执行这些任务。 现在这些任务最终会调用一个 memoized 函数,例如:
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
它崩溃了:
/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
如果我尝试在 IEx 中执行代码,它会按预期工作:
/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
我知道它与混合任务中未完成的一些初始化有关,但我无法弄清楚它是什么。
我们需要在混合任务中显式启动应用程序。
代码已加载,但应用程序在 运行 混合命令时未启动。
Mix does not automatically start our application or any of its dependencies ... Ref
所以我们需要明确地启动它:
def run(_) do
{:ok, _} = Application.ensure_all_started(:memoize)
MemoizedModule.get_value()
end
如果您需要在应用程序中执行其他初始化任务,您可能需要将 :memoize
更改为 :my_otp_app
。
为什么它在iex -S mix
里面起作用?
那是因为 iex -S mix [run]
已经为您启动了申请。