Skip to content

✨ catalogd graphql shift to file-based cache#2732

Open
grokspawn wants to merge 1 commit into
operator-framework:mainfrom
grokspawn:graphql-file-cache
Open

✨ catalogd graphql shift to file-based cache#2732
grokspawn wants to merge 1 commit into
operator-framework:mainfrom
grokspawn:graphql-file-cache

Conversation

@grokspawn
Copy link
Copy Markdown
Contributor

Description

This PR proposes a shift in the graphql service endpoint from in-memory to on-disk caching which leverages common architectural conventions like fan-out catalog index generation (graphql-schema.json) which is then accessed to fulfill queries to eliminate RSS increases from the feature initial implementation.

Included is a structured graphql validation package as a focus for future limits enforcement and adds several cold-cache/cache-miss concurrency tests.

Reviewer Checklist

  • API Go Documentation
  • Tests: Unit Tests (and E2E Tests, if appropriate)
  • Comprehensive Commit Messages
  • Links to related GitHub Issue(s)

Copilot AI review requested due to automatic review settings May 29, 2026 20:07
@openshift-ci openshift-ci Bot requested review from dtfranz and perdasilva May 29, 2026 20:07
@netlify
Copy link
Copy Markdown

netlify Bot commented May 29, 2026

Deploy Preview for olmv1 ready!

Name Link
🔨 Latest commit ec01fe5
🔍 Latest deploy log https://app.netlify.com/projects/olmv1/deploys/6a19f1fa472f860008c48c28
😎 Deploy Preview https://deploy-preview-2732--olmv1.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented May 29, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign camilamacedo86 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR shifts catalogd’s GraphQL implementation from building/caching schemas off in-memory catalog metas to a file-based approach: schema metadata is discovered during Store() and persisted to disk, while query execution loads requested objects from catalog.jsonl on-demand using byte offsets from index.json. It also introduces a query complexity validation helper and updates handlers/tests to use the new GraphQL service interface.

Changes:

  • Persist GraphQL schema metadata to graphql-schema.json during catalog storage and load it from disk for schema building.
  • Switch query execution to disk-backed object loading using index-based byte offsets (reducing RSS growth from caching parsed objects).
  • Add a GraphQL query complexity validation helper and expand concurrency/singleflight tests around cache misses/builds.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
internal/catalogd/storage/localdir.go Writes graphql-schema.json on store, adds disk-backed object loader, and adjusts GraphQL pre-warm behavior.
internal/catalogd/storage/index.go Exposes schema-section byte ranges for disk-backed GraphQL pagination.
internal/catalogd/service/graphql_service.go Refactors service to use a storage-provided data provider and adds query validation/timeout.
internal/catalogd/service/graphql_service_test.go Updates tests to use the new provider-based GraphQL service and adds singleflight coverage via provider counting.
internal/catalogd/server/handlers.go Updates GraphQL handler to execute queries without needing a catalog FS.
internal/catalogd/server/handlers_test.go Updates mocks/tests for the new GraphQL service interface and error behavior.
internal/catalogd/graphql/validation.go Adds AST-based query complexity validation (depth/aliases/fields).
internal/catalogd/graphql/graphql.go Adds schema serialization/deserialization and switches to loader-based query-time object retrieval.
hack/demo/graphql-demo-server/main.go Updates demo server to build schema once and serve GraphQL directly from the generated schema.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +355 to +358
buf := make([]byte, sec.Length)
if _, err := f.ReadAt(buf, sec.Offset); err != nil {
return nil, fmt.Errorf("error reading section at offset %d: %w", sec.Offset, err)
}
Comment on lines +332 to +336
return func(schemaName string, offset, limit int) ([]map[string]interface{}, error) {
sections := idx.GetSchemaSections(schemaName)
if sections == nil {
return nil, nil
}
Comment on lines +93 to +96
s.graphqlSvc.InvalidateCache(catalog)

if _, err := s.graphqlSvc.GetSchema(context.Background(), catalog); err != nil {
// Schema build failed — remove the catalog to maintain consistency.
Comment on lines +120 to +128
func serializableToFieldInfo(sfi *serializableFieldInfo) *FieldInfo {
k := stringToKind(sfi.JSONType)
fi := &FieldInfo{
Name: sfi.Name,
OriginalName: sfi.OriginalName,
JSONType: k,
IsArray: sfi.IsArray,
GraphQLType: jsonTypeToGraphQL(k, sfi.IsArray, nil),
}
Comment on lines +48 to +70
for _, sel := range ss.Selections {
switch s := sel.(type) {
case *ast.Field:
c.fields++
if c.fields > MaxQueryFields {
return fmt.Errorf("query exceeds maximum field count of %d", MaxQueryFields)
}
if s.Alias != nil && s.Alias.Value != "" {
c.aliases++
if c.aliases > MaxQueryAliases {
return fmt.Errorf("query exceeds maximum alias count of %d", MaxQueryAliases)
}
}
if err := c.walkSelectionSet(s.SelectionSet, depth+1); err != nil {
return err
}
case *ast.InlineFragment:
if err := c.walkSelectionSet(s.SelectionSet, depth+1); err != nil {
return err
}
case *ast.FragmentSpread:
c.fields++
}
@codecov
Copy link
Copy Markdown

codecov Bot commented May 29, 2026

Codecov Report

❌ Patch coverage is 45.14286% with 192 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.64%. Comparing base (70601b6) to head (ec01fe5).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/catalogd/graphql/graphql.go 61.49% 58 Missing and 9 partials ⚠️
internal/catalogd/storage/localdir.go 43.02% 40 Missing and 9 partials ⚠️
internal/catalogd/graphql/validation.go 0.00% 33 Missing ⚠️
hack/demo/graphql-demo-server/main.go 0.00% 27 Missing ⚠️
internal/catalogd/service/graphql_service.go 61.90% 7 Missing and 1 partial ⚠️
internal/catalogd/storage/index.go 0.00% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2732      +/-   ##
==========================================
- Coverage   67.07%   66.64%   -0.43%     
==========================================
  Files         149      150       +1     
  Lines       11339    11565     +226     
==========================================
+ Hits         7606     7708     +102     
- Misses       3179     3291     +112     
- Partials      554      566      +12     
Flag Coverage Δ
e2e 34.42% <1.23%> (-0.92%) ⬇️
experimental-e2e 52.45% <44.58%> (-0.31%) ⬇️
unit 51.31% <16.28%> (-0.79%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Successfully merging this pull request may close these issues.

2 participants