繁体   English   中英

如何从破坏 Elixir Phoenix 的地方恢复 Elixir 任务

[英]how to resume an elixir task from where it broke Elixir Phoenix

我们正在使用SeaweedFS ,它是一个文件系统来存储(图像)文件,它作为一个rest api。 我们正在尝试将数据从一台服务器移动到另一台服务器。

有几个级别的数据目录。 存储图像的基本模式是

http://{server}:8888/ballymore-project-wave/snapshots/recordings/{year}/{month}/{day}/{hour}/00_00_000.jpg

目录的每一层都有自己的返回,以JSON形式,如

{
    "Path": "/ballymore-project-wave/snapshots/recordings/",
    "Files": null,
    "Directories": [
        {
            "Name": "2016",
            "Id": 91874
        },
        {
            "Name": "2017",
            "Id": 1538395
        }
    ],
    "Limit": 100,
    "LastFileName": "",
    "ShouldDisplayLoadMore": false
}

上面的响应是针对当您试图获得年份的录音时,同样的响应是针对月、日和小时的。 当您获取单个小时时会发生轻微变化

{
    "Path": "/ballymore-project-wave/snapshots/recordings/2016/11/02/01/",
    "Files": [
        {
            "name": "00_00_000.jpg",
            "fid": "29515,744a5a496b97ff98"
        },
        {
            "name": "00_01_000.jpg",
            "fid": "29514,744a5aa52ea3cf3d"
        }
    ],
    "Directories": null,
    "Limit": 100,
    "LastFileName": "02_15_000.jpg",
    "ShouldDisplayLoadMore": true
}

现在我们需要将所有这些数据从一台服务器移动到另一台服务器。 我为它写了一个脚本

  defp move_snapshots(exids) do
    exids
    |> Enum.each(fn (exid) ->
      request_from_seaweedfs("#{@seaweedfs}/#{exid}/snapshots/recordings/", "Directories", "Name")
      |> Enum.sort |> Enum.each(fn (year) ->
        request_from_seaweedfs("#{@seaweedfs}/#{exid}/snapshots/recordings/#{year}/", "Directories", "Name")
        |> Enum.sort |> Enum.each(fn (month) ->
          request_from_seaweedfs("#{@seaweedfs}/#{exid}/snapshots/recordings/#{year}/#{month}/", "Directories", "Name")
          |> Enum.sort |> Enum.each(fn (day) ->
            request_from_seaweedfs("#{@seaweedfs}/#{exid}/snapshots/recordings/#{year}/#{month}/#{day}/", "Directories", "Name")
            |> Enum.sort |> Enum.each(fn (hour) ->
              request_from_seaweedfs("#{@seaweedfs}/#{exid}/snapshots/recordings/#{year}/#{month}/#{day}/#{hour}/?limit=3600", "Files", "name")
              |> Enum.sort |> Enum.each(fn (file) ->
                exist_on_seaweed?("/#{exid}/snapshots/recordings/#{year}/#{month}/#{day}/#{hour}/#{file}")
                |> copy_or_skip("/#{exid}/snapshots/recordings/#{year}/#{month}/#{day}/#{hour}/#{file}")
              end)
            end)
          end)
        end)
      end)
    end)
  end

这是主要功能, exids表示所有相机字符串类型标识,例如,它是ballymore-project-wave

在上面的脚本中,我正在检查每个级别,如果有什么东西存在,我会更深入,直到最后,我检查它是否是一个有效的图像

  defp exist_on_seaweed?(url) do
    hackney = [pool: :seaweedfs_download_pool, recv_timeout: 30_000_000]
    case HTTPoison.get("#{@seaweedfs}#{url}", ["Accept": "application/json"], hackney: hackney) do
      {:ok, %HTTPoison.Response{status_code: 200, body: data}} -> {:ok, data}
      _error ->
        :not_found
    end
  end

  defp copy_or_skip(:not_found, _path), do: :noop
  defp copy_or_skip({:ok, data}, path) do
    hackney = [pool: :seaweedfs_upload_pool]
    case HTTPoison.post("#{@seaweedfs_new}#{path}", {:multipart, [{path, data, []}]}, [], hackney: hackney) do
      {:ok, _response} -> Logger.info "[seaweedfs_save]"
      {:error, error} -> Logger.info "[seaweedfs_save] [#{inspect error}]"
    end
  end

这一切正常但是当它由于某种原因崩溃或损坏时我有一个小问题,我需要为此提供指导/想法。 如您所见,如果相机exids为 200 并且它在 100 或更少时exids ,它将恢复,但从一开始,我们无法在移动后删除旧服务器上的内容,直到完全移动,任何帮助将不胜感激。 此外,如果您认为代码中可能会有一些改进,这会有所帮助。

在您发布实际的堆栈跟踪或遇到的错误的详细信息之前,不可能确切地找出问题所在。 但是对于初学者来说,这里有一些可能会有所帮助的建议:

  • 你应该把你的move_snapshots方法分解成更容易理解的方法,也许使用像Enum.reduce/3的递归方法,并调用你的copy_or_skip方法作为基本情况。

  • 尝试将您的copy_or_skip方法实现包装在try/rescue ,挽救任何异常,记录它们并继续下一个。

     defp copy_or_skip(args, path) do # Your Implementation rescue error -> Logger.error("Exception caught on #{inspect(path)}\\n#{inspect(error)}") end
  • 您也可以浏览所有文件的列表,并将有效路径添加到诸如QueToniq类的作业处理库中的某个“Worker”。 该库将执行所有移动操作并将它们标记为成功或失败。 然后您可以返回查看哪些操作失败并找出导致它们的原因,或者自动重新启动失败的操作。


关于提高代码可靠性和性能的更多提示:

  • 使用Stream或更好的Flow来划分任务并并行处理它们。
  • 在单独的Task进程中执行实际的移动操作,最好由Supervisor管理。 (可选地使用池)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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