Skip to content

Commit

Permalink
Merge pull request #972 from clement911/master
Browse files Browse the repository at this point in the history
Using SystemTextJson instead of JsonNet to extract leaky bucket state…
  • Loading branch information
clement911 authored Dec 14, 2023
2 parents 6cdd3df + 233241b commit 1373b65
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 24 deletions.
1 change: 1 addition & 0 deletions ShopifySharp.Tests/Graph_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class Graph_Tests : IClassFixture<Graph_Tests_Fixture>
public Graph_Tests(Graph_Tests_Fixture fixture)
{
_fixture = fixture;
_fixture.Service.SetExecutionPolicy(new LeakyBucketExecutionPolicy());
}

[Fact(DisplayName = "Lists orders using the GraphService")]
Expand Down
30 changes: 15 additions & 15 deletions ShopifySharp/Infrastructure/BucketStates/GraphQLBucketState.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Newtonsoft.Json.Linq;

namespace ShopifySharp
namespace ShopifySharp
{
public class GraphQLBucketState
{
Expand All @@ -14,24 +12,26 @@ public class GraphQLBucketState

public int? ActualQueryCost { get; private set; }

public static GraphQLBucketState Get(JToken response)
public static GraphQLBucketState Get(System.Text.Json.JsonDocument response)
{
var cost = response.SelectToken("extensions.cost");
if (cost == null)
if (!response.RootElement.TryGetProperty("extensions", out var extensions))
return null;
if (!extensions.TryGetProperty("cost", out var cost))
return null;

var throttleStatus = cost["throttleStatus"];
int maximumAvailable = (int)throttleStatus["maximumAvailable"];
int restoreRate = (int)throttleStatus["restoreRate"];
int currentlyAvailable = (int)throttleStatus["currentlyAvailable"];
int requestedQueryCost = (int)cost["requestedQueryCost"];
int? actualQueryCost = (int?)cost["actualQueryCost"];//actual query cost is null if THROTTLED
int requestedQueryCost = cost.GetProperty("requestedQueryCost").GetInt32();
int? actualQueryCost = cost.TryGetProperty("actualQueryCost", out var actualQueryCostElt) && actualQueryCostElt.ValueKind != System.Text.Json.JsonValueKind.Null ? actualQueryCostElt.GetInt32() : null;//actual query cost is null if THROTTLED

var throttleStatus = cost.GetProperty("throttleStatus");
decimal maximumAvailable = throttleStatus.GetProperty("maximumAvailable").GetDecimal();
decimal restoreRate = throttleStatus.GetProperty("restoreRate").GetDecimal();
decimal currentlyAvailable = throttleStatus.GetProperty("currentlyAvailable").GetDecimal();

return new GraphQLBucketState
{
MaxAvailable = maximumAvailable,
RestoreRate = restoreRate,
CurrentlyAvailable = currentlyAvailable,
MaxAvailable = (int)maximumAvailable,
RestoreRate = (int)restoreRate,
CurrentlyAvailable = (int)currentlyAvailable,
RequestedQueryCost = requestedQueryCost,
ActualQueryCost = actualQueryCost,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,16 @@ public async Task<RequestResult<T>> Run<T>(CloneableRequestMessage baseRequest,
await bucket.WaitForAvailableGraphQLAsync(graphqlQueryCost.Value, cancellationToken);

var graphRes = await executeRequestAsync(request);
var json = graphRes.Result as JToken;
if (graphRes.Result is System.Text.Json.JsonDocument jsonDoc)
json = JToken.Parse(jsonDoc.RootElement.ToString());
var jsonDoc = graphRes.Result switch
{
System.Text.Json.JsonDocument systemTextJsonDoc => systemTextJsonDoc,
JToken jsonNetDoc => System.Text.Json.JsonDocument.Parse(jsonNetDoc.ToString(Newtonsoft.Json.Formatting.None)),
_ => throw new Exception($"Unexpected non json result of type {graphRes.Response.GetType().Name} for GraphQL Admin API")
};

if (bucket != null)
{
var graphBucketState = graphRes.GetGraphQLBucketState(json);
var graphBucketState = graphRes.GetGraphQLBucketState(jsonDoc);
if (graphBucketState != null)
{
int actualQueryCost = graphBucketState.ActualQueryCost ?? graphqlQueryCost.Value;//actual query cost is null if THROTTLED
Expand All @@ -84,10 +87,10 @@ public async Task<RequestResult<T>> Run<T>(CloneableRequestMessage baseRequest,
}
}

if (json.SelectToken("errors")
?.Children()
.Any(r => r.SelectToken("extensions.code")?.Value<string>() == "THROTTLED")
== true)
if (jsonDoc.RootElement.TryGetProperty("errors", out var errors) &&
errors.EnumerateArray().Any(error => error.TryGetProperty("extensions", out var extensions) &&
extensions.TryGetProperty("code", out var code) &&
code.GetString() == "THROTTLED"))
{
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
break;
Expand Down
2 changes: 1 addition & 1 deletion ShopifySharp/Infrastructure/RequestResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public RestBucketState GetRestBucketState()
return RestBucketState.Get(this.Response);
}

public GraphQLBucketState GetGraphQLBucketState(JToken response)
public GraphQLBucketState GetGraphQLBucketState(System.Text.Json.JsonDocument response)
{
return GraphQLBucketState.Get(response);
}
Expand Down
8 changes: 8 additions & 0 deletions ShopifySharp/Services/Graph/GraphService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ public virtual Task<TResult> SendAsync<TResult>(string graphqlQuery, int? graphq
return SendAsync<TResult>(new GraphRequest { query = graphqlQuery }, graphqlQueryCost, cancellationToken);
}

/// <summary>
/// Issue a single value query and return the value as an strongly typed object.
/// Use a type from the ShopifySharp.GraphQL namespace
/// </summary>
/// <typeparam name="TResult">Use a type from the ShopifySharp.GraphQL namespace</typeparam>
/// <param name="request"></param>
/// <param name="graphqlQueryCost"></param>
/// <param name="cancellationToken"></param>
public virtual async Task<TResult> SendAsync<TResult>(GraphRequest request, int? graphqlQueryCost = null, CancellationToken cancellationToken = default)
where TResult : class
{
Expand Down

0 comments on commit 1373b65

Please sign in to comment.