我有Enum.each
这种经历很多的人。
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}")
save_current_directory(exid, year, month, day, hour, file)
end)
end)
end)
end)
end)
next_exid_index = Enum.find_index(exids, fn(x) -> x == exid end)
File.write!("#{@root_dir}/moving_old_data", "#{Enum.at(exids, next_exid_index + 1)}")
end)
这是一个很长的运行循环,但是它没有处理任何停止和恢复逻辑。
我试图将当前数据保存到文件中,并在重新启动时从那里恢复为
exids
|> clean_already_completed(0)
|> Enum.each(fn (exid) ->
request_from_seaweedfs("#{@seaweedfs}/#{exid}/snapshots/recordings/", "Directories", "Name")
|> Enum.sort |> clean_already_completed(1) |> Enum.each(fn (year) ->
request_from_seaweedfs("#{@seaweedfs}/#{exid}/snapshots/recordings/#{year}/", "Directories", "Name")
|> Enum.sort |> clean_already_completed(2) |> Enum.each(fn (month) ->
request_from_seaweedfs("#{@seaweedfs}/#{exid}/snapshots/recordings/#{year}/#{month}/", "Directories", "Name")
|> Enum.sort |> clean_already_completed(3) |> Enum.each(fn (day) ->
request_from_seaweedfs("#{@seaweedfs}/#{exid}/snapshots/recordings/#{year}/#{month}/#{day}/", "Directories", "Name")
|> Enum.sort |> clean_already_completed(4) |> Enum.each(fn (hour) ->
request_from_seaweedfs("#{@seaweedfs}/#{exid}/snapshots/recordings/#{year}/#{month}/#{day}/#{hour}/?limit=3600", "Files", "name")
|> Enum.sort |> clean_already_completed(5) |> 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}")
save_current_directory(exid, year, month, day, hour, file)
end)
end)
end)
end)
end)
next_exid_index = Enum.find_index(exids, fn(x) -> x == exid end)
File.write!("#{@root_dir}/moving_old_data", "#{Enum.at(exids, next_exid_index + 1)}")
end)
clean_already_completed
就是这样。
defp clean_already_completed(list, index), do: get_recent_value(index) |> dont_reduce?(list)
defp dont_reduce?(nil, list), do: list
defp dont_reduce?(last, list), do: Enum.drop_while(list, fn el -> el != last end)
defp get_recent_value(index), do: read_recent_file() |> Enum.at(index)
defp read_recent_file, do: File.read("#{@root_dir}/moving_old_data") |> file_is_present()
defp file_is_present({:error, :enoent}), do: []
defp file_is_present({:ok, ""}), do: []
defp file_is_present({:ok, data}), do: data |> String.split(" ")
但是当我停止并重新启动它时,即使在运行时,它也无法按预期工作。它跳过了下一年,几天和几个月。
在保存的文件中,我有这种数据
1-granby-row 2017 03 18 05 43_49_000.jpg
例如,关于失败,我只想从这些值恢复每个循环。上一行解释为exid year month day hour file
。
有没有可能以更好的方式做到这一点?如果整个循环再次开始,则从文件信息中获取信息,是否可以从那里恢复?
答案 0 :(得分:0)
更好的方法是将流程分为较小的步骤:
each
语句以构建所有需要移动的文件的清单。就像我之前提到的in my other answer一样,这一切都可以使用作业处理库来完成;您需要做的就是解析所有路径并将它们添加为需要处理的作业。如果出现错误,崩溃或其他故障,他们可以重新启动失败的“作业”,并恢复尚未完成的作业。
如果您决定不使用作业处理库来执行代码,则代码将是这样:
# Steps 1 and 2
def build_manifest do
all_files =
exids
|> Enum.map(fn exid -> "#{@seaweedfs}/#{exid}/snapshots/recordings/" end)
|> Enum.flat_map(&get_dir_paths/1) # Get Year directories
|> Enum.flat_map(&get_dir_paths/1) # Get Month directories
|> Enum.flat_map(&get_dir_paths/1) # Get Day directories
|> Enum.flat_map(&get_dir_paths/1) # Get Hour directories
|> Enum.flat_map(&get_file_paths/1) # Get files in the hour directories
# Now store these files to a datastore
end
# Steps 3 & 4
def copy_all_files do
case get_next_incomplete_file() do
nil ->
IO.puts("All files have been copied")
path ->
if exist_on_seaweed?(path)
copy_file(path)
end
copy_all_files()
end
end
defp get_dir_paths(path) do
path
|> request_from_seaweedfs("Directories", "Name")
|> Enum.sort
|> Enum.map(&Path.join(path, &1))
end
defp get_file_paths(path) do
(path <> "?limit=3600")
|> request_from_seaweedfs("Files", "Name")
|> Enum.sort
|> Enum.map(&Path.join(path, &1))
end
defp get_next_incomplete_file do
# query your datastore to get the next file that is
# marked "not done"
end
defp copy_file(path) do
# copy the file
# and then mark it "done" in the datastore
end