rmosolgo/graphql-ruby

Max complexity not respected when using enterprise object cache

ollie-nye opened this issue · 2 comments

Describe the bug

Not sure if it's something we're doing or not, but in our schema we have max_complexity 200, count_introspection_fields: false. The introspection query comes in at a calculated complexity of 215 or 217, and gets blocked even with count_introspection_fields: false. We've also got use(GraphQL::Enterprise::ObjectCache, redis_cluster: ApplicationRedis.instance.redis) in the schema, but removing this line lets the introspection query through with a 0 cost. I saw that count_introspection_fields: false is relatively new, is there somewhere we need to set that for the enterprise side as well?

Changing max complexity to something larger like 220 and restarting the rails server also doesn't seem to have an effect, the error message still has the max set at 200.

Versions

graphql version: 2.3.4
rails (or other framework): 7.1.3.4
graphql-enterprise: 1.4.0
graphql-pro: 1.27.0
graphql-batch: 0.6.0

GraphQL schema

class ApiSchema < GraphQL::Schema
  use(GraphQL::Batch)
  use(GraphQL::Subscriptions::ActionCableSubscriptions, broadcast: true)

  if ApplicationRedis.instance.redis
    use(GraphQL::Enterprise::ObjectCache, redis_cluster: ApplicationRedis.instance.redis)
  end

  mutation(Types::MutationType)
  query(Types::QueryType)
  subscription(Types::RootSubscriptionType)

  max_complexity 200, count_introspection_fields: false
  max_depth 7, count_introspection_fields: false
end

GraphQL query

Example GraphQL query and response (if query execution is involved)

Any introspection query, tried GraphiQL and Insomnia with the same results

Steps to reproduce

  • Load up GraphiQL and refresh documentation

Expected behavior

Introspection query is allowed and documentation is rendered in GraphiQL

Actual behavior

What specifically went wrong?

GraphiQL starting shows the below error message as a result of its initial introspection query being fired:

{
  "errors": [
    {
      "message": "Query has complexity of 215, which exceeds max complexity of 200"
    }
  ]
}

Additional context

Add any other context about the problem here.

With these details, we can efficiently hunt down the bug!

Hey, sorry for the trouble and thanks for the detailed report!

Is it possible that the result was cached before count_introspection_fields: false was configured? I think the cache is returning the (cached) error response, ignoring that setting.

To address this problem, I just released GraphQL-Enterprise v1.4.2 with two new features:

  • context[:refresh_object_cache]: if it's set to true, the cache will ignore any cached result and re-evaluate the query (caching the result if appropriate). You could set that to cause this query to be re-evaluated with the new settings.
  • def self.fingerprint in your schema class: implement this method to return a String; when it returns a new string, any already-cached results will be expired. (Use it to expire all previously-cached results).

Would one of those approaches work for you? Please download that new version and give it a try if you think it'd work for you.

Using fingerprint looks like it did the trick, thank you so much for the quick fix!