Однократный процесс эликсира - PullRequest
1 голос
/ 07 июня 2019

Я пытаюсь создать «Подогрев кеша» для запуска ОДИН РАЗ при запуске приложения, вызывая модуль genServer «Кэш»

Я создал некоторый код: GenServer «Cache Warmer», который используется для обработки одного асинхронного вызова при запуске приложения, настроен с помощью [restart:: временный]. Основная идея - возврат {: stop,: normal, state} после приведения, чтобы остановить процесс

defmodule TlgmBot.Application do
 ...
     def start(_type, _args) do
     ...
       children = [
       ... some stuff ...
        %{
          id: Services.Cache.CacheWarmer,
          start: {Services.Cache.CacheWarmer, :start_link, [restart: :temporary]},
          type: :supervisor
      }

        %{
          id: Services.Cache.Cache,
          start: {Services.Cache.Cache, :start_link, []},
          type: :supervisor
      },
    end
end
defmodule Services.Cache.CacheWarmer do
 use GenServer

  def start_link(_state \\ []) do
    GenServer.start_link(__MODULE__, [:ok], name: __MODULE__)
  end

  def handle_cast({:warm_up_cache}, state) do
    debug "loading users..."
    load_users()
    debug "done."
    load_mfc()

    {:stop, :normal, state}
  end

  defp load_users() do
    result = RedmineApi.request_rm_users()

    case result do
    {:ok, users} -> Cache.save_users(users)
                    {:ok}
    _            -> {:error}
    end
  end
end

И процесс «Подогрев кеша» продолжает работать снова и снова

Пожалуйста, укажите мне, как правильно выполнить эту задачу, или помогите мне выяснить, что я здесь делаю неправильно.

Может быть, я должен добавить пару строк в application.start (), чтобы вызвать модуль кеша здесь и забыть об этом?

Ответы [ 2 ]

3 голосов
/ 08 июня 2019

Поскольку ваш подогреватель кэша не использует свое состояние или не должен существовать после выполнения своего долга, я бы рекомендовал вам вместо этого вызывать функцию либо при запуске приложения, либо внутри handle_continue в вашем кэше.Это произойдет после init, чтобы не блокировать запуск других потомков.

См .: GenServer.handle_continue/2.

2 голосов
/ 08 июня 2019

Помимо handle_continue/2, опубликованного @ aleksei-matiushkin, в вашем дереве наблюдения также может быть задание после кэша:

MyApp.Cache,
{Task, &MyApp.Cache.warmup/0}

По умолчанию задание является временным, что означает, что он не будет перезапущен, если он падает.Обратите внимание, что если в процессе кеширования происходит сбой, handle_continue / 2 будет запущен снова после перезапуска процесса.Задание не будет запускаться снова, если стратегия наблюдения - :one_for_one, но она будет выполняться для :rest_for_one и :one_for_all.

В опубликованном вами коде есть две проблемы: запускается подогрев кеша до кэша, поэтому запрос приведения не найдет сервер кэша.Он также перечисляет дочерние элементы как type: :supervisor, что должно быть сделано только для супервизоров (здесь это не вызовет реальной ошибки, но может вызвать проблемы при завершении работы, обновлении горячего кода и т. Д.).

...