コード例 #1
0
 public void Add(BatchResult result)
 {
     foreach (var request in result._Requests)
     {
         _Requests.Add(request);
     }
     foreach (var(key, value) in result._Errors)
     {
         _Errors.Add(key, value);
     }
     foreach (var(key, value) in result._Queries)
     {
         _Queries.Add(key, value);
     }
     foreach (var(key, value) in result._Results)
     {
         _Results.Add(key, value);
     }
 }
コード例 #2
0
        public async Task <BatchResult> BatchAsync(IBatchRequest request)
        {
            if (request == null || request.BatchRequests.Count <= 0)
            {
                throw new ArgumentNullException(nameof(request));
            }

            try
            {
                var resourceName = $"{request.Prefix}composite/batch";

                if (request.HaltOnError)
                {
                    if (request.BatchRequests.Count > Dnf.BatchLimit)
                    {
                        throw new ArgumentOutOfRangeException(nameof(request));
                    }

                    var inputObject = new JObject
                    {
                        ["batchRequests"] = JToken.FromObject(request.BatchRequests.Select(req => Dnf.Assign(JObject.FromObject(req), new JObject
                        {
                            ["url"] = DecodeReference($"/services/data/{ApiVersion}/{request.Prefix}{req.Url?.TrimStart('/')}")
                        }))),
                        ["haltOnError"] = true
                    };

                    var result = await JsonHttp.HttpPostAsync <BatchResultBody>(inputObject, resourceName)
                                 .ConfigureAwait(false);

                    var results = new BatchResult(request.BatchRequests, result?.Results ?? new List <BatchSubRequestResult>());
                    return(results);
                }
                else
                {
                    var throttler = new SemaphoreSlim(Dnf.DefaultConcurrentLimit, Dnf.DefaultConcurrentLimit);
                    var results   = new BatchResult();

                    var chunks = new List <IList <BatchSubRequest> >();
                    IList <BatchSubRequest>?chunk = null;

                    foreach (var req in request.BatchRequests)
                    {
                        var added = false;

                        if (chunk?.Count < Dnf.BatchLimit)
                        {
                            chunk.Add(req);
                            added = true;
                        }

                        if (added)
                        {
                            continue;
                        }
                        chunk = new List <BatchSubRequest> {
                            req
                        };
                        chunks.Add(chunk);
                    }

                    var tasks = new List <Task>();

                    foreach (var requests in chunks)
                    {
                        await throttler.WaitAsync()
                        .ConfigureAwait(false);

                        tasks.Add(Task.Run(async() =>
                        {
                            try
                            {
                                var inputObject = new JObject
                                {
                                    ["batchRequests"] = JToken.FromObject(requests.Select(req => Dnf.Assign(JObject.FromObject(req), new JObject
                                    {
                                        ["url"] = DecodeReference($"/services/data/{ApiVersion}/{request.Prefix}{req.Url?.TrimStart('/')}")
                                    })))
                                };


                                var result = await JsonHttp.HttpPostAsync <BatchResultBody>(inputObject, resourceName)
                                             .ConfigureAwait(false);
                                results.Add(requests, result?.Results ?? new List <BatchSubRequestResult>());
                            }
                            catch (Exception ex)
                            {
                                var body = new JArray {
                                    ex.Message
                                };
                                var responses = requests.Select(req => new BatchSubRequestResult
                                {
                                    Result     = body,
                                    StatusCode = 500
                                }).ToList();
                                results.Add(requests, responses);
                            }
                            finally
                            {
                                throttler.Release();
                            }
                        }));
                    }
                    await Task.WhenAll(tasks)
                    .ConfigureAwait(false);

                    return(results);
                }
            }
            catch (Exception ex)
            {
                var body = new JArray {
                    ex.Message
                };
                var responses = request.BatchRequests.Select(req => new BatchSubRequestResult
                {
                    Result     = body,
                    StatusCode = 500
                }).ToList();
                var results = new BatchResult(request.BatchRequests, responses);
                return(results);
            }
        }