Recursive Flows
Hi I'm trying to right a flow that runs itself given a condition.
This leads to somekind of infinity recursion. I also tried copying the flow to a different file but that lead to an engine deadlock, it seems like the "sub" flow is run in the same context as the "parent" flow leading and as they both have the same step names it does not know which of the steps belong to which flow.
defmodule Demo.Inventory.Flows.Search do
@moduledoc """
"""
use Ash.Flow, otp_app: :demo
flow do
api(Demo.Support)
argument(:size, :integer)
argument(:token, :string)
argument(:query, :struct)
argument(:check_in, :date) do
allow_nil? false
end
argument(:check_out, :date) do
allow_nil? false
end
argument(:occupancies, {:array, Demo.Inventory.Resources.Types.Occupancy}) do
allow_nil? false
end
returns(:merge_results)
end
steps do
custom :get_hotels, Demo.Inventory.Flows.Steps.GetHotels do
input(%{
check_in: arg(:check_in),
check_out: arg(:check_out),
occupancies: arg(:occupancies),
page: [limit: arg(:size), after: arg(:token)]
})
end
custom :filter_unavailable_hotels, Demo.Inventory.Flows.Steps.FilterUnavailableHotels do
input %{
hotels: result(:get_hotels)
}
end
custom :need_more_hotels?, Demo.Inventory.Flows.Steps.NeedMoreHotels do
input %{
keyset: result(:get_hotels),
available_hotels: result(:filter_unavailable_hotels),
needed_size: arg(:size)
}
end
branch :maybe_get_more_hotels, result(:need_more_hotels?) do
output :get_next_token
custom :get_next_token, fn %{hotels: hotels}, _ ->
{:ok, get_in(Map.from_struct(List.last(hotels)), [:__metadata__, :keyset])}
end do
input %{
hotels: result(:filter_unavailable_hotels)
}
end
custom :get_number_of_missing_hotels, fn %{hotels: hotels, size: size}, _ ->
{:ok, size - length(hotels)}
end do
input %{
hotels: result(:filter_unavailable_hotels),
size: arg(:size)
}
end
run_flow :get_more_hotels, __MODULE__ do
input %{
check_in: arg(:check_in),
check_out: arg(:check_out),
occupancies: arg(:occupancies),
size: result(:get_number_of_missing_hotels),
token: result(:get_next_token)
}
end
end
custom :merge_results, Demo.Inventory.Flows.Steps.MergeResults do
input %{
hotels: result(:get_hotels),
more_hotels: result(:maybe_get_more_hotels)
}
end
end
enddefmodule Demo.Inventory.Flows.Search do
@moduledoc """
"""
use Ash.Flow, otp_app: :demo
flow do
api(Demo.Support)
argument(:size, :integer)
argument(:token, :string)
argument(:query, :struct)
argument(:check_in, :date) do
allow_nil? false
end
argument(:check_out, :date) do
allow_nil? false
end
argument(:occupancies, {:array, Demo.Inventory.Resources.Types.Occupancy}) do
allow_nil? false
end
returns(:merge_results)
end
steps do
custom :get_hotels, Demo.Inventory.Flows.Steps.GetHotels do
input(%{
check_in: arg(:check_in),
check_out: arg(:check_out),
occupancies: arg(:occupancies),
page: [limit: arg(:size), after: arg(:token)]
})
end
custom :filter_unavailable_hotels, Demo.Inventory.Flows.Steps.FilterUnavailableHotels do
input %{
hotels: result(:get_hotels)
}
end
custom :need_more_hotels?, Demo.Inventory.Flows.Steps.NeedMoreHotels do
input %{
keyset: result(:get_hotels),
available_hotels: result(:filter_unavailable_hotels),
needed_size: arg(:size)
}
end
branch :maybe_get_more_hotels, result(:need_more_hotels?) do
output :get_next_token
custom :get_next_token, fn %{hotels: hotels}, _ ->
{:ok, get_in(Map.from_struct(List.last(hotels)), [:__metadata__, :keyset])}
end do
input %{
hotels: result(:filter_unavailable_hotels)
}
end
custom :get_number_of_missing_hotels, fn %{hotels: hotels, size: size}, _ ->
{:ok, size - length(hotels)}
end do
input %{
hotels: result(:filter_unavailable_hotels),
size: arg(:size)
}
end
run_flow :get_more_hotels, __MODULE__ do
input %{
check_in: arg(:check_in),
check_out: arg(:check_out),
occupancies: arg(:occupancies),
size: result(:get_number_of_missing_hotels),
token: result(:get_next_token)
}
end
end
custom :merge_results, Demo.Inventory.Flows.Steps.MergeResults do
input %{
hotels: result(:get_hotels),
more_hotels: result(:maybe_get_more_hotels)
}
end
end
endThis leads to somekind of infinity recursion. I also tried copying the flow to a different file but that lead to an engine deadlock, it seems like the "sub" flow is run in the same context as the "parent" flow leading and as they both have the same step names it does not know which of the steps belong to which flow.
