Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Variable Batching #6981

Merged
merged 43 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
53702b5
Start refactoring request/response structures
michaelstaib Mar 9, 2024
6a53c06
edits
michaelstaib Mar 9, 2024
acd732a
Remove export directive
michaelstaib Mar 9, 2024
41ae1f6
Edits
michaelstaib Mar 9, 2024
4ae9a28
Edits
michaelstaib Mar 9, 2024
0cc9fbe
Edits
michaelstaib Mar 9, 2024
1ae8ba9
Edits
michaelstaib Mar 9, 2024
80ecc93
Edits
michaelstaib Mar 9, 2024
27a4fe8
Edits
michaelstaib Mar 9, 2024
af47731
Edits
michaelstaib Mar 9, 2024
d697169
Abstraction Tests Work
michaelstaib Mar 9, 2024
08bbda7
clean snapshots
michaelstaib Mar 9, 2024
56e350f
fixed more tests
michaelstaib Mar 9, 2024
5fe19ef
fixed more tests
michaelstaib Mar 9, 2024
376996e
fixed more tests
michaelstaib Mar 9, 2024
9281c67
fixed more tests
michaelstaib Mar 9, 2024
515494e
fixed more tests
michaelstaib Mar 10, 2024
842b4c5
fixed more tests
michaelstaib Mar 10, 2024
90c0b8c
removed complexity code
michaelstaib Mar 10, 2024
b650551
removed complexity code
michaelstaib Mar 10, 2024
c492348
Fixed tests
michaelstaib Mar 10, 2024
fda5663
Fixed more tests
michaelstaib Mar 10, 2024
206d30c
Fixed more tests
michaelstaib Mar 10, 2024
7844d93
Fixed more tests
michaelstaib Mar 10, 2024
0601cf8
Edits
michaelstaib Mar 12, 2024
8d2afc4
Did some work on SSE
michaelstaib Mar 13, 2024
7b7d2a4
Fixed MultiPart Batching
michaelstaib Mar 17, 2024
c8479b0
fixed
michaelstaib Mar 17, 2024
ab4f868
Edits
michaelstaib Mar 19, 2024
62a514d
Merge branch 'main' into mst/variable-batching
michaelstaib May 1, 2024
996438e
edits
michaelstaib May 1, 2024
87141cb
eidts
michaelstaib May 1, 2024
77fdcad
edits
michaelstaib May 1, 2024
5fa2995
edits
michaelstaib May 6, 2024
ceae950
Merge branch 'main' into mst/variable-batching
michaelstaib May 13, 2024
1d4058c
edits
michaelstaib May 21, 2024
e9d1038
Merge branch 'main' into mst/variable-batching
michaelstaib May 21, 2024
7116207
edits
michaelstaib May 21, 2024
ad50107
Merge branch 'main' into mst/variable-batching
michaelstaib May 21, 2024
5a28e03
edits
michaelstaib May 21, 2024
9bd8a89
edits
michaelstaib May 22, 2024
d420bf0
edits
michaelstaib May 22, 2024
8bcdeca
Merge branch 'main' into mst/variable-batching
michaelstaib May 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ public static class CommonTestExtensions
if (context.ContextData.TryGetValue("ex", out var queryString))
{
context.Result =
QueryResultBuilder
OperationResultBuilder
.FromResult(context.Result!.ExpectQueryResult())
.SetContextData("ex", queryString)
.Create();
.Build();
}
})
.UseDefaultPipeline()
Expand Down
11 changes: 11 additions & 0 deletions src/CookieCrumble/src/CookieCrumble/Extensions/WriterExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ public static void AppendLine(this IBufferWriter<byte> snapshot)
snapshot.GetSpan(1)[0] = (byte)'\n';
snapshot.Advance(1);
}

public static void AppendLine(this IBufferWriter<byte> snapshot, bool appendWhenTrue)
{
if (!appendWhenTrue)
{
return;
}

snapshot.GetSpan(1)[0] = (byte)'\n';
snapshot.Advance(1);
}

