Skip to content

Commit

Permalink
Memory Optimization on Schema (#6290)
Browse files Browse the repository at this point in the history
  • Loading branch information
PascalSenn authored Jun 25, 2023
1 parent aaa0c43 commit e11401c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 22 deletions.
32 changes: 20 additions & 12 deletions src/HotChocolate/Core/src/Types/Schema.Initialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace HotChocolate;

public partial class Schema
{
private readonly Action<ISchemaTypeDescriptor> _configure;
private Action<ISchemaTypeDescriptor> _configure;
private bool _sealed;

protected internal Schema()
Expand All @@ -24,18 +24,30 @@ public Schema(Action<ISchemaTypeDescriptor> configure)

protected virtual void Configure(ISchemaTypeDescriptor descriptor) { }

protected sealed override SchemaTypeDefinition CreateDefinition(
ITypeDiscoveryContext context)
protected sealed override SchemaTypeDefinition CreateDefinition(ITypeDiscoveryContext context)
{
var descriptor = SchemaTypeDescriptor.New(
context.DescriptorContext,
GetType());
var descriptor = SchemaTypeDescriptor.New(context.DescriptorContext, GetType());

_configure(descriptor);

return descriptor.CreateDefinition();
}

protected override void OnAfterInitialize(
ITypeDiscoveryContext context,
DefinitionBase definition)
{
base.OnAfterInitialize(context, definition);

// we clear the configuration delegate to make sure that we do not hold on to any references
// if we do not do this all the instances used during initialization will be kept in memory
// until the schema is phased out.
// We do this in OnAfterInitialized because after this point the schema is marked as
// initialized. This means that a subsequent call to Initialize will throw anyway and
// therefore we do not need to keep the configuration delegate.
_configure = null;
}

protected override void OnRegisterDependencies(
ITypeDiscoveryContext context,
SchemaTypeDefinition definition)
Expand All @@ -46,10 +58,7 @@ protected override void OnRegisterDependencies(
{
foreach (var directive in definition.Directives)
{
context.Dependencies.Add(
new(
directive.Type,
TypeDependencyFulfilled.Completed));
context.Dependencies.Add(new(directive.Type, TypeDependencyFulfilled.Completed));
}
}

Expand All @@ -72,8 +81,7 @@ protected override void OnCompleteType(
Services = context.Services;
}

internal void CompleteSchema(
SchemaTypesDefinition schemaTypesDefinition)
internal void CompleteSchema(SchemaTypesDefinition schemaTypesDefinition)
{
if (schemaTypesDefinition is null)
{
Expand Down
22 changes: 12 additions & 10 deletions src/HotChocolate/Core/src/Types/Types/DirectiveType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@
namespace HotChocolate.Types;

/// <summary>
/// <para>
/// A GraphQL schema describes directives which are used to annotate various parts of a
/// GraphQL document as an indicator that they should be evaluated differently by a
/// validator, executor, or client tool such as a code generator.
///
/// http://spec.graphql.org/draft/#sec-Type-System.Directives
/// </para>
/// <para>http://spec.graphql.org/draft/#sec-Type-System.Directives</para>
/// </summary>
public partial class DirectiveType
: TypeSystemObjectBase<DirectiveTypeDefinition>
, IHasRuntimeType
, IHasTypeIdentity
, IHasRuntimeType
, IHasTypeIdentity
{
private Action<IDirectiveTypeDescriptor>? _configure;
private Func<object?[], object> _createInstance = default!;
Expand Down Expand Up @@ -81,12 +82,11 @@ public static DirectiveType CreateUnsafe(DirectiveTypeDefinition definition)
/// <summary>
/// Gets the directive field middleware.
/// </summary>
public DirectiveMiddleware? Middleware { get; private set; } =
default!;
public DirectiveMiddleware? Middleware { get; private set; }

/// <summary>
/// Defines that this directive can be used in executable GraphQL documents.
///
/// <para>Defines that this directive can be used in executable GraphQL documents.</para>
/// <para>
/// In order to be executable a directive must at least be valid
/// in one of the following locations:
/// QUERY (<see cref="DirectiveLocation.Query"/>)
Expand All @@ -97,12 +97,13 @@ public static DirectiveType CreateUnsafe(DirectiveTypeDefinition definition)
/// FRAGMENT_SPREAD (<see cref="DirectiveLocation.FragmentSpread"/>)
/// INLINE_FRAGMENT (<see cref="DirectiveLocation.InlineFragment"/>)
/// VARIABLE_DEFINITION (<see cref="DirectiveLocation.VariableDefinition"/>)
/// </para>
/// </summary>
public bool IsExecutableDirective { get; private set; }

/// <summary>
/// Defines that this directive can be applied to type system members.
///
/// <para>Defines that this directive can be applied to type system members.</para>
/// <para>
/// In order to be a type system directive it must at least be valid
/// in one of the following locations:
/// SCHEMA (<see cref="DirectiveLocation.Schema"/>)
Expand All @@ -116,6 +117,7 @@ public static DirectiveType CreateUnsafe(DirectiveTypeDefinition definition)
/// ENUM_VALUE (<see cref="DirectiveLocation.EnumValue"/>)
/// INPUT_OBJECT (<see cref="DirectiveLocation.InputObject"/>)
/// INPUT_FIELD_DEFINITION (<see cref="DirectiveLocation.InputFieldDefinition"/>)
/// </para>
/// </summary>
public bool IsTypeSystemDirective { get; private set; }

Expand Down

0 comments on commit e11401c

Please sign in to comment.