fix: fix resolvable requests logic

This commit is contained in:
Zach Daniel 2020-04-30 13:36:16 -04:00
parent 73c51943cf
commit b7ca80d2eb
No known key found for this signature in database
GPG key ID: C377365383138D4B

View file

@ -111,24 +111,19 @@ defmodule Ash.Engine do
defp next(%{state: :resolve_some} = engine) do defp next(%{state: :resolve_some} = engine) do
# TODO: We should probably find requests that can be fetched in parallel # TODO: We should probably find requests that can be fetched in parallel
# and fetch them asynchronously (if their data layer allows it) # and fetch them asynchronously (if their data layer allows it)
engine
case resolvable_requests(engine) do case resolvable_requests(engine) do
[request | _rest] -> [request | _rest] ->
# TODO: run any preparations on the data here, and then store what preparations have been run on what data so # TODO: run any preparations on the data here, and then store what preparations have been run on what data so
# we don't run them again. # we don't run them again.
engine engine
|> Map.put(:no_resolvable_requests?, false)
|> resolve_data(request) |> resolve_data(request)
|> transition(:check) |> transition(:check)
[] -> [] ->
if engine.no_resolvable_requests? do transition(engine, :complete, %{message: "No requests to resolve"})
transition(engine, :complete, %{message: "No requests to resolve"})
else
engine
|> Map.put(:no_resolvable_requests?, true)
|> transition(:check)
end
end end
end end
@ -217,20 +212,19 @@ defmodule Ash.Engine do
# Also, sort them by whether or not they *should* be fetched # Also, sort them by whether or not they *should* be fetched
engine.requests engine.requests
|> Enum.reject(& &1.error?) |> Enum.reject(& &1.error?)
|> Enum.reject(& &1.strict_access?)
|> Enum.filter(&Request.all_dependencies_met?(&1, engine.data, true)) |> Enum.filter(&Request.all_dependencies_met?(&1, engine.data, true))
|> Enum.filter(&allowed_access?(engine, &1)) |> Enum.filter(&allowed_access?(engine, &1))
end end
defp allowed_access?(engine, request) do defp allowed_access?(engine, request) do
if request.strict_access? do if request.strict_access? do
passes_strict_check_in_isolation?(request, engine)
else
false false
else
could_pass_strict_check_in_isolation?(request, engine)
end end
end end
defp passes_strict_check_in_isolation?(request, engine) do defp could_pass_strict_check_in_isolation?(request, engine) do
requests_with_data_filter = requests_with_data_filter =
Enum.flat_map([request], fn request -> Enum.flat_map([request], fn request ->
if Request.data_resolved?(request) && request.data not in [nil, []] do if Request.data_resolved?(request) && request.data not in [nil, []] do
@ -245,8 +239,8 @@ defmodule Ash.Engine do
end) end)
case SatSolver.solve(requests_with_data_filter, engine.facts) do case SatSolver.solve(requests_with_data_filter, engine.facts) do
{:ok, scenarios} -> {:ok, _scenarios} ->
find_real_scenario(scenarios, engine.facts) != nil true
{:error, :unsatisfiable} -> {:error, :unsatisfiable} ->
false false