public static void AppendSeparator(this IBufferWriter<byte> snapshot)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,43 @@ internal sealed class OperationResultSnapshotValueFormatter : SnapshotValueForma
{
protected override void Format(IBufferWriter<byte> snapshot, OperationResult value)
{
var next = false;

if(value.RequestIndex.HasValue)
{
snapshot.Append("RequestIndex: ");
snapshot.Append(value.RequestIndex.Value.ToString());
next = true;
}

if(value.VariableIndex.HasValue)
{
snapshot.AppendLine(appendWhenTrue: next);
snapshot.Append("VariableIndex: ");
snapshot.Append(value.VariableIndex.Value.ToString());
next = true;
}

if (value.Data.ValueKind is JsonValueKind.Object)
{
snapshot.Append("Data:");
snapshot.AppendLine();
snapshot.AppendLine(appendWhenTrue: next);
snapshot.Append("Data: ");
snapshot.Append(value.Data.ToString());
next = true;
}

if (value.Errors.ValueKind is JsonValueKind.Array)
{
snapshot.Append("Errors:");
snapshot.AppendLine();
snapshot.AppendLine(appendWhenTrue: next);
snapshot.Append("Errors: ");
snapshot.Append(value.Errors.ToString());
next = true;
}

if (value.Extensions.ValueKind is JsonValueKind.Object)
{
snapshot.Append("Extensions:");
snapshot.AppendLine();
snapshot.AppendLine(appendWhenTrue: next);
snapshot.Append("Extensions: ");
snapshot.Append(value.Extensions.ToString());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public async Task Subgraph_SDL()
// assert
Assert.IsType<ObjectResult>(
Assert.IsType<ObjectResult>(
Assert.IsType<QueryResult>(result).Data)
Assert.IsType<OperationResult>(result).Data)
.GetValueOrDefault("_service"))
.GetValueOrDefault("sdl")
.MatchSnapshot();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public async Task Subgraph_SDL()
""");

// assert
var queryResult = Assert.IsType<QueryResult>(result);
var queryResult = Assert.IsType<OperationResult>(result);
var data = Assert.IsType<ObjectResult>(queryResult.Data);
var service = Assert.IsType<ObjectResult>(data.GetValueOrDefault("_service"));
service.GetValueOrDefault("sdl").MatchSnapshot();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class DefaultHttpRequestInterceptor : IHttpRequestInterceptor
public virtual ValueTask OnCreateAsync(
HttpContext context,
IRequestExecutor requestExecutor,
IQueryRequestBuilder requestBuilder,
OperationRequestBuilder requestBuilder,
CancellationToken cancellationToken)
{
var userState = new UserState(context.User);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ public class DefaultSocketSessionInterceptor : ISocketSessionInterceptor
public virtual ValueTask OnRequestAsync(
ISocketSession session,
string operationSessionId,
IQueryRequestBuilder requestBuilder,
OperationRequestBuilder requestBuilder,
CancellationToken cancellationToken = default)
{
var context = session.Connection.HttpContext;
var userState = new UserState(context.User);
var serviceScopeFactory = session.Connection.RequestServices.GetService<IServiceScopeFactory>();

requestBuilder.TryAddGlobalState(nameof(IServiceScopeFactory), serviceScopeFactory);
requestBuilder.TryAddGlobalState(nameof(CancellationToken), session.Connection.RequestAborted);
requestBuilder.TryAddGlobalState(nameof(HttpContext), context);
Expand All @@ -47,10 +47,10 @@ public class DefaultSocketSessionInterceptor : ISocketSessionInterceptor
return default;
}

public virtual ValueTask<IQueryResult> OnResultAsync(
public virtual ValueTask<IOperationResult> OnResultAsync(
ISocketSession session,
string operationSessionId,
IQueryResult result,
IOperationResult result,
CancellationToken cancellationToken = default)
=> new(result);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public DelegateHttpRequestInterceptor(HttpRequestInterceptorDelegate interceptor
public override async ValueTask OnCreateAsync(
HttpContext context,
IRequestExecutor requestExecutor,
IQueryRequestBuilder requestBuilder,
OperationRequestBuilder requestBuilder,
CancellationToken cancellationToken)
{
await _interceptor(context, requestExecutor, requestBuilder, cancellationToken);
Expand Down
20 changes: 10 additions & 10 deletions src/HotChocolate/AspNetCore/src/AspNetCore/ErrorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ public static IError NoSupportedAcceptMediaType()
.SetCode(ErrorCodes.Server.NoSupportedAcceptMediaType)
.Build();

public static IQueryResult TypeNameIsEmpty()
=> QueryResultBuilder.CreateError(
public static IOperationResult TypeNameIsEmpty()
=> OperationResultBuilder.CreateError(
new Error(
ErrorHelper_TypeNameIsEmpty,
code: ErrorCodes.Server.TypeParameterIsEmpty));

public static IQueryResult InvalidTypeName(string typeName)
=> QueryResultBuilder.CreateError(
public static IOperationResult InvalidTypeName(string typeName)
=> OperationResultBuilder.CreateError(
new Error(
ErrorHelper_InvalidTypeName,
code: ErrorCodes.Server.InvalidTypeName,
Expand All @@ -41,8 +41,8 @@ public static IQueryResult InvalidTypeName(string typeName)
{ nameof(typeName), typeName },
}));

public static IQueryResult TypeNotFound(string typeName)
=> QueryResultBuilder.CreateError(
public static IOperationResult TypeNotFound(string typeName)
=> OperationResultBuilder.CreateError(
new Error(
string.Format(ErrorHelper_TypeNotFound, typeName),
code: ErrorCodes.Server.TypeDoesNotExist,
Expand All @@ -51,8 +51,8 @@ public static IQueryResult TypeNotFound(string typeName)
{ nameof(typeName), typeName },
}));

public static IQueryResult InvalidAcceptMediaType(string headerValue)
=> QueryResultBuilder.CreateError(
public static IOperationResult InvalidAcceptMediaType(string headerValue)
=> OperationResultBuilder.CreateError(
new Error(
string.Format(ErrorHelper_InvalidAcceptMediaType, headerValue),
code: ErrorCodes.Server.InvalidAcceptHeaderValue,
Expand All @@ -61,8 +61,8 @@ public static IQueryResult InvalidAcceptMediaType(string headerValue)
{ nameof(headerValue), headerValue },
}));

public static IQueryResult MultiPartRequestPreflightRequired()
=> QueryResultBuilder.CreateError(
public static IOperationResult MultiPartRequestPreflightRequired()
=> OperationResultBuilder.CreateError(
new Error(
ErrorHelper_MultiPartRequestPreflightRequired,
code: ErrorCodes.Server.MultiPartPreflightRequired));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public AcceptHeaderResult(string headerValue)

public AcceptMediaType[] AcceptMediaTypes { get; }

public IQueryResult? ErrorResult { get; }
public IOperationResult? ErrorResult { get; }

[MemberNotNullWhen(true, nameof(ErrorResult))]
public bool HasError { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public sealed class HttpMultipartMiddleware : HttpPostMiddlewareBase
private const string _operations = "operations";
private const string _map = "map";
private readonly FormOptions _formOptions;
private readonly IQueryResult _multipartRequestError = MultiPartRequestPreflightRequired();
private readonly IOperationResult _multipartRequestError = MultiPartRequestPreflightRequired();

public HttpMultipartMiddleware(
HttpRequestDelegate next,
Expand Down Expand Up @@ -185,7 +185,7 @@ private static HttpMultipartRequest ParseMultipartRequest(IFormCollection form)
GraphQLRequest request,
IDictionary<string, IFile> fileMap)
{
if (!(request.Variables is Dictionary<string, object?> mutableVariables))
if (request.Variables is not [Dictionary<string, object?> mutableVariables,])
{
throw new InvalidOperationException(
HttpMultipartMiddleware_InsertFilesIntoRequest_VariablesImmutable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ protected async Task HandleRequestAsync(HttpContext context)
statusCode = HttpStatusCode.NotAcceptable;

var error = ErrorHelper.NoSupportedAcceptMediaType();
result = QueryResultBuilder.CreateError(error);
result = OperationResultBuilder.CreateError(error);
DiagnosticEvents.HttpRequestError(context, error);
goto HANDLE_RESULT;
}
Expand All @@ -120,15 +120,15 @@ protected async Task HandleRequestAsync(HttpContext context)
// GraphQL error result.
statusCode = HttpStatusCode.BadRequest;
var errors = errorHandler.Handle(ex.Errors);
result = QueryResultBuilder.CreateError(errors);
result = OperationResultBuilder.CreateError(errors);
DiagnosticEvents.ParserErrors(context, errors);
goto HANDLE_RESULT;
}
catch (Exception ex)
{
statusCode = HttpStatusCode.InternalServerError;
var error = errorHandler.CreateUnexpectedError(ex).Build();
result = QueryResultBuilder.CreateError(error);
result = OperationResultBuilder.CreateError(error);
DiagnosticEvents.HttpRequestError(context, error);
goto HANDLE_RESULT;
}
Expand All @@ -145,7 +145,7 @@ protected async Task HandleRequestAsync(HttpContext context)
{
statusCode = HttpStatusCode.BadRequest;
var error = errorHandler.Handle(ErrorHelper.RequestHasNoElements());
result = QueryResultBuilder.CreateError(error);
result = OperationResultBuilder.CreateError(error);
DiagnosticEvents.HttpRequestError(context, error);
break;
}
Expand Down Expand Up @@ -178,7 +178,7 @@ protected async Task HandleRequestAsync(HttpContext context)
{
var error = errorHandler.Handle(ErrorHelper.InvalidRequest());
statusCode = HttpStatusCode.BadRequest;
result = QueryResultBuilder.CreateError(error);
result = OperationResultBuilder.CreateError(error);
DiagnosticEvents.HttpRequestError(context, error);
}

Expand Down Expand Up @@ -221,7 +221,7 @@ protected async Task HandleRequestAsync(HttpContext context)
{
var error = errorHandler.Handle(ErrorHelper.InvalidRequest());
statusCode = HttpStatusCode.BadRequest;
result = QueryResultBuilder.CreateError(error);
result = OperationResultBuilder.CreateError(error);
DiagnosticEvents.HttpRequestError(context, error);
}
break;
Expand All @@ -231,7 +231,7 @@ protected async Task HandleRequestAsync(HttpContext context)
{
// This allows extensions to throw GraphQL exceptions in the GraphQL interceptor.
statusCode = null; // we let the serializer determine the status code.
result = QueryResultBuilder.CreateError(ex.Errors);
result = OperationResultBuilder.CreateError(ex.Errors);

foreach (var error in ex.Errors)
{
Expand All @@ -242,7 +242,7 @@ protected async Task HandleRequestAsync(HttpContext context)
{
statusCode = HttpStatusCode.InternalServerError;
var error = errorHandler.CreateUnexpectedError(ex).Build();
result = QueryResultBuilder.CreateError(error);
result = OperationResultBuilder.CreateError(error);
DiagnosticEvents.HttpRequestError(context, error);
}

Expand All @@ -262,7 +262,7 @@ protected async Task HandleRequestAsync(HttpContext context)
// to the HTTP response stream.
Debug.Assert(result is not null, "No GraphQL result was created.");

if (result is IQueryResult queryResult)
if (result is IOperationResult queryResult)
{
formatScope = DiagnosticEvents.FormatHttpResponse(context, queryResult);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ namespace HotChocolate.AspNetCore;
public delegate ValueTask HttpRequestInterceptorDelegate(
HttpContext context,
IRequestExecutor requestExecutor,
IQueryRequestBuilder requestBuilder,
OperationRequestBuilder requestBuilder,
CancellationToken cancellationToken);
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ public interface IHttpRequestInterceptor
ValueTask OnCreateAsync(
HttpContext context,
IRequestExecutor requestExecutor,
IQueryRequestBuilder requestBuilder,
OperationRequestBuilder requestBuilder,
CancellationToken cancellationToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public interface ISocketSessionInterceptor
ValueTask OnRequestAsync(
ISocketSession session,
string operationSessionId,
IQueryRequestBuilder requestBuilder,
OperationRequestBuilder requestBuilder,
CancellationToken cancellationToken = default);

/// <summary>
Expand All @@ -69,10 +69,10 @@ public interface ISocketSessionInterceptor
/// <returns>
/// Returns the result that shall be send to the client.
/// </returns>
ValueTask<IQueryResult> OnResultAsync(
ValueTask<IOperationResult> OnResultAsync(
ISocketSession session,
string operationSessionId,
IQueryResult result,
IOperationResult result,
CancellationToken cancellationToken = default);

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public void ParserErrors(HttpContext context, IReadOnlyList<IError> errors)
}
}

public IDisposable FormatHttpResponse(HttpContext context, IQueryResult result)
public IDisposable FormatHttpResponse(HttpContext context, IOperationResult result)
{
var scopes = new IDisposable[_listeners.Length];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public interface IServerDiagnosticEvents
/// <returns>
/// A scope that will be disposed when GraphQL query result is written to the response stream.
/// </returns>
IDisposable FormatHttpResponse(HttpContext context, IQueryResult result);
IDisposable FormatHttpResponse(HttpContext context, IOperationResult result);

/// <summary>
/// Called when starting to establish a GraphQL WebSocket session.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void ParserErrors(HttpContext context, IReadOnlyList<IError> errors)
{
}

public IDisposable FormatHttpResponse(HttpContext context, IQueryResult result) => EmptyScope;
public IDisposable FormatHttpResponse(HttpContext context, IOperationResult result) => EmptyScope;

public IDisposable WebSocketSession(HttpContext context) => EmptyScope;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public virtual void ParserErrors(HttpContext context, IReadOnlyList<IError> erro
}

/// <inheritdoc />
public virtual IDisposable FormatHttpResponse(HttpContext context, IQueryResult result)
public virtual IDisposable FormatHttpResponse(HttpContext context, IOperationResult result)
=> EmptyScope;

/// <inheritdoc />
Expand Down
Loading
Loading