protected void OnTransmissionSent(TransmissionProcessedEventArgs args)
 {
     EventHandler<TransmissionProcessedEventArgs> handler = this.TransmissionSent;
     if (handler != null)
     {
         handler(this, args);
     }
 }
        private void HandleTransmissionSentEvent(object sender, TransmissionProcessedEventArgs e)
        {
            var webException = e.Exception as WebException;
            if (webException != null)
            {
                this.ConsecutiveErrors++;
                HttpWebResponse httpWebResponse = webException.Response as HttpWebResponse;
                if (httpWebResponse != null)
                {
                    TelemetryChannelEventSource.Log.TransmissionSendingFailedWebExceptionWarning(e.Transmission.Id, webException.Message, (int)httpWebResponse.StatusCode);

                    switch (httpWebResponse.StatusCode)
                    {
                        case (HttpStatusCode)408:
                        case (HttpStatusCode)503:
                        case (HttpStatusCode)500:
                            // Disable sending and buffer capacity (=EnqueueAsync will enqueue to the Storage)
                            this.MaxSenderCapacity = 0;
                            this.MaxBufferCapacity = 0;
                            this.LogCapacityChanged();
                            this.Apply();

                            // Back-off for the Delay duration and enable sending capacity
                            this.pauseTimer.Delay = this.GetBackOffTime(httpWebResponse.Headers);
                            this.pauseTimer.Start(() =>
                            {
                                this.MaxBufferCapacity = null;
                                this.MaxSenderCapacity = null;
                                this.LogCapacityChanged();
                                this.Apply();

                                return TaskEx.FromResult<object>(null);
                            });

                            this.Transmitter.Enqueue(e.Transmission);
                            break;
                    }
                }
                else
                {
                    TelemetryChannelEventSource.Log.TransmissionSendingFailedWebExceptionWarning(e.Transmission.Id, webException.Message, (int)HttpStatusCode.InternalServerError);
                }
            }
            else
            {
                if (e.Exception != null)
                {
                    TelemetryChannelEventSource.Log.TransmissionSendingFailedWarning(e.Transmission.Id, e.Exception.Message);
                }

                this.ConsecutiveErrors = 0;
            }
        }
        private void HandleTransmissionSentEvent(object sender, TransmissionProcessedEventArgs e)
        {
            var webException = e.Exception as WebException;
            if (webException != null)
            {
                HttpWebResponse httpWebResponse = webException.Response as HttpWebResponse;
                if (httpWebResponse != null)
                {
                    if (httpWebResponse.StatusCode == (HttpStatusCode)ResponseCodeTooManyRequests ||
                        httpWebResponse.StatusCode == (HttpStatusCode)ResponseCodeTooManyRequestsOverExtendedTime ||
                        httpWebResponse.StatusCode == (HttpStatusCode)ResponseCodePaymentRequired)
                    {
                        TimeSpan retryAfterTimeSpan;
                        if (!this.TryParseRetryAfter(httpWebResponse.Headers, out retryAfterTimeSpan))
                        {
                            this.ResetPolicy();                         
                        }
                        else
                        {
                            this.pauseTimer.Delay = retryAfterTimeSpan;
                            TelemetryChannelEventSource.Log.ThrottlingRetryAfterParsedInSec(retryAfterTimeSpan.TotalSeconds);

                            this.MaxSenderCapacity = 0;
                            this.MaxBufferCapacity =
                                httpWebResponse.StatusCode == (HttpStatusCode)ResponseCodeTooManyRequestsOverExtendedTime ?
                                (int?)0 :
                                null;
                            this.MaxStorageCapacity =
                                httpWebResponse.StatusCode == (HttpStatusCode)ResponseCodeTooManyRequestsOverExtendedTime ?
                                (int?)0 :
                                null;

                            this.LogCapacityChanged();

                            this.Apply();

                            // Back-off for the Delay duration and enable sending capacity
                            this.pauseTimer.Start(() =>
                            {
                                this.ResetPolicy();
                                return TaskEx.FromResult<object>(null);
                            });

                            this.Transmitter.Enqueue(e.Transmission);
                        }
                    }
                }
            }
        }
            public void IsRaisedWhenTransmissionWasDequeuedSuccessfully()
            {
                object eventSender = null;
                TransmissionProcessedEventArgs eventArgs = null;
                var buffer = new TransmissionBuffer();

                buffer.TransmissionDequeued += (sender, args) =>
                {
                    eventSender = sender;
                    eventArgs   = args;
                };

                buffer.Enqueue(() => new StubTransmission());

                Transmission dequeuedTransmission = buffer.Dequeue();

                Assert.AreSame(buffer, eventSender);
                Assert.AreSame(dequeuedTransmission, eventArgs.Transmission);
            }
        private void HandleTransmissionSentEvent(object sender, TransmissionProcessedEventArgs e)
        {
            var webException = e.Exception as WebException;

            if (webException != null)
            {
                HttpWebResponse httpWebResponse = webException.Response as HttpWebResponse;
                if (httpWebResponse != null)
                {
                    if (httpWebResponse.StatusCode == (HttpStatusCode)ResponseStatusCodes.ResponseCodeTooManyRequests ||
                        httpWebResponse.StatusCode == (HttpStatusCode)ResponseStatusCodes.ResponseCodeTooManyRequestsOverExtendedTime)
                    {
                        this.MaxSenderCapacity = 0;
                        if (httpWebResponse.StatusCode == (HttpStatusCode)ResponseStatusCodes.ResponseCodeTooManyRequestsOverExtendedTime)
                        {
                            // We start loosing data!
                            this.MaxBufferCapacity  = 0;
                            this.MaxStorageCapacity = 0;
                        }
                        else
                        {
                            this.MaxBufferCapacity  = null;
                            this.MaxStorageCapacity = null;
                        }

                        this.LogCapacityChanged();
                        this.Apply();

                        this.backoffLogicManager.ReportBackoffEnabled((int)httpWebResponse.StatusCode);
                        this.Transmitter.Enqueue(e.Transmission);

                        this.backoffLogicManager.ScheduleRestore(
                            httpWebResponse.Headers,
                            () =>
                        {
                            this.ResetPolicy();
                            return(TaskEx.FromResult <object>(null));
                        });
                    }
                }
            }
        }
