/// <summary> /// Adds or replaces the source data supplied to the field request. /// </summary> /// <param name="sourceData">The source data.</param> /// <param name="path">An optional to mock where in the graph query the data originated.</param> /// <returns>MockFieldRequest.</returns> public FieldContextBuilder AddSourceData(object sourceData, SourcePath path = null) { path = path ?? SourcePath.None; var item = new GraphDataItem(_mockInvocationContext.Object, sourceData, path); var dataSource = new GraphFieldDataSource(sourceData, path, item); _mockRequest.Setup(x => x.DataSource).Returns(dataSource); return(this); }
private void CreateEdge(GraphDataItem item) { var edge = new Edge { ID = item.EdgeID, SourceVertex = EnsureVertex(item.SourceVertexID), TargetVertex = EnsureVertex(item.TargetVertexID), Cost = item.Cost, IsReverse = false, DataItem = item, }; edge.SourceVertex.Neighbours.Add(edge.TargetVertex); { var key = GetKey(edge.SourceVertex.ID, edge.TargetVertex.ID); if (!mEdges.ContainsKey(key)) { mEdges.Add(key, edge); } else if (mEdges[key].Cost > edge.Cost) { mEdges[key] = edge; } } edge = new Edge { ID = item.EdgeID, SourceVertex = EnsureVertex(item.TargetVertexID), TargetVertex = EnsureVertex(item.SourceVertexID), Cost = item.ReverseCost, IsReverse = true, DataItem = item, }; edge.SourceVertex.Neighbours.Add(edge.TargetVertex); { var key = GetKey(edge.SourceVertex.ID, edge.TargetVertex.ID); if (!mEdges.ContainsKey(key)) { mEdges.Add(key, edge); } else if (mEdges[key].Cost > edge.Cost) { mEdges[key] = edge; } } }
private void OnTimerTick(object sender, EventArgs e) { if (GraphCanvas.ActualWidth == 0 || GraphCanvas.ActualHeight == 0) { return; } if (m_updateGraphBorder) { UpdateGraphBorders(); m_updateGraphBorder = false; } DateTime now = DateTime.Now; List <GraphDataItem> tempList = new List <GraphDataItem>(m_graphData); foreach (GraphDataItem dataItem in tempList) { if (m_graphData.Count == 1) { break; } TimeSpan timeElapsed = now - dataItem.time; if (timeElapsed.TotalMilliseconds > GRAPH_TIME_LENGTH_MSEC) { GraphCanvas.Children.Remove(dataItem.graphBar); m_graphData.Remove(dataItem); } } double xScale = (GraphCanvas.ActualWidth - GRAPH_X_MARGIN * 2.0) / GRAPH_TIME_LENGTH_MSEC; double yScale = (GraphCanvas.ActualHeight - GRAPH_Y_MARGIN * 2.0) / (m_yMax - m_yMin); double xOffset = GraphCanvas.ActualWidth - 2.0 * GRAPH_X_MARGIN; Debug.Assert(xScale > 0.0); Debug.Assert(yScale > 0.0); Debug.Assert(xOffset > 0.0); for (int i = m_graphData.Count - 1; i >= 0; --i) { GraphDataItem graphDataItem = m_graphData[i]; DateTime endTime = (i == m_graphData.Count - 1) ? now : m_graphData[i + 1].time; double duration = (endTime - graphDataItem.time).TotalMilliseconds; graphDataItem.graphBar.Width = Math.Min(duration * xScale, GRAPH_TIME_LENGTH_MSEC * xScale); graphDataItem.graphBar.Width = Math.Min(graphDataItem.graphBar.Width, xOffset); graphDataItem.graphBar.Height = graphDataItem.val * yScale; graphDataItem.graphBar.SetValue(Canvas.LeftProperty, GRAPH_X_MARGIN + xOffset - graphDataItem.graphBar.Width); graphDataItem.graphBar.SetValue(Canvas.TopProperty, GraphCanvas.ActualHeight - GRAPH_Y_MARGIN - graphDataItem.graphBar.Height); if (!GraphCanvas.Children.Contains(graphDataItem.graphBar)) { GraphCanvas.Children.Insert(GraphCanvas.Children.Count - 1, graphDataItem.graphBar); } xOffset = xOffset - graphDataItem.graphBar.Width; if (xOffset < Double.Epsilon) { break; } } }
private async Task ExecuteOperation(GraphQueryExecutionContext context) { // create a cancelation sourc irrespective of the required timeout for exeucting this operation // this allows for indication of why a task was canceled (timeout or other user driven reason) // vs just "it was canceled" which allows for tighter error messages in the response. var operation = context.QueryOperation; var fieldInvocations = new List <FieldPipelineInvocation>(); // Convert the supplied variable values to usable objects of the type expression // of the chosen operation var variableResolver = new ResolvedVariableGenerator(_schema, operation); var variableData = variableResolver.Resolve(context.Request.VariableData); var cancelSource = new CancellationTokenSource(); try { // begin a field execution pipeline for each top level field foreach (var invocationContext in operation.FieldContexts) { var path = new SourcePath(); path.AddFieldName(invocationContext.Name); object dataSourceValue; // fetch the source data value to use for the field invocation // attempt to retrieve from the master context if it was supplied by the pipeline // invoker, otherwise generate a root source if (!context.DefaultFieldSources.TryRetrieveSource(invocationContext.Field, out dataSourceValue)) { dataSourceValue = this.GenerateRootSourceData(operation.OperationType); } var topLevelDataItem = new GraphDataItem(invocationContext, dataSourceValue, path); var sourceData = new GraphFieldDataSource(dataSourceValue, path, topLevelDataItem); var fieldRequest = new GraphFieldRequest( invocationContext, sourceData, new SourceOrigin(invocationContext.Origin.Location, path), context.Items); var fieldContext = new GraphFieldExecutionContext( context, fieldRequest, variableData, context.DefaultFieldSources); var fieldTask = _fieldExecutionPipeline.InvokeAsync(fieldContext, cancelSource.Token); var pipelineInvocation = new FieldPipelineInvocation() { Task = fieldTask, DataItem = topLevelDataItem, FieldContext = fieldContext, }; fieldInvocations.Add(pipelineInvocation); // top level mutation operatons must be executed in sequential order // https://graphql.github.io/graphql-spec/June2018/#sec-Mutation if (_awaitEachTask || operation.OperationType == GraphCollection.Mutation) { await fieldTask.ConfigureAwait(false); } } // await all the outstanding tasks or a configured timeout var fieldPipelineTasksWrapper = Task.WhenAll(fieldInvocations.Select(x => x.Task)); var timeOutTask = Task.Delay(_timeoutMs, cancelSource.Token); var completedTask = await Task.WhenAny(fieldPipelineTasksWrapper, timeOutTask).ConfigureAwait(false); var isTimedOut = completedTask == timeOutTask; var cancelationWasRequested = cancelSource.IsCancellationRequested; if (!isTimedOut) { // Field resolutions completed within the timeout period. // Consider that the task may have faulted or been canceled causing them to complete incorrectly. // "re-await" so that any exceptions/cancellation are rethrown correctly. // and not aggregated under the `WhenAll/WhenAny` task from above // https://stackoverflow.com/questions/4238345/asynchronously-wait-for-taskt-to-complete-with-timeout foreach (var invocation in fieldInvocations) { await invocation.Task.ConfigureAwait(false); // load the reslts of each field (in order) to the context // for further processing context.FieldResults.Add(invocation.DataItem); context.Messages.AddRange(invocation.FieldContext.Messages); } } else { // when the timeout finishes first, process the cancel token in case any outstanding tasks are running // helps in cases where the timeout finished first but any of the field resolutions are perhaps stuck open // instruct all outstanding tasks to clean them selves up at the earlest possible point if (!cancelationWasRequested) { cancelSource.Cancel(); } } if (cancelationWasRequested) { context.Messages.Critical("The execution was canceled prior to completion of the requested query.", Constants.ErrorCodes.OPERATION_CANCELED); } else if (isTimedOut) { context.Messages.Critical($"The execution timed out prior to completion of the requested query. (Total Time: {_timeoutMs}ms)", Constants.ErrorCodes.OPERATION_CANCELED); } } finally { cancelSource.Dispose(); } }
/// <summary> /// Initializes a new instance of the <see cref="FieldValidationContext" /> class. /// </summary> /// <param name="schema">The schema in scope for this validation context.</param> /// <param name="dataItem">The data item to process.</param> /// <param name="messageCollection">An optional message collection to use for this context, if not supplied /// a new one will be generated.</param> public FieldValidationContext(ISchema schema, GraphDataItem dataItem, IGraphMessageCollection messageCollection = null) { this.Schema = Validation.ThrowIfNullOrReturn(schema, nameof(schema)); this.DataItem = dataItem; this.Messages = messageCollection ?? new GraphMessageCollection(); }