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)); }); } } } }
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)); }); } } }
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; }
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); }