Problem/Motivation

\Drupal\graphql\Plugin\GraphQL\Schema\SdlSchemaPluginBase::getSchema() does a cache get in \Drupal\graphql\Plugin\GraphQL\Schema\SdlSchemaPluginBase::getSchemaDocument() and does work and then does another cache get in \Drupal\graphql\Plugin\GraphQL\Schema\SdlSchemaPluginBase::getFullSchemaDocument() which makes all the previous work redundant. Let's check to see if the full cache exists

Proposed resolution

Remove ::getFullSchemaDocument() and put it's cache in the calling method above.

Remaining tasks

None

User interface changes

None

API changes

None

Data model changes

None

Issue fork graphql-3576164

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

alexpott created an issue. See original summary.

alexpott’s picture

Status: Active » Needs review
kingdutch’s picture

Status: Needs review » Postponed

The current form of caching actively breaks use-cases for things like directives (e.g graphql_oauth no longer works since that change was introduced). This is because the schema printer can only provide the SDL for the schema as a client would interpret it and can not preserve directives (since they may change server behaviour). There's a feature request in webonyx/graphql-php but it's blocked by the reference implementation (graphql-js) not actually supporting it.

With that in mind I want to make sure that #3572680: SdlSchemaPluginBase should cache AST instead of printing lands first, since it implements caching in a way that no longer actively breaks server-side behavior. That implementation is ready as of this week.

I would be curious to hear how that fares performance wise and if that's already an improvement. It does eliminate the full AST cache entirely, because the only way in the library to get that, while preserving things like directives, is to use SchemaExtender::extend.

I don't think we can cache the final Schema instance itself because it may contain closures. However, while writing this I can not directly point at any, so it may be worth experimenting with that route.

One benefit of the implementation in #3572680: SdlSchemaPluginBase should cache AST instead of printing is that we're now caching ASTs which reduces the amount of times we print and parse SDLs.

alexpott’s picture

Version: 5.x-dev » 8.x-4.x-dev
Status: Postponed » Needs work

I think this change is still good for the 4.x branch and I'll review #3572680: SdlSchemaPluginBase should cache AST instead of printing to make sure it is good for 5.x

alexpott changed the visibility of the branch 3576164-improve-efficiency-of to hidden.

alexpott’s picture

Status: Needs work » Needs review

Even if we have the cache this is the place where extension's resolvers are registered so we still need to do that.

On my site this change results in a massive performance improvement for a simple graphql query

query MyQuery {
  entityById(entityType: NODE, id: "3538") {
    id
    label
  }
}

Before

  • Wall time: 70ms to 81ms
  • Memory: 119.47MB
  • Recorded calls: 36430

After

  • Wall time: 45ms to 70ms
  • Memory: 66.31MB
  • Recorded calls: 35360
kingdutch’s picture

Status: Needs review » Fixed

There was a request to merge and release this in 4.x even though we took a different route for 5.x. The 5.x equivalent of this is the AST caching, which also restores functionality for GraphQL Directives, but that requires breaking changes and is thus not suitable for the 4.x version.

This PR still provides a good performance improvement for people who can not yet move to 5.x. Thanks Alex!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • kingdutch committed 25ef0c58 on 8.x-4.x authored by alexpott
    fix: #3576164 Improve efficiency of cache usage in SdlSchemaPluginBase::...