private async Task SendRequestInternal()

in LinuxCommunicator/LinuxCommunicator.cs [390:468]


        private async Task SendRequestInternal<T>(string action, string callbackUri, string nodeName, Func<HttpContent, Exception, Task> callback, T arg, int retryCount = 0)
        {
            this.Tracer.TraceDetail("Sending out request, action {0}, callback {1}, nodeName {2}", action, callbackUri, nodeName);
            var request = new HttpRequestMessage(HttpMethod.Post, this.GetResoureUri(nodeName, action));
            request.Headers.Add(CallbackUriHeaderName, callbackUri);
            request.Headers.Add(MessageAuthenticationHandler.AuthenticationHeaderKey, this.ClusterAuthenticationKey);
            var formatter = new JsonMediaTypeFormatter();
            request.Content = new ObjectContent<T>(arg, formatter);

            Exception ex = null;
            HttpContent content = null;
            bool retry = false;

            using (HttpClient client = new HttpClient())
            {
                client.Timeout = this.RequestTimeout;

                HttpResponseMessage response = null;
                try
                {
                    response = await client.SendAsync(request, this.cancellationTokenSource.Token);
                }
                catch (Exception e)
                {
                    ex = e;
                }

                this.Tracer.TraceDetail("Sending out request task completed, action {0}, callback {1}, nodeName {2} ex {3}", action, callbackUri, nodeName, ex);

                if (ex == null)
                {
                    try
                    {
                        content = response.Content;

                        if (!response.IsSuccessStatusCode)
                        {
                            using (content)
                            {
                                if (response.StatusCode >= HttpStatusCode.InternalServerError)
                                {
                                    throw new InvalidProgramException(await content.ReadAsStringAsync());
                                }
                                else
                                {
                                    response.EnsureSuccessStatusCode();
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        ex = e;
                    }
                }

                if (this.CanRetry(ex) && retryCount < AutoRetrySendLimit)
                {
                    retry = true;
                }
                else
                {
                    try
                    {
                        await callback(content, ex);
                    }
                    catch (Exception callbackEx)
                    {
                        this.Tracer.TraceError("Finished sending, callback error: action {0}, callback {1}, nodeName {2} retry count {3}, ex {4}", action, callbackUri, nodeName, retryCount, callbackEx);
                    }
                }
            }

            if (retry)
            {
                await Task.Delay(DelayBetweenRetry);
                this.SendRequest(action, callbackUri, nodeName, callback, arg, retryCount + 1);
            }
        }