Skip to content

Commit 77c67d6

Browse files
committed
Add EnableMetrics option
1 parent 4f6c82c commit 77c67d6

File tree

4 files changed

+71
-77
lines changed

4 files changed

+71
-77
lines changed

samples/Website/App_Start/UmbracoEvents.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ public class UmbracoEvents : ApplicationEventHandler
99
{
1010
protected override void ApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
1111
{
12-
UmbracoDefaultOwinStartup.MiddlewareConfigured += (sender, e) => e.AppBuilder.UseUmbracoGraphQL(applicationContext);
12+
UmbracoDefaultOwinStartup.MiddlewareConfigured += (sender, e) => e.AppBuilder.UseUmbracoGraphQL(applicationContext, new GraphQLServerOptions()
13+
{
14+
EnableMetrics = true,
15+
Debug = true
16+
});
1317
}
1418
}
1519
}

src/Our.Umbraco.GraphQL/Types/ComplexGraphTypeOfIPublishedContentExtensions.cs

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -116,24 +116,11 @@ public static IEnumerable<TSource> Filter<TSource, TParent>(
116116
{
117117
var orderByArg = context.GetArgument<IEnumerable<object>>("orderBy")?.OfType<OrderBy>();
118118

119-
var executionContext = new ExecutionContext
120-
{
121-
Schema = context.Schema,
122-
CancellationToken = context.CancellationToken,
123-
Document = context.Document,
124-
Errors = context.Errors,
125-
Fragments = context.Fragments,
126-
Metrics = context.Metrics,
127-
Operation = context.Operation,
128-
RootValue = context.RootValue,
129-
UserContext = context.UserContext,
130-
Variables = context.Variables
131-
};
132119
if (context.Arguments.TryGetValue("filter", out object filterArg) && filterArg != null)
133120
{
134121
var rootFilter = ((IDictionary<string, object>)filterArg).First();
135122
var filterType = (IComplexGraphType)context.FieldDefinition.Arguments.Find("filter").ResolvedType;
136-
var filter = ResolveFilter(filterType, rootFilter, context.ParentType, executionContext);
123+
var filter = ResolveFilter(filterType, rootFilter, context);
137124

138125
source = source.Where(x => filter.IsSatisfiedBy(x));
139126
}
@@ -145,6 +132,7 @@ public static IEnumerable<TSource> Filter<TSource, TParent>(
145132

146133
object KeySelector(TSource item)
147134
{
135+
var path = (context.Path ?? new[] { "order" }).Concat(new[] { fieldType.Name });
148136
var value = fieldType.Resolver.Resolve(new ResolveFieldContext
149137
{
150138
FieldName = order.Field,
@@ -162,6 +150,7 @@ object KeySelector(TSource item)
162150
CancellationToken = context.CancellationToken,
163151
Metrics = context.Metrics,
164152
Errors = context.Errors,
153+
Path = path
165154
});
166155
if (value is Task<object> task)
167156
{
@@ -188,31 +177,33 @@ object KeySelector(TSource item)
188177
return source;
189178
}
190179

191-
internal static IFilter ResolveFilter(
180+
internal static IFilter ResolveFilter<TParentType>(
192181
this IComplexGraphType filterType,
193182
KeyValuePair<string, object> value,
194-
IObjectGraphType parentType,
195-
ExecutionContext executionContext)
183+
ResolveFieldContext<TParentType> context)
196184
{
185+
var path = (context.Path ?? new[] { "filter" }).Concat(new[] { value.Key });
197186
var field = filterType.Fields.First(x => x.Name == value.Key);
187+
198188
return (IFilter)field.Resolver.Resolve(
199189
new ResolveFieldContext
200190
{
201191
FieldName = field.Name,
202192
FieldAst = new Field(null, new NameNode(field.Name)),
203193
FieldDefinition = field,
204-
ParentType = parentType,
194+
ParentType = context.ParentType,
205195
Source = value.Value,
206-
Schema = executionContext.Schema,
207-
Document = executionContext.Document,
208-
Fragments = executionContext.Fragments,
209-
RootValue = executionContext.RootValue,
210-
UserContext = executionContext.UserContext,
211-
Operation = executionContext.Operation,
212-
Variables = executionContext.Variables,
213-
CancellationToken = executionContext.CancellationToken,
214-
Metrics = executionContext.Metrics,
215-
Errors = executionContext.Errors,
196+
Schema = context.Schema,
197+
Document = context.Document,
198+
Fragments = context.Fragments,
199+
RootValue = context.RootValue,
200+
UserContext = context.UserContext,
201+
Operation = context.Operation,
202+
Variables = context.Variables,
203+
CancellationToken = context.CancellationToken,
204+
Metrics = context.Metrics,
205+
Errors = context.Errors,
206+
Path = path,
216207
}
217208
);
218209
}
@@ -488,6 +479,7 @@ protected void AddFilterField(
488479
{
489480
object ResolveValue(object source)
490481
{
482+
var path = (context.Path ?? new [] { "filter" }).Concat(new[] { fieldType.Name });
491483
var value = fieldType.Resolver.Resolve(
492484
new ResolveFieldContext
493485
{
@@ -506,6 +498,7 @@ object ResolveValue(object source)
506498
CancellationToken = context.CancellationToken,
507499
Metrics = context.Metrics,
508500
Errors = context.Errors,
501+
Path = path
509502
}
510503
);
511504

@@ -533,28 +526,14 @@ protected void AddFilterField(
533526
description,
534527
resolve: context =>
535528
{
536-
var executionContext = new ExecutionContext
537-
{
538-
Schema = context.Schema,
539-
CancellationToken = context.CancellationToken,
540-
Document = context.Document,
541-
Errors = context.Errors,
542-
Fragments = context.Fragments,
543-
Metrics = context.Metrics,
544-
Operation = context.Operation,
545-
RootValue = context.RootValue,
546-
UserContext = context.UserContext,
547-
Variables = context.Variables
548-
};
549-
550529
var value = (IEnumerable<object>)context.Source;
551530
var subFilters = new List<IFilter>();
552531
foreach (var obj in value)
553532
{
554533
var dict = (IDictionary<string, object>)obj;
555534
foreach (KeyValuePair<string, object> pair in dict)
556535
{
557-
subFilters.Add(this.ResolveFilter(pair, (IObjectGraphType)parentType, executionContext));
536+
subFilters.Add(this.ResolveFilter(pair, context));
558537
}
559538
}
560539
return resolveFilter(subFilters);

src/Our.Umbraco.GraphQL/Web/GraphQLMiddleware.cs

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
using GraphQL;
66
using GraphQL.Conversion;
77
using GraphQL.Http;
8+
using GraphQL.Instrumentation;
89
using GraphQL.Utilities;
910
using Microsoft.Owin;
1011
using Our.Umbraco.GraphQL.Schema;
12+
using StackExchange.Profiling;
1113
using Umbraco.Core;
1214
using Umbraco.Core.Cache;
1315
using Umbraco.Web;
@@ -18,6 +20,8 @@ public class GraphQLMiddleware : OwinMiddleware
1820
{
1921
private readonly ApplicationContext _applicationContext;
2022
private readonly GraphQLServerOptions _options;
23+
private readonly DocumentExecuter _documentExecutor;
24+
private readonly DocumentWriter _documentWriter;
2125

2226
public GraphQLMiddleware(
2327
OwinMiddleware next,
@@ -26,6 +30,8 @@ public GraphQLMiddleware(
2630
{
2731
_applicationContext = applicationContext ?? throw new ArgumentNullException(nameof(applicationContext));
2832
_options = options ?? throw new ArgumentNullException(nameof(options));
33+
_documentExecutor = new DocumentExecuter();
34+
_documentWriter = new DocumentWriter();
2935
}
3036

3137
public override async Task Invoke(IOwinContext context)
@@ -62,54 +68,59 @@ public override async Task Invoke(IOwinContext context)
6268
return;
6369
}
6470

65-
IEnumerable<Task<ExecutionResult>> requests = request.Select(requestParams =>
71+
IEnumerable<Task<ExecutionResult>> requests = request.Select(async requestParams =>
6672
{
67-
try
68-
{
69-
string query = requestParams.Query;
70-
string operationName = requestParams.OperationName;
71-
Inputs variables = requestParams.Variables;
72-
73-
return new DocumentExecuter()
74-
.ExecuteAsync(x =>
73+
string query = requestParams.Query;
74+
string operationName = requestParams.OperationName;
75+
Inputs variables = requestParams.Variables;
76+
77+
var start = DateTime.Now;
78+
79+
var result = await _documentExecutor
80+
.ExecuteAsync(x =>
81+
{
82+
x.CancellationToken = context.Request.CallCancelled;
83+
//x.ComplexityConfiguration = new ComplexityConfiguration();
84+
x.ExposeExceptions = _options.Debug;
85+
if (_options.EnableMetrics)
7586
{
76-
x.CancellationToken = context.Request.CallCancelled;
77-
//x.ComplexityConfiguration = new ComplexityConfiguration();
78-
x.ExposeExceptions = _options.Debug;
79-
//x.FieldMiddleware.Use<InstrumentFieldsMiddleware>();
80-
x.FieldNameConverter = new DefaultFieldNameConverter();
81-
x.Inputs = variables;
82-
x.OperationName = operationName;
83-
x.Query = query;
84-
//x.Root =
85-
x.Schema = schema;
86-
x.UserContext = new UmbracoGraphQLContext(
87-
context.Request.Uri,
88-
_applicationContext,
89-
UmbracoContext.Current,
90-
_options
91-
);
92-
});
93-
}
94-
catch (Exception)
87+
x.EnableMetrics = true;
88+
x.FieldMiddleware.Use<InstrumentFieldsMiddleware>();
89+
}
90+
x.FieldNameConverter = new DefaultFieldNameConverter();
91+
x.Inputs = variables;
92+
x.OperationName = operationName;
93+
x.Query = query;
94+
//x.Root =
95+
x.Schema = schema;
96+
x.UserContext = new UmbracoGraphQLContext(
97+
context.Request.Uri,
98+
_applicationContext,
99+
UmbracoContext.Current,
100+
_options
101+
);
102+
});
103+
104+
if (_options.EnableMetrics && result.Errors == null)
95105
{
96-
throw;
106+
result.EnrichWithApolloTracing(start);
97107
}
108+
109+
return result;
98110
});
99111

100112
var responses = await Task.WhenAll(requests);
101113

102114
context.Response.ContentType = "application/json";
103115

104-
var writer = new DocumentWriter();
105116
if (false == request.IsBatched)
106117
{
107-
var response = writer.Write(responses[0]);
118+
var response = _documentWriter.Write(responses[0]);
108119
await context.Response.WriteAsync(response);
109120
}
110121
else
111122
{
112-
var response = writer.Write(responses);
123+
var response = _documentWriter.Write(responses);
113124
await context.Response.WriteAsync(response);
114125
}
115126
}

src/Our.Umbraco.GraphQL/Web/GraphQLServerOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public GraphQLServerOptions(ICorsPolicyProvider corsPolicyProvder)
4949
public bool Debug { get; set; }
5050
//public bool ExposeGraphiQL { get; set; } = true;
5151
//public bool EnableLogin { get; set; } = false;
52-
//public bool EnableMetrics { get; set; } = false;
52+
public bool EnableMetrics { get; set; } = false;
5353
//public bool ExposeSchema { get; set; } = true;
5454
public Func<IContentTypeBase, string> PublishedContentNameResolver { get; set; } = Conventions.NameResolvers.PascalCase;
5555
}

0 commit comments

Comments
 (0)