public T withRetryUntilSuccess <T>(Func <SMBExecutor.triedNetworkCallRes <T> > action, cancellableDateTime deadline) { while (true) { SMBExecutor.triedNetworkCallRes <T> res = action(); if (!res.retryRequested) { if (res.error == null) { return(res.res); } if (!(res.error is Win32Exception) && !(res.error is TimeoutException) && !(res.error is IOException) && !(res.error is VimException)) { throw res.error; } if (!deadline.stillOK) { throw res.error; } } deadline.doCancellableSleep(TimeSpan.FromSeconds(3)); } }
public executionResult getResultIfComplete() { // Read the return code last. We do this because there's no way in VMWare's guest tools specify file locking, so // we may see empty files before they have been written to. SMBExecutor.triedNetworkCallRes <string> returnCodeResultInfo = _host.tryGetFileFromGuestWithRes(_returnCodeFilename); SMBExecutor.triedNetworkCallRes <string> stdOutResultInfo = _host.tryGetFileFromGuestWithRes(_stdOutFilename); SMBExecutor.triedNetworkCallRes <string> stdErrResultInfo = _host.tryGetFileFromGuestWithRes(_stdErrFilename); if (returnCodeResultInfo.retryRequested || returnCodeResultInfo.error != null || stdOutResultInfo.retryRequested || stdOutResultInfo.error != null || stdErrResultInfo.retryRequested || stdErrResultInfo.error != null) { return(null); } int retCode = Int32.Parse(returnCodeResultInfo.res); string stdOut = stdOutResultInfo.res; string stdErr = stdErrResultInfo.res; return(new executionResult(stdOut, stdErr, retCode)); }
public static T doWithRetryOnSomeExceptions <T>(Func <SMBExecutor.triedNetworkCallRes <T> > thingtoDo, cancellableDateTime deadline = null, TimeSpan retryDelay = default(TimeSpan)) { if (retryDelay == default(TimeSpan)) { retryDelay = TimeSpan.FromSeconds(1); } if (deadline == null) { deadline = new cancellableDateTime(); } while (true) { SMBExecutor.triedNetworkCallRes <T> res = thingtoDo.Invoke(); if (!res.retryRequested) { if (res.error == null) { return(res.res); } if (res.error is VimException) { // This VimException is fatal if (res.error.Message.Contains("are insufficient for the operation") || res.error.Message.Contains("Permission to perform this operation was denied.")) { throw res.error; } // while others are not. if (!deadline.stillOK) { throw res.error; } } if (!(res.error is SocketException) && !(res.error is SoapException) && !(res.error is TimeoutException) && !(res.error is WebException) && !(res.error is hypervisorExecutionException) && !(res.error is hypervisorExecutionException_retryable) && !(res.error is SshOperationTimeoutException) && !(res.error is SshConnectionException) && !(res.error is UnauthorizedAccessException) && !(res.error is COMException)) { // An exception of a type we don't anticipate, so throw throw res.error; } // throw if the deadline has passed if (!deadline.stillOK) { throw res.error; } } // Otherwise, just retry. deadline.doCancellableSleep(retryDelay); } }