Skip to content

Conversation

@ScriptSmith
Copy link
Member

No description provided.

Copy link

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 aims to improve GraphQL performance by caching the dynamically generated Graphene schema and invalidating that cache when registry definitions change.

Changes:

  • Memoize create_dynamic_schema() using cache_memoize and add clear_dynamic_schema_cache().
  • Invalidate the schema cache on registry form/section/CDE changes.
  • Add new signal receivers intended to invalidate the schema cache on Registry / ContextFormGroup changes.

Reviewed changes

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

File Description
rdrf/report/schema.py Adds memoization to the dynamic schema builder and exposes an explicit cache invalidation hook.
rdrf/rdrf/models/definition/models.py Hooks schema cache invalidation into model lifecycle events via Django signals.

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

Comment on lines 1098 to 1100
@cache_memoize(settings.CACHE_DEFAULT_TIMEOUT)
def create_dynamic_schema():
if not Registry.objects.all().exists():
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

@cache_memoize uses the Django cache backend (db/memcached/etc) and will pickle the return value. A graphene.Schema built from dynamically created types and local resolver functions (closures/partials) is not pickleable, so caching create_dynamic_schema() this way is likely to raise a PicklingError at runtime when the decorator attempts to cache the schema.

Suggested fix: use a per-process in-memory cache (e.g., functools.lru_cache(maxsize=1) or a module-level singleton) and update clear_dynamic_schema_cache() to call cache_clear()/reset the module variable. If you truly need cross-process caching, cache a serializable representation (e.g., SDL) rather than the Schema object itself.

Copilot uses AI. Check for mistakes.
Comment on lines 1093 to 1094
@receiver([post_save, post_delete], sender="definition.Registry")
@receiver([post_save, post_delete], sender="definition.ContextFormGroup")
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The signal senders for registry_definition_changed are specified as strings ("definition.Registry" and "definition.ContextFormGroup"), but the actual model labels in this project appear to be under the rdrf app (e.g., settings installs the rdrf app, and other code references these models as "rdrf.Registry" / "rdrf.ContextFormGroup"). As written, this receiver likely never fires, so the dynamic schema cache won’t be invalidated when registries or context form groups change.

Suggested fix: use the model classes directly (sender=Registry / sender=ContextFormGroup) or update the string labels to "rdrf.Registry" and "rdrf.ContextFormGroup". It would also be good to add a test that creates/updates a ContextFormGroup or Registry and asserts create_dynamic_schema() reflects the change after invalidation.

Suggested change
@receiver([post_save, post_delete], sender="definition.Registry")
@receiver([post_save, post_delete], sender="definition.ContextFormGroup")
@receiver([post_save, post_delete], sender=Registry)
@receiver([post_save, post_delete], sender=ContextFormGroup)

Copilot uses AI. Check for mistakes.
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