Example #6
0
        private void HandleTransmissionSentEvent(object sender, TransmissionProcessedEventArgs e)
        {
            HttpWebResponseWrapper httpWebResponse = e.Response;

            if (httpWebResponse != null)
            {
                if (httpWebResponse.StatusCode == ResponseStatusCodes.ResponseCodeTooManyRequests ||
                    httpWebResponse.StatusCode == ResponseStatusCodes.ResponseCodeTooManyRequestsOverExtendedTime)
                {
                    this.MaxSenderCapacity = 0;
                    if (httpWebResponse.StatusCode == ResponseStatusCodes.ResponseCodeTooManyRequestsOverExtendedTime)
                    {
                        // We start losing data!
                        this.MaxBufferCapacity  = 0;
                        this.MaxStorageCapacity = 0;
                    }
                    else
                    {
                        this.MaxBufferCapacity  = null;
                        this.MaxStorageCapacity = null;
                    }

                    this.LogCapacityChanged();
                    this.Apply();

                    this.backoffLogicManager.ReportBackoffEnabled((int)httpWebResponse.StatusCode);
                    this.Transmitter.Enqueue(e.Transmission);

                    this.pauseTimer.Delay = this.backoffLogicManager.GetBackOffTimeInterval(httpWebResponse.RetryAfterHeader);
                    this.pauseTimer.Start(
                        () =>
                    {
                        this.ResetPolicy();
                        return(TaskEx.FromResult <object>(null));
                    });
                }
            }
        }
