elixir - 如何监督长生不老药中的方法
问题描述
我正在尝试监督长生不老药中的一种方法。我有这个模块EvercamMedia.SnapshotExtractor.CloudExtractor
,GenStage
我正在向它传递一些参数,例如。
def handle_cast({:snapshot_extractor, config}, state) do
_start_extractor(config)
{:noreply, [], state}
end
这个_strat_extractor
方法本身很长,方法很多。但在所有这些方法中,我使用一种方法不是直接发送 HTTPoison 请求,而是通过一个dropbox
api 包装器发送 HTTPoison 请求。
def upload(200, response, starting, camera_exid, id, requestor) do
construction =
case requestor do
"marklensmen@gmail.com" ->
"Construction"
_ ->
"Construction2"
end
image_save_path = "#{@root_dir}/#{camera_exid}/extract/#{id}/#{starting}.jpg"
path = "#{@root_dir}/#{camera_exid}/extract/#{id}/"
File.write(image_save_path, response, [:binary]) |> File.close
client = ElixirDropbox.Client.new(System.get_env["DROP_BOX_TOKEN"])
{:ok, file_size} = get_file_size(image_save_path)
try do
%{"session_id" => session_id} = ElixirDropbox.Files.UploadSession.start(client, true, image_save_path)
write_sessional_values(session_id, file_size, "/#{construction}/#{camera_exid}/#{id}/#{starting}.jpg", path)
check_1000_chunk(path) |> length() |> commit_if_1000(client, path)
rescue
_ ->
:timer.sleep(:timer.seconds(3))
upload(200, response, starting, camera_exid, id, requestor)
end
end
def upload(_, _response, _starting, _camera_exid, _id, _requestor), do: :noop
现在,我的问题是如何监督这种方法?
有时这部分会失败ElixirDropbox.Files.UploadSession.start(client, true, image_save_path)
。我还为它添加了一个主管,但它不会在崩溃时重新启动它,而是在应用程序停止时恢复它。
我如何利用Supervisor
策略并在崩溃时恢复此方法。
def upload(200, response, starting, camera_exid, id, requestor) do
不管怎样,我的主管看起来像这样。
defmodule EvercamMedia.SnapshotExtractor.ExtractorSupervisor do
use Supervisor
require Logger
alias EvercamMedia.SnapshotExtractor.Extractor
alias EvercamMedia.SnapshotExtractor.CloudExtractor
import Commons
@root_dir Application.get_env(:evercam_media, :storage_dir)
def start_link() do
Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)
end
def init(:ok) do
Task.start_link(&initiate_workers/0)
extractor_children = [worker(Extractor, [], restart: :permanent)]
supervise(extractor_children, strategy: :simple_one_for_one, max_restarts: 1_000_000)
cloud_extractor_childern = [worker(CloudExtractor, [], restart: :permanent)]
supervise(cloud_extractor_childern, strategy: :simple_one_for_one, max_restarts: 1_000_000)
end
PS:我尝试将两个工人都添加到子列表中,并立即将其传递给监督,但效果不佳。
解决方案
有很多问题ExtractorSupervisor.init/1
。
def init(:ok) do
Task.start_link(&initiate_workers/0)
children1 = ...
supervise(children1, ...)
children2 = ...
supervise(children2, ...)
end
首先,您使用不推荐使用的遗留方式来初始化主管和遗留策略中的子项。
这种方法的主要问题是children1
永远不会受到监督。Supervisor.Spec.supervise/2
不是凭空监督的魔杖制作过程。它只是从回调中返回规范,调用者init/1
可以理解,最终将子项嵌入到监督树中。这意味着,第一次调用是 noop。监督所有孩子应该做的事supervise/2
def init(:ok) do
children1 = ...
children2 = ...
supervise(children1 ++ children2, ...)
end
可能会有更多的故障,但除非这两个被修复,否则很难推理。
旁注:虽然它在某种程度上是合法的,但我很确定可能会有更好的地方打电话Task.start_link/1
而不是init/1
回调主管。
推荐阅读
- excel - 有没有其他方法可以过滤掉excel中的空白?
- c# - Excel 互操作:获取用户设置的过滤器,并在经过一些处理后将其设置回来
- python - 如何使用 Python 将 .png 标签转换为 EPL?
- python - 列表索引在 Jinja 中的工作原理
- python-3.x - 尝试在 python 中连接 mongodb 数据库时出现配置错误
- laravel - 如何在 Laravel Livewire 的引导模式中显示帖子记录?
- docker - Cairo docker build 由于缺少 pixman 依赖项而失败
- api - 将数据从 RDBMS 迁移到 Arango DB:批量上传
- java - PostgreSQL 的批量更新插入最佳实践
- c - 我无法为单链表运行快速排序。m 无法将递归调用的条件放入快速排序函数中