You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am trying to implement an SLA mechanism for GraphQL queries, where we can assign an SLA value (in milliseconds) to a particular query. Then, using the SLA value, I'd like to enrich our request telemetry so that we have values to compare: actual request execution and assumed SLA.
My initial idea is to:
Add a custom extension to IObjectFieldDescriptor which adds SLA to particular field definition. For example:
descriptor.Field("myField")
...
.UseSla(100);
public static IObjectFieldDescriptor UseSla(
this IObjectFieldDescriptor descriptor,
int milliseconds)
{
if(!descriptor.Extend().Definition.ContextData.ContainsKey("SLA"))
descriptor.Extend().Definition.ContextData.Add("SLA", milliseconds);
return descriptor;
}
use IHttpRequestInterceptor to read the request SLA and enrich the request telemetry. Here, I've a problem, because it's hard for me to know what fields are included in the query. The only way I found is the following:
public override ValueTask OnCreateAsync(HttpContext context,
IRequestExecutor requestExecutor, IQueryRequestBuilder requestBuilder,
CancellationToken cancellationToken)
{
var request = requestBuilder.Create();
if (request.Query is QueryDocument document)
{
var sla = GetSla(requestExecutor, document);
if (sla.HasValue)
{
context.AddSla(sla.Value);
}
}
return base.OnCreateAsync(context, requestExecutor, requestBuilder,
cancellationToken);
}
private static int? GetSla(IRequestExecutor requestExecutor, QueryDocument document)
{
foreach (var node in document.Document.GetNodes())
{
var name = FindFieldName(node);
if (name != null)
{
var field = requestExecutor.Schema.QueryType.Fields[name];
if (field.ContextData.TryGetValue("SLA", out var @value) &&
int.TryParse(@value?.ToString(), out var sla))
{
return sla;
}
}
}
return null;
}
private static string FindFieldName(ISyntaxNode node)
{
if (node == null)
return null;
if (node.Kind == SyntaxKind.Field && node is FieldNode fieldNode)
return fieldNode.Name.Value;
foreach (var childNode in node.GetNodes())
{
var result = FindFieldName(childNode);
if (!string.IsNullOrWhiteSpace(result))
return result;
}
return null;
}
This solution seems to work but what I don't like is that I manually parse the document to find a field that has SLA applied.
Is there a better way to get metadata about the fields in the request ?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi,
I am trying to implement an SLA mechanism for GraphQL queries, where we can assign an SLA value (in milliseconds) to a particular query. Then, using the SLA value, I'd like to enrich our request telemetry so that we have values to compare: actual request execution and assumed SLA.
My initial idea is to:
IObjectFieldDescriptor
which adds SLA to particular field definition. For example:IHttpRequestInterceptor
to read the request SLA and enrich the request telemetry. Here, I've a problem, because it's hard for me to know what fields are included in the query. The only way I found is the following:This solution seems to work but what I don't like is that I manually parse the document to find a field that has SLA applied.
Is there a better way to get metadata about the fields in the request ?
Beta Was this translation helpful? Give feedback.
All reactions