【问题标题】:using melpon/memoize in elixir mix task在长生不老药混合任务中使用 melpon/memoize
【发布时间】:2022-01-22 17:14:47
【问题描述】:

我在我的 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

我知道这与混合任务中未完成的一些初始化有关,但我无法弄清楚它是什么。

【问题讨论】:

    标签: elixir memoization elixir-mix


    【解决方案1】:

    我们需要在混合任务中明确启动应用程序。

    代码已加载,但运行混合命令时应用程序未启动。

    Mix 不会自动启动我们的应用程序或其任何依赖项... 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] 已经为你启动了你的申请。

    【讨论】:

      猜你喜欢
      • 2016-07-24
      • 2016-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      • 2017-10-21
      • 2015-02-03
      • 1970-01-01
      相关资源
      最近更新 更多