Example #7
0
        private void HandleTransmissionSentEvent(object sender, TransmissionProcessedEventArgs args)
        {
            if (args.Exception == null && (args.Response == null || args.Response.StatusCode == ResponseStatusCodes.Success))
            {
                // We successfully sent transmittion
                this.backoffLogicManager.ResetConsecutiveErrors();
                return;
            }

            if (args.Response != null && args.Response.StatusCode == ResponseStatusCodes.PartialSuccess)
            {
                int          statusCode;
                Transmission transmission;
                string       newTransmissions = ParsePartialSuccessResponse(args.Transmission, args, out statusCode);

                if (!string.IsNullOrEmpty(newTransmissions))
                {
                    if (args.Transmission.IsFlushAsyncInProgress)
                    {
                        // Move newTransmission to storage on IAsyncFlushable.FlushAsync
                        transmission = SerializeNewTransmission(args, newTransmissions);
                        this.DelayFutureProcessing(args.Response, statusCode);
                    }
                    else
                    {
                        this.DelayFutureProcessing(args.Response, statusCode);
                        transmission = SerializeNewTransmission(args, newTransmissions);
                    }

                    this.Transmitter.Enqueue(transmission);
                }
                else
                {
                    // We got 206 but there is no indication in response that something was not accepted.
                    this.backoffLogicManager.ResetConsecutiveErrors();
                }
            }
        }
        private void HandleTransmissionSentEvent(object sender, TransmissionProcessedEventArgs args)
        {
            if (args.Response != null && args.Response.StatusCode == ResponseStatusCodes.PartialSuccess)
            {
                string newTransmissions = this.ParsePartialSuccessResponse(args.Transmission, args);

                if (!string.IsNullOrEmpty(newTransmissions))
                {
                    this.ConsecutiveErrors++;
                    this.DelayFutureProcessing(args.Response);

                    byte[] data = JsonSerializer.ConvertToByteArray(newTransmissions);
                    Transmission newTransmission = new Transmission(
                        args.Transmission.EndpointAddress,
                        data,
                        args.Transmission.ContentType,
                        args.Transmission.ContentEncoding,
                        args.Transmission.Timeout);

                    this.Transmitter.Enqueue(newTransmission);
                }
            }
        }
            public void RaisesTransmissionSentWhenTransmissionFinishesSending()
            {
                var         sender = new StubTransmissionSender();
                Transmitter queue  = CreateTransmitter(sender: sender);

                object eventSender = null;
                TransmissionProcessedEventArgs eventArgs = null;

                queue.TransmissionSent += (s, e) =>
                {
                    eventSender = s;
                    eventArgs   = e;
                };

                var transmission = new StubTransmission();
                var exception    = new Exception();

                sender.OnTransmissionSent(new TransmissionProcessedEventArgs(transmission, exception));

                Assert.Same(queue, eventSender);
                Assert.Same(transmission, eventArgs.Transmission);
                Assert.Same(exception, eventArgs.Exception);
            }
            public void IsRaisedWhenTransmissionIsSentSuccessfully()
            {
                var sender = new TransmissionSender();

                var    eventIsRaised = new ManualResetEventSlim();
                object eventSender   = null;
                TransmissionProcessedEventArgs eventArgs = null;

                sender.TransmissionSent += (s, a) =>
                {
                    eventSender = s;
                    eventArgs   = a;
                    eventIsRaised.Set();
                };

                Transmission transmission = new StubTransmission();

                sender.Enqueue(() => transmission);

                Assert.IsTrue(eventIsRaised.Wait(50));
                Assert.AreSame(sender, eventSender);
                Assert.AreSame(transmission, eventArgs.Transmission);
            }
 public new void OnTransmissionDequeued(TransmissionProcessedEventArgs e)
 {
     base.OnTransmissionDequeued(e);
 }
        private void HandleTransmissionSentEvent(object sender, TransmissionProcessedEventArgs e)
        {
            var webException = e.Exception as WebException;

            if (webException != null)
            {
                HttpWebResponse httpWebResponse = webException.Response as HttpWebResponse;
                if (httpWebResponse != null)
                {
                    TelemetryChannelEventSource.Log.TransmissionSendingFailedWebExceptionWarning(
                        e.Transmission.Id,
                        webException.Message,
                        (int)httpWebResponse.StatusCode,
                        httpWebResponse.StatusDescription);

                    this.AdditionalVerboseTracing(httpWebResponse);

                    switch (httpWebResponse.StatusCode)
                    {
                    case (HttpStatusCode)ResponseStatusCodes.RequestTimeout:
                    case (HttpStatusCode)ResponseStatusCodes.ServiceUnavailable:
                    case (HttpStatusCode)ResponseStatusCodes.InternalServerError:
                        // Disable sending and buffer capacity (Enqueue will enqueue to the Storage)
                        this.MaxSenderCapacity = 0;
                        this.MaxBufferCapacity = 0;
                        this.LogCapacityChanged();
                        this.Apply();

                        this.backoffLogicManager.ReportBackoffEnabled((int)httpWebResponse.StatusCode);
                        this.Transmitter.Enqueue(e.Transmission);

                        this.backoffLogicManager.ScheduleRestore(
                            httpWebResponse.Headers,
                            () =>
                        {
                            this.MaxBufferCapacity = null;
                            this.MaxSenderCapacity = null;
                            this.LogCapacityChanged();
                            this.Apply();

                            this.backoffLogicManager.ReportBackoffDisabled();

                            return(TaskEx.FromResult <object>(null));
                        });
                        break;
                    }
                }
                else
                {
                    // We are loosing data here (we did not upload failed transaction back).
                    // We did not get response back.
                    TelemetryChannelEventSource.Log.TransmissionSendingFailedWebExceptionWarning(e.Transmission.Id, webException.Message, (int)HttpStatusCode.InternalServerError, null);
                }
            }
            else
            {
                if (e.Exception != null)
                {
                    // We are loosing data here (we did not upload failed transaction back).
                    // We got unknown exception.
                    TelemetryChannelEventSource.Log.TransmissionSendingFailedWarning(e.Transmission.Id, e.Exception.Message);
                }
            }
        }
 protected void OnTransmissionSent(TransmissionProcessedEventArgs args)
 {
     this.TransmissionSent?.Invoke(this, args);
 }
 internal new void OnTransmissionSent(TransmissionProcessedEventArgs e)
 {
     base.OnTransmissionSent(e);
 }
        private string ParsePartialSuccessResponse(Transmission initialTransmission, TransmissionProcessedEventArgs args)
        {
            BackendResponse backendResponse;
            string responseContent = args.Response.Content;
            try
            {
                backendResponse = this.serializer.Deserialize<BackendResponse>(responseContent);
            }
            catch (ArgumentException exp)
            {
                TelemetryChannelEventSource.Log.BreezeResponseWasNotParsedWarning(exp.Message, responseContent);
                this.ConsecutiveErrors = 0;
                return null;
            }
            catch (InvalidOperationException exp)
            {
                TelemetryChannelEventSource.Log.BreezeResponseWasNotParsedWarning(exp.Message, responseContent);
                this.ConsecutiveErrors = 0;
                return null;
            }

            string newTransmissions = null;

            if (backendResponse != null && backendResponse.ItemsAccepted != backendResponse.ItemsReceived)
            {
                string[] items = JsonSerializer
                    .Deserialize(initialTransmission.Content)
                    .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

                foreach (var error in backendResponse.Errors)
                {
                    if (error != null)
                    {
                        if (error.Index >= items.Length || error.Index < 0)
                        {
                            TelemetryChannelEventSource.Log.UnexpectedBreezeResponseWarning(items.Length, error.Index);
                            continue;
                        }

                        TelemetryChannelEventSource.Log.ItemRejectedByEndpointWarning(error.Message);

                        if (error.StatusCode == ResponseStatusCodes.RequestTimeout ||
                            error.StatusCode == ResponseStatusCodes.ServiceUnavailable ||
                            error.StatusCode == ResponseStatusCodes.InternalServerError ||
                            error.StatusCode == ResponseStatusCodes.ResponseCodeTooManyRequests ||
                            error.StatusCode == ResponseStatusCodes.ResponseCodeTooManyRequestsOverExtendedTime)
                        {
                            if (string.IsNullOrEmpty(newTransmissions))
                            {
                                newTransmissions = items[error.Index];
                            }
                            else
                            {
                                newTransmissions += Environment.NewLine + items[error.Index];
                            }
                        }
                    }
                }
            }

            return newTransmissions;
        }
