apollographql / apollo-studio-community

🎡  GraphQL developer portal featuring an IDE (Apollo Explorer), auto-documentation, metrics reporting, and more. This repo is for issues, feature requests, and preview docs. 📬
https://studio.apollographql.com
249 stars 29 forks source link

Query to server in Ruby on Rails gets stuck in introspection loop #133

Open AngelAlexQC opened 2 years ago

AngelAlexQC commented 2 years ago

Hello, I recently discovered this tool and I find it wonderful, it is the best Graphl client I have used, I want to contribute by reporting a problem that happens to me.

I was trying to do a query to my server in Ruby on Rails but it stays in the request infinitely without returning a response.

In the rails logs the query succeeds but it does the instrospection again, and it repeats infinitely.

This has only happened to me with rails servers, because in one with Node this does not happen, however in the rails server the requests with other clients such as Insomnia are performed successfully. The client is stuck in loading state and the response is never displayed:

Screenshot

This is one fragment of the logs:

I, [2022-01-07T11:09:59.253688 #1559]  INFO -- : Processing by GraphqlController#execute as */*
I, [2022-01-07T11:09:59.254103 #1559]  INFO -- :   Parameters: {"query"=>"query Survey($token: String!) {\n  survey(token: $token) {\n    id\n    storeId\n    status\n    surveyTitle\n    surveyType\n    surveyToken\n    menuItems {\n      id\n      like\n    }\n    invoice {\n      listInvoices {\n        userInvoice {\n          fullname\n          email\n        }\n      }\n    }\n  }\n}\n", "variables"=>{"token"=>"e26949af074157591753"}, "operationName"=>"Survey", "graphql"=>{"query"=>"query Survey($token: String!) {\n  survey(token: $token) {\n    id\n    storeId\n    status\n    surveyTitle\n    surveyType\n    surveyToken\n    menuItems {\n      id\n      like\n    }\n    invoice {\n      listInvoices {\n        userInvoice {\n          fullname\n          email\n        }\n      }\n    }\n  }\n}\n", "variables"=>{"token"=>"e26949af074157591753"}, "operationName"=>"Survey"}}
I, [2022-01-07T11:10:02.301511 #1559]  INFO -- : Completed 200 OK in 3432ms (Views: 440.8ms | MongoDB: 0.0ms)

I, [2022-01-07T11:10:02.392025 #1559]  INFO -- : Processing by GraphqlController#execute as */*
I, [2022-01-07T11:10:02.392363 #1559]  INFO -- :   Parameters: {"query"=>"\n    query IntrospectionQuery {\n      __schema {\n        \n        queryType { name }\n        mutationType { name }\n        subscriptionType { name }\n        types {\n          ...FullType\n        }\n        directives {\n          name\n          description\n          \n          locations\n          args(includeDeprecated: true) {\n            ...InputValue\n          }\n        }\n      }\n    }\n\n    fragment FullType on __Type {\n      kind\n      name\n      description\n      \n      fields(includeDeprecated: true) {\n        name\n        description\n        args(includeDeprecated: true) {\n          ...InputValue\n        }\n        type {\n          ...TypeRef\n        }\n        isDeprecated\n        deprecationReason\n      }\n      inputFields(includeDeprecated: true) {\n        ...InputValue\n      }\n      interfaces {\n        ...TypeRef\n      }\n      enumValues(includeDeprecated: true) {\n        name\n        description\n        isDeprecated\n        deprecationReason\n      }\n      possibleTypes {\n        ...TypeRef\n      }\n    }\n\n    fragment InputValue on __InputValue {\n      name\n      description\n      type { ...TypeRef }\n      defaultValue\n      isDeprecated\n      deprecationReason\n    }\n\n    fragment TypeRef on __Type {\n      kind\n      name\n      ofType {\n        kind\n        name\n        ofType {\n          kind\n          name\n          ofType {\n            kind\n            name\n            ofType {\n              kind\n              name\n              ofType {\n                kind\n                name\n                ofType {\n                  kind\n                  name\n                  ofType {\n                    kind\n                    name\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  ", "operationName"=>"IntrospectionQuery", "graphql"=>{"query"=>"\n    query IntrospectionQuery {\n      __schema {\n        \n        queryType { name }\n        mutationType { name }\n        subscriptionType { name }\n        types {\n          ...FullType\n        }\n        directives {\n          name\n          description\n          \n          locations\n          args(includeDeprecated: true) {\n            ...InputValue\n          }\n        }\n      }\n    }\n\n    fragment FullType on __Type {\n      kind\n      name\n      description\n      \n      fields(includeDeprecated: true) {\n        name\n        description\n        args(includeDeprecated: true) {\n          ...InputValue\n        }\n        type {\n          ...TypeRef\n        }\n        isDeprecated\n        deprecationReason\n      }\n      inputFields(includeDeprecated: true) {\n        ...InputValue\n      }\n      interfaces {\n        ...TypeRef\n      }\n      enumValues(includeDeprecated: true) {\n        name\n        description\n        isDeprecated\n        deprecationReason\n      }\n      possibleTypes {\n        ...TypeRef\n      }\n    }\n\n    fragment InputValue on __InputValue {\n      name\n      description\n      type { ...TypeRef }\n      defaultValue\n      isDeprecated\n      deprecationReason\n    }\n\n    fragment TypeRef on __Type {\n      kind\n      name\n      ofType {\n        kind\n        name\n        ofType {\n          kind\n          name\n          ofType {\n            kind\n            name\n            ofType {\n              kind\n              name\n              ofType {\n                kind\n                name\n                ofType {\n                  kind\n                  name\n                  ofType {\n                    kind\n                    name\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  ", "operationName"=>"IntrospectionQuery"}}
I, [2022-01-07T11:10:06.125514 #1559]  INFO -- : Completed 200 OK in 3732ms (Views: 446.7ms | MongoDB: 0.0ms)

I, [2022-01-07T11:10:06.142415 #1559]  INFO -- : Processing by GraphqlController#execute as */*
I, [2022-01-07T11:10:06.144628 #1559]  INFO -- :   Parameters: {"query"=>"\n    query IntrospectionQuery {\n      __schema {\n        \n        queryType { name }\n        mutationType { name }\n        subscriptionType { name }\n        types {\n          ...FullType\n        }\n        directives {\n          name\n          description\n          \n          locations\n          args(includeDeprecated: true) {\n            ...InputValue\n          }\n        }\n      }\n    }\n\n    fragment FullType on __Type {\n      kind\n      name\n      description\n      \n      fields(includeDeprecated: true) {\n        name\n        description\n        args(includeDeprecated: true) {\n          ...InputValue\n        }\n        type {\n          ...TypeRef\n        }\n        isDeprecated\n        deprecationReason\n      }\n      inputFields(includeDeprecated: true) {\n        ...InputValue\n      }\n      interfaces {\n        ...TypeRef\n      }\n      enumValues(includeDeprecated: true) {\n        name\n        description\n        isDeprecated\n        deprecationReason\n      }\n      possibleTypes {\n        ...TypeRef\n      }\n    }\n\n    fragment InputValue on __InputValue {\n      name\n      description\n      type { ...TypeRef }\n      defaultValue\n      isDeprecated\n      deprecationReason\n    }\n\n    fragment TypeRef on __Type {\n      kind\n      name\n      ofType {\n        kind\n        name\n        ofType {\n          kind\n          name\n          ofType {\n            kind\n            name\n            ofType {\n              kind\n              name\n              ofType {\n                kind\n                name\n                ofType {\n                  kind\n                  name\n                  ofType {\n                    kind\n                    name\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  ", "operationName"=>"IntrospectionQuery", "graphql"=>{"query"=>"\n    query IntrospectionQuery {\n      __schema {\n        \n        queryType { name }\n        mutationType { name }\n        subscriptionType { name }\n        types {\n          ...FullType\n        }\n        directives {\n          name\n          description\n          \n          locations\n          args(includeDeprecated: true) {\n            ...InputValue\n          }\n        }\n      }\n    }\n\n    fragment FullType on __Type {\n      kind\n      name\n      description\n      \n      fields(includeDeprecated: true) {\n        name\n        description\n        args(includeDeprecated: true) {\n          ...InputValue\n        }\n        type {\n          ...TypeRef\n        }\n        isDeprecated\n        deprecationReason\n      }\n      inputFields(includeDeprecated: true) {\n        ...InputValue\n      }\n      interfaces {\n        ...TypeRef\n      }\n      enumValues(includeDeprecated: true) {\n        name\n        description\n        isDeprecated\n        deprecationReason\n      }\n      possibleTypes {\n        ...TypeRef\n      }\n    }\n\n    fragment InputValue on __InputValue {\n      name\n      description\n      type { ...TypeRef }\n      defaultValue\n      isDeprecated\n      deprecationReason\n    }\n\n    fragment TypeRef on __Type {\n      kind\n      name\n      ofType {\n        kind\n        name\n        ofType {\n          kind\n          name\n          ofType {\n            kind\n            name\n            ofType {\n              kind\n              name\n              ofType {\n                kind\n                name\n                ofType {\n                  kind\n                  name\n                  ofType {\n                    kind\n                    name\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  ", "operationName"=>"IntrospectionQuery"}}
I, [2022-01-07T11:10:09.204139 #1559]  INFO -- : Completed 200 OK in 3059ms (Views: 491.3ms | MongoDB: 0.0ms)

I, [2022-01-07T11:10:09.218368 #1559]  INFO -- : Processing by GraphqlController#execute as */*
I, [2022-01-07T11:10:09.218787 #1559]  INFO -- :   Parameters: {"query"=>"\n    query IntrospectionQuery {\n      __schema {\n        \n        queryType { name }\n        mutationType { name }\n        subscriptionType { name }

As you can see the instrospection is repeated infinitely despite getting a response from the server.

cheapsteak commented 2 years ago

Hi there, thanks so much for the bug report!

We poll for introspection so that changes in your server can be picked up immediately, so that part may be functioning as expected? (If you'd like to disable the polling, please either click the green dot next to your endpoint to pause, or click the gear icon to open "connection settings" and disable "auto update")

Is indeed strange that it isn't returning a response though. Could you open chrome devtools, and see what is returned from the introspection request? (Find the network request to your endpoint that has a Payload with an operation name of operationName: "IntrospectionQuery")

AngelAlexQC commented 2 years ago

Ok, I disabled auto updating and it worked great. This is the response returned by the instrospection query:

image

Now I tried it activated and all the pending queries remain pending, the query that I execute and the instropection queries. The problem I think is that many requests are sent in a short time, and although they are all successful the server can't process so many at once.

image

I think it could be fixed by pausing the instrospection in the background while the query or mutation is executed.

cheapsteak commented 2 years ago

Ah thank you that makes sense

Perhaps we should allow people to specify how frequently the poll should occur

Curious what time interval might make sense for your server?

AngelAlexQC commented 2 years ago

Personally I would put it between 3 and 5 seconds, but it is much better if it is configurable by each user.