Skip to content

Commit

Permalink
Added in-memory cache for persisted queries. (#2872)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib authored Jan 14, 2021
1 parent 687be58 commit 2131a7a
Show file tree
Hide file tree
Showing 27 changed files with 1,099 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public static async Task<ClientQueryResult> GetStoreActivePersistedQueryAsync(
HttpResponseMessage response =
await SendGetRequestAsync(
testServer,
$"query={query}&" +
$"query={query}&" +
"extensions={\"persistedQuery\":{\"version\":1," +
$"\"{hashName}\":\"{hash}\"}}}}",
path);
Expand Down Expand Up @@ -254,7 +254,7 @@ public static Task<HttpResponseMessage> SendGetRequestAsync(
this TestServer testServer, string query, string path = null)
{
return testServer.CreateClient()
.GetAsync($"{CreateUrl(path)}?{query}");
.GetAsync($"{CreateUrl(path)}/?{query}");
}

public static string CreateUrl(string path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,12 @@ public static IRequestExecutorBuilder UsePersistedQueryPipeline(
.UseOperationExecution();
}

[Obsolete("Use UseAutomaticPersistedQueryPipeline")]
public static IRequestExecutorBuilder UseActivePersistedQueryPipeline(
this IRequestExecutorBuilder builder) =>
UseAutomaticPersistedQueryPipeline(builder);

public static IRequestExecutorBuilder UseAutomaticPersistedQueryPipeline(
this IRequestExecutorBuilder builder)
{
if (builder is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,26 +136,32 @@ public static IServiceCollection AddOperationCache(
}

public static IServiceCollection AddMD5DocumentHashProvider(
this IServiceCollection services)
this IServiceCollection services,
HashFormat format = HashFormat.Base64)
{
services.RemoveAll<IDocumentHashProvider>();
services.AddSingleton<IDocumentHashProvider, MD5DocumentHashProvider>();
services.AddSingleton<IDocumentHashProvider>(
new MD5DocumentHashProvider(format));
return services;
}

public static IServiceCollection AddSha1DocumentHashProvider(
this IServiceCollection services)
this IServiceCollection services,
HashFormat format = HashFormat.Base64)
{
services.RemoveAll<IDocumentHashProvider>();
services.AddSingleton<IDocumentHashProvider, Sha1DocumentHashProvider>();
services.AddSingleton<IDocumentHashProvider>(
new Sha1DocumentHashProvider(format));
return services;
}

public static IServiceCollection AddSha256DocumentHashProvider(
this IServiceCollection services)
this IServiceCollection services,
HashFormat format = HashFormat.Base64)
{
services.RemoveAll<IDocumentHashProvider>();
services.AddSingleton<IDocumentHashProvider, Sha256DocumentHashProvider>();
services.AddSingleton<IDocumentHashProvider>(
new Sha256DocumentHashProvider(format));
return services;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static ISchemaBuilder EnableRelaySupport(
{
options ??= new();

if (options.AddQueryFieldsToMutations)
if (options.AddQueryFieldToMutationPayloads)
{
schemaBuilder.TryAddTypeInterceptor<QueryFieldTypeInterceptor>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class RelayOptions
/// If set to <c>true</c> the mutation payloads are rewritten to provide access to
/// the query root type to allow better capabilities refetch data.
/// </summary>
public bool AddQueryFieldsToMutations { get; set; }
public bool AddQueryFieldToMutationPayloads { get; set; }

/// <summary>
/// The name of the query field on a mutation payload (default: query).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async Task EnableRelay_AddQueryToMutationPayloads()
.AddGraphQL()
.AddQueryType<QueryType>()
.AddMutationType<Mutation>()
.EnableRelaySupport(new RelayOptions { AddQueryFieldsToMutations = true })
.EnableRelaySupport(new RelayOptions { AddQueryFieldToMutationPayloads = true })
.BuildSchemaAsync()
.MatchSnapshotAsync();
}
Expand All @@ -47,7 +47,7 @@ public async Task EnableRelay_AddQueryToMutationPayloads_With_Extensions()
.AddQueryType<QueryType>()
.AddMutationType(d => d.Name("Mutation"))
.AddTypeExtension<MutationExtension>()
.EnableRelaySupport(new RelayOptions { AddQueryFieldsToMutations = true })
.EnableRelaySupport(new RelayOptions { AddQueryFieldToMutationPayloads = true })
.BuildSchemaAsync()
.MatchSnapshotAsync();
}
Expand All @@ -61,7 +61,7 @@ public async Task EnableRelay_AddQueryToMutationPayloads_Refetch_SomeId()
.AddGraphQL()
.AddQueryType<QueryType>()
.AddMutationType<Mutation>()
.EnableRelaySupport(new RelayOptions { AddQueryFieldsToMutations = true })
.EnableRelaySupport(new RelayOptions { AddQueryFieldToMutationPayloads = true })
.ExecuteRequestAsync("mutation { foo { query { some { id } } } }")
.MatchSnapshotAsync();
}
Expand All @@ -75,7 +75,7 @@ public async Task EnableRelay_AddQueryToMutationPayloads_Refetch_SomeId_With_Que
.AddGraphQL()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.EnableRelaySupport(new RelayOptions { AddQueryFieldsToMutations = true })
.EnableRelaySupport(new RelayOptions { AddQueryFieldToMutationPayloads = true })
.ExecuteRequestAsync("mutation { foo { query { some { id } } } }")
.MatchSnapshotAsync();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ namespace HotChocolate.Language
public class Sha1DocumentHashProvider
: DocumentHashProviderBase
{
private readonly ThreadLocal<SHA1> _sha =
new ThreadLocal<SHA1>(() => SHA1.Create());
private readonly ThreadLocal<SHA1> _sha = new(SHA1.Create);

public Sha1DocumentHashProvider()
: this(HashFormat.Base64)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ namespace HotChocolate.Language
public class Sha256DocumentHashProvider
: DocumentHashProviderBase
{
private readonly ThreadLocal<SHA256> _sha =
new ThreadLocal<SHA256>(() => SHA256.Create());
private readonly ThreadLocal<SHA256> _sha = new(SHA256.Create);

public Sha256DocumentHashProvider()
: this(HashFormat.Base64)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HotChocolate.Subscriptions"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HotChocolate.Utilities", "..\Utilities\src\Utilities\HotChocolate.Utilities.csproj", "{8BCB768F-4588-41A2-9C7F-7AE7F3FAC404}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.PersistedQueries.InMemory", "src\PersistedQueries.InMemory\HotChocolate.PersistedQueries.InMemory.csproj", "{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.PersistedQueries.InMemory.Tests", "test\PersistedQueries.InMemory.Tests\HotChocolate.PersistedQueries.InMemory.Tests.csproj", "{406929B9-06ED-428D-B478-A21B41B9BDC0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -207,6 +211,30 @@ Global
{8BCB768F-4588-41A2-9C7F-7AE7F3FAC404}.Release|x64.Build.0 = Release|Any CPU
{8BCB768F-4588-41A2-9C7F-7AE7F3FAC404}.Release|x86.ActiveCfg = Release|Any CPU
{8BCB768F-4588-41A2-9C7F-7AE7F3FAC404}.Release|x86.Build.0 = Release|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Debug|x64.ActiveCfg = Debug|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Debug|x64.Build.0 = Debug|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Debug|x86.ActiveCfg = Debug|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Debug|x86.Build.0 = Debug|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Release|Any CPU.Build.0 = Release|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Release|x64.ActiveCfg = Release|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Release|x64.Build.0 = Release|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Release|x86.ActiveCfg = Release|Any CPU
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB}.Release|x86.Build.0 = Release|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Debug|x64.ActiveCfg = Debug|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Debug|x64.Build.0 = Debug|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Debug|x86.ActiveCfg = Debug|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Debug|x86.Build.0 = Debug|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Release|Any CPU.Build.0 = Release|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Release|x64.ActiveCfg = Release|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Release|x64.Build.0 = Release|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Release|x86.ActiveCfg = Release|Any CPU
{406929B9-06ED-428D-B478-A21B41B9BDC0}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -225,6 +253,8 @@ Global
{A00201B6-4099-40A9-936A-D7D7D9EB6A62} = {0FE82812-5154-4AF6-9053-487CBD1C5E74}
{84E30541-5226-4FD4-A93B-A87018CC47BC} = {0FE82812-5154-4AF6-9053-487CBD1C5E74}
{8BCB768F-4588-41A2-9C7F-7AE7F3FAC404} = {0FE82812-5154-4AF6-9053-487CBD1C5E74}
{FDCD436C-3276-4F21-AC8F-E3DCA4EB41EB} = {9313BB55-188C-4067-9514-9317E83847BC}
{406929B9-06ED-428D-B478-A21B41B9BDC0} = {A302B0E8-3C01-458D-8C2D-D59FF528287A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FAA72987-7EEF-40D2-B232-34E3D16C9489}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using HotChocolate;
using HotChocolate.Execution.Configuration;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using HotChocolate;
using HotChocolate.Execution.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Provides utility methods to setup dependency injection.
/// </summary>
public static class HotChocolateInMemoryPersistedQueriesRequestExecutorBuilderExtensions
{
/// <summary>
/// Adds a file system read and write query storage to the
/// services collection.
/// </summary>
/// <param name="builder">
/// The service collection to which the services are added.
/// </param>
/// <param name="cacheDirectory">
/// The directory path that shall be used to store queries.
/// </param>
public static IRequestExecutorBuilder AddInMemoryQueryStorage(
this IRequestExecutorBuilder builder)
{
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}

return builder.ConfigureSchemaServices(
s => s.AddInMemoryQueryStorage());
}

/// <summary>
/// Adds a file system read-only query storage to the
/// services collection.
/// </summary>
/// <param name="builder">
/// The service collection to which the services are added.
/// </param>
/// <param name="cacheDirectory">
/// The directory path that shall be used to read queries from.
/// </param>
public static IRequestExecutorBuilder AddReadOnlyInMemoryQueryStorage(
this IRequestExecutorBuilder builder)
{
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}

return builder.ConfigureSchemaServices(
s => s.AddReadOnlyInMemoryQueryStorage());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using HotChocolate.Execution;
using HotChocolate.PersistedQueries.FileSystem;
using Microsoft.Extensions.Caching.Memory;

namespace HotChocolate
{
/// <summary>
/// Provides utility methods to setup dependency injection.
/// </summary>
public static class HotChocolateInMemoryPersistedQueriesServiceCollectionExtensions
{
/// <summary>
/// Adds a file system read and write query storage to the
/// services collection.
/// </summary>
/// <param name="services">
/// The service collection to which the services are added.
/// </param>
/// <param name="cacheDirectory">
/// The directory path that shall be used to store queries.
/// </param>
public static IServiceCollection AddInMemoryQueryStorage(
this IServiceCollection services)
{
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}

return services
.AddReadOnlyInMemoryQueryStorage()
.AddSingleton<IWriteStoredQueries>(
sp => sp.GetRequiredService<InMemoryQueryStorage>());
}

/// <summary>
/// Adds a file system read-only query storage to the
/// services collection.
/// </summary>
/// <param name="services">
/// The service collection to which the services are added.
/// </param>
/// <param name="cacheDirectory">
/// The directory path that shall be used to read queries from.
/// </param>
public static IServiceCollection AddReadOnlyInMemoryQueryStorage(
this IServiceCollection services)
{
if (services is null)
{
throw new ArgumentNullException(nameof(services));
}

return services
.RemoveService<IReadStoredQueries>()
.RemoveService<IWriteStoredQueries>()
.AddSingleton(c => new InMemoryQueryStorage(
c.GetService<IMemoryCache>() ??
c.GetApplicationService<IMemoryCache>()))
.AddSingleton<IReadStoredQueries>(
sp => sp.GetRequiredService<InMemoryQueryStorage>());
}

private static IServiceCollection RemoveService<TService>(
this IServiceCollection services)
{
ServiceDescriptor? serviceDescriptor =
services.FirstOrDefault(t => t.ServiceType == typeof(TService));

if (serviceDescriptor != null)
{
services.Remove(serviceDescriptor);
}

return services;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="Current">

<PropertyGroup>
<PackageId>HotChocolate.PersistedQueries.InMemory</PackageId>
<AssemblyName>HotChocolate.PersistedQueries.InMemory</AssemblyName>
<RootNamespace>HotChocolate.PersistedQueries.InMemory</RootNamespace>
<Description>An implementation of Hot Chocolate persisted queries using Microsoft.Extensions.Caching.Memory.IMemoryCache.</Description>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\Core\src\Core\HotChocolate.Core.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.0" />
</ItemGroup>

<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

</Project>
Loading

0 comments on commit 2131a7a

Please sign in to comment.