Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

schema compilation goes into infinite recurion #1296

Open
bsanyi opened this issue Feb 14, 2024 · 1 comment
Open

schema compilation goes into infinite recurion #1296

bsanyi opened this issue Feb 14, 2024 · 1 comment

Comments

@bsanyi
Copy link

bsanyi commented Feb 14, 2024

The compilation of the following schema module runs into an infinite recursion:

defmodule SomeSchema do
  use Absinthe.Schema

  import_sdl """
    interface Animal { eats: [Food!]!   }
    interface Food   { eatenBy: Animal! }

    type Cat implements Animal { eats: [CatFood!]! }
    type Dog implements Animal { eats: [DogFood!]! }

    type CatFood implements Food { eatenBy: Cat! }
    type DogFood implements Food { eatenBy: Dog! }
  """
end

It's easy to reproduce: create a new project with mix new, and add absinthe ~> 1.7.6 as a dependency. Run mix deps.get and mix deps.compile. Add the above module to the project, and try to compile the app with mix compile. It will not terminate.

Actual behavior

The compilation takes a very long time and seems like it eats up all the available memory. The OS kills the compilation process after some time.

It I use the interface name instead of the type name at least on one side of the relation, the schema compiles.

Interestingly it works when I turn the eatenBy fields type to Animal in the CatFood and DogFood types:

    type CatFood implements Food { eatenBy: Animal! } # was `eatenBy: Cat`
    type DogFood implements Food { eatenBy: Animal! } # was `eatenBy: Dog`

It also works when the eatenBy stays CatFood and DogFood, but the eats fields type is changed to Food in Cat and `Dog:

    type Cat implements Animal { eats: [Food!]! } # was `eats: CatFood`
    type Dog implements Animal { eats: [Food!]! } # was `eats: DogFood`

Environment

  • Elixir version: tried with several versions from 24.3.4 up to 26.2.2
  • Absinthe version: 1.7.6
@maartenvanvliet
Copy link
Contributor

I suspect this happens in the ObjectMustImplementInterfaces phase. It does covariant checking there and can get quite difficult to follow. There's also some normalization happening.

I don't have time to work on it but wanted to point to what I think is happening.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants