public ExecutionState(StorageCommandBase <T> cmd, IRetryPolicy policy, OperationContext operationContext) { throw new System.NotImplementedException(); }
/// <summary> /// Apply timeout options to StorageCommandBase /// </summary> /// <typeparam name="T">Return value type of StorageCommandBase</typeparam> /// <param name="requestOptions">The request options.</param> /// <param name="cmd">An instance of StorageCommandBase to apply options to</param> internal static void ApplyToStorageCommand <T>(this TableRequestOptions requestOptions, StorageCommandBase <T> cmd) { if (requestOptions.MaximumExecutionTime.HasValue) { cmd.ClientMaxTimeout = requestOptions.MaximumExecutionTime.Value; } if (requestOptions.ServerTimeout.HasValue) { cmd.ServerTimeoutInSeconds = (int)requestOptions.ServerTimeout.Value.TotalSeconds; } }
public static T ExecuteSync <T>(StorageCommandBase <T> cmd, IRetryPolicy policy, OperationContext operationContext) { // Note all code below will reference state, not params directly, this will allow common code with async executor ExecutionState <T> executionState = new ExecutionState <T>(cmd, policy, operationContext); bool shouldRetry = false; do { try { executionState.Init(); // 0. Begin Request Executor.StartRequestAttempt(executionState); // Steps 1-4 Executor.ProcessStartOfRequest(executionState); Executor.CheckTimeout <T>(executionState, true); // Enter Retryable Section of execution // 5. potentially upload data if (executionState.RestCMD.SendStream != null) { // Reset timeout executionState.Req.Timeout = executionState.RemainingTimeout; executionState.ReqStream = executionState.Req.GetRequestStream(); executionState.RestCMD.SendStream.WriteToSync(executionState.ReqStream, null /* maxLength */, executionState.OperationExpiryTime, false, true, executionState.OperationContext, null /* streamCopyState */); // don't calculate md5 here as we should have already set this for auth purposes } // 6. Get response try { // Reset timeout executionState.Req.Timeout = executionState.RemainingTimeout; executionState.Resp = (HttpWebResponse)executionState.Req.GetResponse(); } catch (WebException ex) { executionState.Resp = (HttpWebResponse)ex.Response; if (executionState.Resp == null) { throw; } else { executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); } } // Response Executor.FireResponseReceived(executionState); // 7. Do Response parsing (headers etc, no stream available here) if (executionState.RestCMD.PreProcessResponse != null) { executionState.Result = executionState.RestCMD.PreProcessResponse(executionState.RestCMD, executionState.Resp, executionState.ExceptionRef, executionState.OperationContext); // clear exception executionState.ExceptionRef = null; } // 8. (Potentially reads stream from server) if (executionState.RestCMD.RetrieveResponseStream) { executionState.RestCMD.ResponseStream = executionState.Resp.GetResponseStream(); } if (executionState.RestCMD.DestinationStream != null) { try { if (executionState.RestCMD.StreamCopyState == null) { executionState.RestCMD.StreamCopyState = new StreamDescriptor(); } executionState.RestCMD.ResponseStream.WriteToSync(executionState.RestCMD.DestinationStream, null /* maxLength */, executionState.OperationExpiryTime, executionState.RestCMD.CalculateMd5ForResponseStream, false, executionState.OperationContext, executionState.RestCMD.StreamCopyState); } finally { executionState.RestCMD.ResponseStream.Dispose(); } } // Step 9 - This will not be called if an exception is raised during stream copying Executor.ProcessEndOfRequest(executionState, executionState.ExceptionRef); Executor.FinishRequestAttempt(executionState); return(executionState.Result); } catch (Exception e) { Executor.FinishRequestAttempt(executionState); StorageException translatedException = StorageException.TranslateException(e, executionState.Cmd.CurrentResult); executionState.ExceptionRef = translatedException; TimeSpan delay = TimeSpan.FromMilliseconds(0); shouldRetry = translatedException.IsRetryable && executionState.RetryPolicy != null? executionState.RetryPolicy.ShouldRetry( executionState.RetryCount++, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.ExceptionRef, out delay, executionState.OperationContext) : false; delay = delay.TotalMilliseconds <0 || delay> Constants.MaximumRetryBackoff ? Constants.MaximumRetryBackoff : delay; if (!shouldRetry || (executionState.OperationExpiryTime.HasValue && (DateTime.Now + delay).CompareTo(executionState.OperationExpiryTime.Value) > 0)) { throw executionState.ExceptionRef; } else { if (executionState.Cmd.RecoveryAction != null) { // I.E. Rewind stream etc. executionState.Cmd.RecoveryAction(executionState.Cmd, executionState.ExceptionRef, executionState.OperationContext); } if (delay > TimeSpan.Zero) { Thread.Sleep(delay); } } } finally { if (executionState.Resp != null) { executionState.Resp.Close(); executionState.Resp = null; } } }while (shouldRetry); // should never get here, either return, or throw; throw new NotImplementedException(SR.InternalStorageError); }
internal static void RewindStream <T>(StorageCommandBase <T> cmd, Exception ex, OperationContext ctx) { SeekStream(cmd, ex, ctx, 0); }
internal static void RewindStream <T>(StorageCommandBase <T> cmd, Exception ex, OperationContext ctx) { RecoveryActions.SeekStream(cmd, 0); }
public static T ExecuteSync <T>(StorageCommandBase <T> cmd, IRetryPolicy policy, OperationContext operationContext) { // Note all code below will reference state, not params directly, this will allow common code with async executor using (ExecutionState <T> executionState = new ExecutionState <T>(cmd, policy, operationContext)) { bool shouldRetry = false; TimeSpan delay = TimeSpan.Zero; do { try { executionState.Init(); // 0. Begin Request Executor.StartRequestAttempt(executionState); // Steps 1-4 Logger.LogInformational(executionState.OperationContext, SR.TraceStartRequestSync, cmd.Uri); Executor.ProcessStartOfRequest(executionState); Executor.CheckTimeout <T>(executionState, true); } catch (Exception ex) { Logger.LogError(executionState.OperationContext, SR.TraceInitRequestError, ex.Message); // Store exception and throw here. All operations in this try would be non-retryable by default StorageException storageEx = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); storageEx.IsRetryable = false; executionState.ExceptionRef = storageEx; throw executionState.ExceptionRef; } // Enter Retryable Section of execution try { // 5. potentially upload data if (executionState.RestCMD.SendStream != null) { executionState.CurrentOperation = ExecutorOperation.BeginGetRequestStream; Logger.LogInformational(executionState.OperationContext, SR.TracePrepareUpload); executionState.Req.Timeout = (int)executionState.RemainingTimeout.TotalMilliseconds; executionState.ReqStream = executionState.Req.GetRequestStream(); executionState.CurrentOperation = ExecutorOperation.BeginUploadRequest; Logger.LogInformational(executionState.OperationContext, SR.TraceUpload); MultiBufferMemoryStream multiBufferMemoryStream = executionState.RestCMD.SendStream as MultiBufferMemoryStream; try { if (multiBufferMemoryStream != null && !executionState.RestCMD.SendStreamLength.HasValue) { multiBufferMemoryStream.FastCopyTo(executionState.ReqStream, executionState.OperationExpiryTime); } else { // don't calculate md5 here as we should have already set this for auth purposes executionState.RestCMD.SendStream.WriteToSync(executionState.ReqStream, executionState.RestCMD.SendStreamLength, null /* maxLength */, false, true, executionState, null /* streamCopyState */); } executionState.ReqStream.Flush(); executionState.ReqStream.Dispose(); executionState.ReqStream = null; } catch (Exception) { executionState.Req.Abort(); throw; } } // 6. Get response try { executionState.CurrentOperation = ExecutorOperation.BeginGetResponse; Logger.LogInformational(executionState.OperationContext, SR.TraceGetResponse); executionState.Req.Timeout = (int)executionState.RemainingTimeout.TotalMilliseconds; executionState.Resp = (HttpWebResponse)executionState.Req.GetResponse(); executionState.CurrentOperation = ExecutorOperation.EndGetResponse; } catch (WebException ex) { Logger.LogWarning(executionState.OperationContext, SR.TraceGetResponseError, ex.Message); executionState.Resp = (HttpWebResponse)ex.Response; if (ex.Status == WebExceptionStatus.Timeout || executionState.ReqTimedOut) { throw new TimeoutException(); } if (executionState.Resp == null) { throw; } else { executionState.ExceptionRef = StorageException.TranslateException(ex, executionState.Cmd.CurrentResult); } } // Response Logger.LogInformational(executionState.OperationContext, SR.TraceResponse, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag); Executor.FireResponseReceived(executionState); // 7. Do Response parsing (headers etc, no stream available here) if (executionState.RestCMD.PreProcessResponse != null) { executionState.CurrentOperation = ExecutorOperation.PreProcess; executionState.Result = executionState.RestCMD.PreProcessResponse(executionState.RestCMD, executionState.Resp, executionState.ExceptionRef, executionState.OperationContext); // clear exception executionState.ExceptionRef = null; Logger.LogInformational(executionState.OperationContext, SR.TracePreProcessDone); } // 8. (Potentially reads stream from server) executionState.CurrentOperation = ExecutorOperation.GetResponseStream; executionState.RestCMD.ResponseStream = executionState.Resp.GetResponseStream(); if (!executionState.RestCMD.RetrieveResponseStream) { executionState.RestCMD.DestinationStream = Stream.Null; } if (executionState.RestCMD.DestinationStream != null) { if (executionState.RestCMD.StreamCopyState == null) { executionState.RestCMD.StreamCopyState = new StreamDescriptor(); } try { executionState.CurrentOperation = ExecutorOperation.BeginDownloadResponse; Logger.LogInformational(executionState.OperationContext, SR.TraceDownload); executionState.RestCMD.ResponseStream.WriteToSync(executionState.RestCMD.DestinationStream, null /* copyLength */, null /* maxLength */, executionState.RestCMD.CalculateMd5ForResponseStream, false, executionState, executionState.RestCMD.StreamCopyState); } finally { executionState.RestCMD.ResponseStream.Dispose(); executionState.RestCMD.ResponseStream = null; } } // Step 9 - This will not be called if an exception is raised during stream copying Executor.ProcessEndOfRequest(executionState); Executor.FinishRequestAttempt(executionState); return(executionState.Result); } catch (Exception e) { Logger.LogWarning(executionState.OperationContext, SR.TraceGenericError, e.Message); Executor.FinishRequestAttempt(executionState); StorageException translatedException = StorageException.TranslateException(e, executionState.Cmd.CurrentResult); executionState.ExceptionRef = translatedException; Logger.LogInformational(executionState.OperationContext, SR.TraceRetryCheck, executionState.RetryCount, executionState.Cmd.CurrentResult.HttpStatusCode, translatedException.IsRetryable ? "yes" : "no", translatedException.Message); shouldRetry = false; if (translatedException.IsRetryable && (executionState.RetryPolicy != null)) { shouldRetry = executionState.RetryPolicy.ShouldRetry( executionState.RetryCount++, executionState.Cmd.CurrentResult.HttpStatusCode, executionState.ExceptionRef, out delay, executionState.OperationContext); if ((delay < TimeSpan.Zero) || (delay > Constants.MaximumRetryBackoff)) { delay = Constants.MaximumRetryBackoff; } } } finally { if (executionState.Resp != null) { executionState.Resp.Close(); executionState.Resp = null; } } if (!shouldRetry || (executionState.OperationExpiryTime.HasValue && (DateTime.Now + delay).CompareTo(executionState.OperationExpiryTime.Value) > 0)) { Logger.LogError(executionState.OperationContext, shouldRetry ? SR.TraceRetryDecisionTimeout : SR.TraceRetryDecisionPolicy, executionState.ExceptionRef.Message); throw executionState.ExceptionRef; } else { if (executionState.Cmd.RecoveryAction != null) { // I.E. Rewind stream etc. executionState.Cmd.RecoveryAction(executionState.Cmd, executionState.ExceptionRef, executionState.OperationContext); } if (delay > TimeSpan.Zero) { Logger.LogInformational(executionState.OperationContext, SR.TraceRetryDelay, (int)delay.TotalMilliseconds); Thread.Sleep(delay); } Logger.LogInformational(executionState.OperationContext, SR.TraceRetry); } }while (shouldRetry); } // should never get here, either return, or throw; throw new NotImplementedException(SR.InternalStorageError); }