Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,6 @@ dotnet_naming_style.end_in_async_style.required_suffix = Async

# dotnet_naming_rule.<namingRuleTitle>.severity = <value>
dotnet_naming_rule.async_methods_end_in_async.severity = warning

# ReSharper: Configure await
configure_await_analysis_mode = library
6 changes: 6 additions & 0 deletions GraphQL.Client.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ VisualStudioVersion = 16.0.28407.52
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{47C98B55-08F1-4428-863E-2C5C876DEEFE}"
ProjectSection(SolutionItems) = preProject
src\.editorconfig = src\.editorconfig
src\src.props = src\src.props
EndProjectSection
EndProject
Expand All @@ -14,6 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.gitignore = .gitignore
dotnet-tools.json = dotnet-tools.json
LICENSE.txt = LICENSE.txt
examples\GraphQL.Client.Example\Program.cs = examples\GraphQL.Client.Example\Program.cs
README.md = README.md
root.props = root.props
EndProjectSection
Expand Down Expand Up @@ -65,6 +67,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{89
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphQL.Client.Example", "examples\GraphQL.Client.Example\GraphQL.Client.Example.csproj", "{6B13B87D-1EF4-485F-BC5D-891E2F4DA6CD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{98D4DDDD-DE15-4997-B888-9BC806C7416C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -133,6 +137,7 @@ Global
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{E95A1258-F666-4D4E-9101-E0C46F6A3CB3} = {0B0EDB0F-FF67-4B78-A8DB-B5C23E1FEE8C}
{05CAF9B2-981E-40C0-AE31-5FA56E351F12} = {98D4DDDD-DE15-4997-B888-9BC806C7416C}
{87FC440E-6A4D-47D8-9EB2-416FC31CC4A6} = {47C98B55-08F1-4428-863E-2C5C876DEEFE}
{C212983F-67DB-44EB-BFB0-5DA75A86DF55} = {0B0EDB0F-FF67-4B78-A8DB-B5C23E1FEE8C}
{92107DF5-73DF-4371-8EB1-6734FED704AD} = {0B0EDB0F-FF67-4B78-A8DB-B5C23E1FEE8C}
Expand All @@ -146,6 +151,7 @@ Global
{0D307BAD-27AE-4A5D-8764-4AA2620B01E9} = {0B0EDB0F-FF67-4B78-A8DB-B5C23E1FEE8C}
{7FFFEC00-D751-4FFC-9FD4-E91858F9A1C5} = {47C98B55-08F1-4428-863E-2C5C876DEEFE}
{6B13B87D-1EF4-485F-BC5D-891E2F4DA6CD} = {89AD33AB-64F6-4F82-822F-21DF7A10CEC0}
{98D4DDDD-DE15-4997-B888-9BC806C7416C} = {63F75859-4698-4EDE-8B70-4ACBB8BC425A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {387AC1AC-F90C-4EF8-955A-04D495C75AF4}
Expand Down
2 changes: 2 additions & 0 deletions examples/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Configure await
configure_await_analysis_mode = disabled
12 changes: 6 additions & 6 deletions src/GraphQL.Client.LocalExecution/GraphQLLocalExecutionClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ public IObservable<GraphQLResponse<TResponse>> CreateSubscriptionStream<TRespons

private async Task<GraphQLResponse<TResponse>> ExecuteQueryAsync<TResponse>(GraphQLRequest request, CancellationToken cancellationToken)
{
var executionResult = await ExecuteAsync(request, cancellationToken);
return await ExecutionResultToGraphQLResponseAsync<TResponse>(executionResult, cancellationToken);
var executionResult = await ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
return await ExecutionResultToGraphQLResponseAsync<TResponse>(executionResult, cancellationToken).ConfigureAwait(false);
}
private async Task<IObservable<GraphQLResponse<TResponse>>> ExecuteSubscriptionAsync<TResponse>(GraphQLRequest request, CancellationToken cancellationToken = default)
{
var result = await ExecuteAsync(request, cancellationToken);
var result = await ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
var stream = ((SubscriptionExecutionResult)result).Streams?.Values.SingleOrDefault();

return stream == null
Expand All @@ -106,17 +106,17 @@ private async Task<ExecutionResult> ExecuteAsync(GraphQLRequest request, Cancell
options.Query = deserializedRequest?.Query;
options.Inputs = inputs;
options.CancellationToken = cancellationToken;
});
}).ConfigureAwait(false);

return result;
}

private async Task<GraphQLResponse<TResponse>> ExecutionResultToGraphQLResponseAsync<TResponse>(ExecutionResult executionResult, CancellationToken cancellationToken = default)
{
using var stream = new MemoryStream();
await _documentWriter.WriteAsync(stream, executionResult, cancellationToken);
await _documentWriter.WriteAsync(stream, executionResult, cancellationToken).ConfigureAwait(false);
stream.Seek(0, SeekOrigin.Begin);
return await Serializer.DeserializeFromUtf8StreamAsync<TResponse>(stream, cancellationToken);
return await Serializer.DeserializeFromUtf8StreamAsync<TResponse>(stream, cancellationToken).ConfigureAwait(false);
}

#endregion
Expand Down
41 changes: 10 additions & 31 deletions src/GraphQL.Client/GraphQLHttpClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Linq;
Expand All @@ -19,7 +18,6 @@ public class GraphQLHttpClient : IGraphQLClient
private GraphQLHttpWebSocket GraphQlHttpWebSocket => _lazyHttpWebSocket.Value;

private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private readonly ConcurrentDictionary<Tuple<GraphQLRequest, Type>, object> _subscriptionStreams = new ConcurrentDictionary<Tuple<GraphQLRequest, Type>, object>();

private readonly bool _disposeHttpClient = false;

Expand Down Expand Up @@ -85,9 +83,9 @@ public async Task<GraphQLResponse<TResponse>> SendQueryAsync<TResponse>(GraphQLR
if (Options.UseWebSocketForQueriesAndMutations ||
!(Options.WebSocketEndPoint is null) && Options.EndPoint is null ||
Options.EndPoint.HasWebSocketScheme())
return await GraphQlHttpWebSocket.SendRequest<TResponse>(request, cancellationToken);
return await GraphQlHttpWebSocket.SendRequest<TResponse>(request, cancellationToken).ConfigureAwait(false);

return await SendHttpRequestAsync<TResponse>(request, cancellationToken);
return await SendHttpRequestAsync<TResponse>(request, cancellationToken).ConfigureAwait(false);
}

/// <inheritdoc />
Expand All @@ -97,34 +95,15 @@ public Task<GraphQLResponse<TResponse>> SendMutationAsync<TResponse>(GraphQLRequ

/// <inheritdoc />
public IObservable<GraphQLResponse<TResponse>> CreateSubscriptionStream<TResponse>(GraphQLRequest request)
{
if (_disposed)
throw new ObjectDisposedException(nameof(GraphQLHttpClient));

var key = new Tuple<GraphQLRequest, Type>(request, typeof(TResponse));

if (_subscriptionStreams.ContainsKey(key))
return (IObservable<GraphQLResponse<TResponse>>)_subscriptionStreams[key];

var observable = GraphQlHttpWebSocket.CreateSubscriptionStream<TResponse>(request);

_subscriptionStreams.TryAdd(key, observable);
return observable;
}
=> CreateSubscriptionStream<TResponse>(request, null);

/// <inheritdoc />
public IObservable<GraphQLResponse<TResponse>> CreateSubscriptionStream<TResponse>(GraphQLRequest request, Action<Exception> exceptionHandler)
public IObservable<GraphQLResponse<TResponse>> CreateSubscriptionStream<TResponse>(GraphQLRequest request, Action<Exception>? exceptionHandler)
{
if (_disposed)
throw new ObjectDisposedException(nameof(GraphQLHttpClient));

var key = new Tuple<GraphQLRequest, Type>(request, typeof(TResponse));

if (_subscriptionStreams.ContainsKey(key))
return (IObservable<GraphQLResponse<TResponse>>)_subscriptionStreams[key];


var observable = GraphQlHttpWebSocket.CreateSubscriptionStream<TResponse>(request, exceptionHandler);
_subscriptionStreams.TryAdd(key, observable);
return observable;
}

Expand All @@ -140,24 +119,24 @@ public IObservable<GraphQLResponse<TResponse>> CreateSubscriptionStream<TRespons

private async Task<GraphQLHttpResponse<TResponse>> SendHttpRequestAsync<TResponse>(GraphQLRequest request, CancellationToken cancellationToken = default)
{
var preprocessedRequest = await Options.PreprocessRequest(request, this);
var preprocessedRequest = await Options.PreprocessRequest(request, this).ConfigureAwait(false);

using var httpRequestMessage = preprocessedRequest.ToHttpRequestMessage(Options, JsonSerializer);
using var httpResponseMessage = await HttpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
using var httpResponseMessage = await HttpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);

var contentStream = await httpResponseMessage.Content.ReadAsStreamAsync();
var contentStream = await httpResponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);

if (httpResponseMessage.IsSuccessStatusCode)
{
var graphQLResponse = await JsonSerializer.DeserializeFromUtf8StreamAsync<TResponse>(contentStream, cancellationToken);
var graphQLResponse = await JsonSerializer.DeserializeFromUtf8StreamAsync<TResponse>(contentStream, cancellationToken).ConfigureAwait(false);
return graphQLResponse.ToGraphQLHttpResponse(httpResponseMessage.Headers, httpResponseMessage.StatusCode);
}

// error handling
string content = null;
if (contentStream != null)
using (var sr = new StreamReader(contentStream))
content = await sr.ReadToEndAsync();
content = await sr.ReadToEndAsync().ConfigureAwait(false);

throw new GraphQLHttpRequestException(httpResponseMessage.StatusCode, httpResponseMessage.Headers, content);
}
Expand Down
Loading