Example #16
0
        private static string ParsePartialSuccessResponse(Transmission initialTransmission, TransmissionProcessedEventArgs args, out int lastStatusCode)
        {
            BackendResponse backendResponse = null;

            lastStatusCode = 206;

            if (args != null && args.Response != null)
            {
                backendResponse = BackoffLogicManager.GetBackendResponse(args.Response.Content);
            }

            if (backendResponse == null)
            {
                return(null);
            }

            string newTransmissions = null;

            if (backendResponse.ItemsAccepted != backendResponse.ItemsReceived)
            {
                string[] items = JsonSerializer
                                 .Deserialize(initialTransmission.Content)
                                 .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

                foreach (var error in backendResponse.Errors)
                {
                    if (error != null)
                    {
                        if (error.Index >= items.Length || error.Index < 0)
                        {
                            TelemetryChannelEventSource.Log.UnexpectedBreezeResponseWarning(items.Length, error.Index);
                            continue;
                        }

                        TelemetryChannelEventSource.Log.ItemRejectedByEndpointWarning(error.Message);

                        if (error.StatusCode == ResponseStatusCodes.RequestTimeout ||
                            error.StatusCode == ResponseStatusCodes.ServiceUnavailable ||
                            error.StatusCode == ResponseStatusCodes.InternalServerError ||
                            error.StatusCode == ResponseStatusCodes.ResponseCodeTooManyRequests ||
                            error.StatusCode == ResponseStatusCodes.ResponseCodeTooManyRequestsOverExtendedTime)
                        {
                            if (string.IsNullOrEmpty(newTransmissions))
                            {
                                newTransmissions = items[error.Index];
                            }
                            else
                            {
                                newTransmissions += Environment.NewLine + items[error.Index];
                            }

                            // Last status code is used for tracing purposes. We will get only one out of many. Most likely they all will be the same.
                            lastStatusCode = error.StatusCode;
                        }
                    }
                }
            }

            return(newTransmissions);
        }
 public new void OnTransmissionSent(TransmissionProcessedEventArgs args)
 {
     base.OnTransmissionSent(args);
 }
        private void HandleTransmissionSentEvent(object sender, TransmissionProcessedEventArgs e)
        {
            HttpWebResponseWrapper httpWebResponseWrapper = e.Response;

            if (httpWebResponseWrapper != null)
            {
                AdditionalVerboseTracing(httpWebResponseWrapper.Content);
                if (httpWebResponseWrapper.StatusCode == ResponseStatusCodes.Success || httpWebResponseWrapper.StatusCode == ResponseStatusCodes.PartialSuccess)
                {
                    // There is no further action for ErrorHandlingTransmissionPolicy here as transmission is success/partial success.
                    return;
                }

                switch (httpWebResponseWrapper.StatusCode)
                {
                case ResponseStatusCodes.BadGateway:
                case ResponseStatusCodes.GatewayTimeout:
                case ResponseStatusCodes.RequestTimeout:
                case ResponseStatusCodes.ServiceUnavailable:
                case ResponseStatusCodes.InternalServerError:
                case ResponseStatusCodes.UnknownNetworkError:
                    // Disable sending and buffer capacity (Enqueue will enqueue to the Storage)
                    this.MaxSenderCapacity = 0;
                    this.MaxBufferCapacity = 0;
                    this.LogCapacityChanged();
                    this.Apply();

                    this.backoffLogicManager.ReportBackoffEnabled((int)httpWebResponseWrapper.StatusCode);
                    this.Transmitter.Enqueue(e.Transmission);

                    this.pauseTimer.Delay = this.backoffLogicManager.GetBackOffTimeInterval(httpWebResponseWrapper.RetryAfterHeader);
                    this.pauseTimer.Start(
                        () =>
                    {
                        this.MaxBufferCapacity = null;
                        this.MaxSenderCapacity = null;
                        this.LogCapacityChanged();
                        this.Apply();

                        this.backoffLogicManager.ReportBackoffDisabled();

                        return(Task.FromResult <object>(null));
                    });
                    break;

                default:
                    // We are losing data here but that is intentional as the response code is
                    // not in the whitelisted set to attempt retry.
                    TelemetryChannelEventSource.Log.TransmissionDataNotRetriedForNonWhitelistedResponse(e.Transmission.Id,
                                                                                                        httpWebResponseWrapper.StatusCode.ToString(CultureInfo.InvariantCulture));
                    // For non white listed response, set the result of FlushAsync to false.
                    e.Transmission.IsFlushAsyncInProgress = false;
                    break;
                }
            }
            else
            {
                // Data loss Unknown Exception
                // We are losing data here (we did not upload failed transaction back).
                // We got unknown exception.
                if (e.Exception != null)
                {
                    TelemetryChannelEventSource.Log.TransmissionDataLossError(e.Transmission.Id,
                                                                              e.Exception.Message);
                }
                else
                {
                    TelemetryChannelEventSource.Log.TransmissionDataLossError(e.Transmission.Id,
                                                                              "Unknown Exception Message");
                }

                // For Unknown Exception set the result of FlushAsync to false.
                e.Transmission.IsFlushAsyncInProgress = false;
            }
        }
 protected void OnTransmissionSent(TransmissionProcessedEventArgs e)
 {
     EventHandler<TransmissionProcessedEventArgs> eventHandler = this.TransmissionSent;
     if (eventHandler != null)
     {
         eventHandler(this, e);
     }
 }
 private void HandleBufferTransmissionDequeuedEvent(object sender, TransmissionProcessedEventArgs e)
 {
     try
     {
         this.MoveTransmissions(this.Storage.Dequeue, this.Buffer.Enqueue);
     }
     catch (Exception exp)
     {
         TelemetryChannelEventSource.Log.ExceptionHandlerStartExceptionWarning(exp.ToString());
     }
 }
 public void ExceptionReturnsValueSuppliedByConstructor()
 {
     Exception exception = new Exception();
     var args = new TransmissionProcessedEventArgs(new StubTransmission(), exception);
     Assert.Same(exception, args.Exception);
 }
 public void TransmissionReturnsValueSuppliedByConstructor()
 {
     Transmission transmission = new StubTransmission();
     var args = new TransmissionProcessedEventArgs(transmission);
     Assert.Same(transmission, args.Transmission);
 }