Contains utility methods for handling HttpResponseMessages in a transaction scope
        protected override Task <HttpResponseMessage> RunQuery(IGraphClient client, CypherQuery query, IExecutionPolicy policy, string commandDescription)
        {
            var txBaseEndpoint  = policy.BaseEndpoint((policy.InTransaction) ? policy.Database : query.Database, !policy.InTransaction);
            var serializedQuery = policy.SerializeRequest(query);

            CustomHeaders = query.CustomHeaders;
            return(Request.With(client.ExecutionConfiguration, query.CustomHeaders, query.MaxExecutionTime)
                   .Post(Endpoint ?? txBaseEndpoint)
                   .WithJsonContent(serializedQuery)
                   // HttpStatusCode.Created may be returned when emitting the first query on a transaction
                   .WithExpectedStatusCodes(HttpStatusCode.OK, HttpStatusCode.Created)
                   .ExecuteAsync(
                       commandDescription,
                       response =>
            {
                // we need to check for errors returned by the transaction. The difference with a normal REST cypher
                // query is that the errors are embedded within the result object, instead of having a 400 bad request
                // status code.
                policy.AfterExecution(TransactionHttpUtils.GetMetadataFromResponse(response), this);

                return response;
            }));
        }
        public Task <HttpResponseMessage> EnqueueTask(string commandDescription, IGraphClient client, IExecutionPolicy policy, CypherQuery query)
        {
            // grab the endpoint in the same thread
            var txBaseEndpoint  = policy.BaseEndpoint;
            var serializedQuery = policy.SerializeRequest(query);

            CustomHeaders = query.CustomHeaders;
            var task = new Task <HttpResponseMessage>(() =>
                                                      Request.With(client.ExecutionConfiguration, query.CustomHeaders, query.MaxExecutionTime)
                                                      .Post(Endpoint ?? txBaseEndpoint)
                                                      .WithJsonContent(serializedQuery)
                                                      // HttpStatusCode.Created may be returned when emitting the first query on a transaction
                                                      .WithExpectedStatusCodes(HttpStatusCode.OK, HttpStatusCode.Created)
                                                      .ExecuteAsync(
                                                          commandDescription,
                                                          responseTask =>
            {
                // we need to check for errors returned by the transaction. The difference with a normal REST cypher
                // query is that the errors are embedded within the result object, instead of having a 400 bad request
                // status code.
                var response = responseTask.Result;
                policy.AfterExecution(TransactionHttpUtils.GetMetadataFromResponse(response), this);

                return(response);
            })
                                                      .Result
                                                      );

            taskQueue.Add(task, cancellationTokenSource.Token);

            if (consumer == null)
            {
                consumer = () =>
                {
                    while (true)
                    {
                        try
                        {
                            Task queuedTask;
                            if (!taskQueue.TryTake(out queuedTask, 0, cancellationTokenSource.Token))
                            {
                                // no items to consume
                                consumer = null;
                                break;
                            }
                            queuedTask.RunSynchronously();
                        }
                        catch (InvalidOperationException)
                        {
                            // we are done, CompleteAdding has been called
                            break;
                        }
                        catch (OperationCanceledException)
                        {
                            // we are done, we were canceled
                            break;
                        }
                    }
                };

                consumer.BeginInvoke(null, null);
            }

            return(task);
        }