Поток эликсира: множество аргументов

Я пытаюсь написать поток, который выглядит так:

def perform(id) do
  id
  |> Flow.from_stage(max_demand: 10)
  |> Flow.map(&download(&1))
  |> Flow.map(&process(&1))
  |> Flow.each(&cleanup(&1, &2))
  |> Flow.each(&respond(&1, &2))
  |> Flow.run
end

Другие функции в модуле выглядят так:

def download(id) do
  Service.get_images(id)
  id
end

def process(id) do
  %Result{out: sys_out, status: _} = Porcelain.exec("osascript",
    ["#{File.cwd!}/lib/script/test", "#{id}", "#{Application.get_env(:app, :server_env)}"]
  )
  {id, sys_out}
end

def cleanup(id, files) do
  for file <- String.split(files, " ") do
    System.cmd("exiftool", ["#{File.cwd!}/#{file}"])
  end
  {id, files}
end

def respond(id, files) do
  files = String.split(files, " ")
  System.cmd("curl", [" -d 'dowhatever=#{files[0]}&else=#{files[1]}' -k #{Application.get_env(:app, :api)}what/#{id}/notify"])
  :ok
end

Но я продолжаю получать эту ошибку:

** (FunctionClauseError) no function clause matching in Flow.each/2
...
(app) lib/app/processor.ex:18: App.Processor.perform/1

Линия 18 является &cleanup/2 линия. Что я здесь не так делаю? Такое ощущение, что я как-то не возвращаю правильные значения...

1 ответ

Решение

process/1 возвращает кортеж {id, sys_out}, в то время как cleanup/2 объявляется имеющим arity 2.

Итерирование списка кортежей подразумевает, что итератор должен быть arity 1. Вы должны разложить свой кортеж внутри cleanup/1:

- def cleanup(id, files) do
+ def cleanup({id, files}) do

и назовите это как:

Flow.each(&cleanup/1)

То же относится и к последующим respond,

Другие вопросы по тегам