如何恢复从那里爆发药剂凤凰仙丹任务(how to resume an elixir task fro

2019-09-28 09:57发布

我们使用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或者也许更少,它会恢复,但是从一开始,我们就不能移动,直到充分运动后删除旧服务器上的东西,任何帮助将不胜感激。 此外,如果你觉得有可能是在代码,将是有益的一些改进。

Answer 1:

在您发布的实际堆栈跟踪或您所遇到的错误的详细信息,这是不可能搞清楚究竟什么是错的。 但对于初学者来说,这里有一些建议,可能会有所帮助:

  • 你应该打破你的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 。 该库将执行所有的移动操作和标记他们成功或失败。 然后,您可以回去看哪些操作失败,找出原因引起的,或自动重启失败的。


在提高代码的可靠性和性能的一些更多提示:

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


文章来源: how to resume an elixir task from where it broke Elixir Phoenix
标签: rest elixir