public TReturn Send <TReturn>(AbstractRequest <TReturn> request, IRequestOptions options = null) where TReturn : class { try { if (logger.IsDebugEnabled) { var debugMessage = request.GetDebugLogMessage(); if (!string.IsNullOrWhiteSpace(debugMessage)) { logger.Debug(debugMessage); } } if (logger.IsInfoEnabled) { var infoMessage = request.GetInfoLogMessage(); if (!string.IsNullOrEmpty(infoMessage)) { logger.Info(infoMessage); } } TReturn result = null; options = options ?? DefaultRequestOptions; var clientForRequest = PickClientForApiName(request.GetApiName()); RetryLogic.DoWithRetry(options.RetryAttempts, request.GetName(), () => result = request.GetSendFunc(clientForRequest)(), logger); return(result); } catch (WebServiceException webx) { string errorCode = string.Empty; if (!string.IsNullOrEmpty(webx.ErrorCode)) { errorCode = string.Format(" ({0})", webx.ErrorCode); } var msg = string.Format("{0} status: {1} ({2}) Message: {3}{4}", request.GetName(), webx.StatusCode, webx.StatusDescription, webx.ErrorMessage, errorCode); throw new BaseSpaceException(msg, webx.ErrorCode, webx); } catch (Exception x) { throw new BaseSpaceException(request.GetName() + " failed", string.Empty, x); } }
protected virtual void UploadPart(string fullUrl, FileInfo fileToUpload, long startPosition, int partNumber, ManualResetEvent errorSignal, string partDescription, uint chunkSize) { RetryLogic.DoWithRetry(ClientSettings.RetryAttempts, string.Format("Uploading part {0} of {1}", partDescription, fileToUpload.Name), () => { if (errorSignal.WaitOne(0)) { return; } using (var wc = new BSWebClient()) { byte[] data = null; try { data = BufferPool.GetChunk((int)chunkSize); var authentication = ClientSettings.Authentication; authentication.UpdateHttpHeader(wc.Headers, new Uri(fullUrl), "PUT"); int actualSize; int desiredSize = (int)Math.Min(fileToUpload.Length - startPosition, chunkSize); lock (_syncRead) // avoid thrashing the disk using (var fs = System.IO.File.Open(fileToUpload.FullName, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read)) { fs.Seek(startPosition, SeekOrigin.Begin); actualSize = fs.Read(data, 0, desiredSize); } if (actualSize != desiredSize) { throw new Exception("we didn't read what we expected from this file"); } if (actualSize != data.Length) { data = data.Take(actualSize).ToArray(); // TODO: Find a way to prevent creating sub-arrays (memory fragmentation) } Logger.InfoFormat("File Upload: {0}: Uploading part {1}", fileToUpload.Name, partDescription); wc.UploadData(fullUrl, "PUT", data); } finally { BufferPool.ReleaseChunk(data); } } }, Logger, error: () => errorSignal.Set()); // notify other threads to give up }
internal static TResult WrapResult <TResult>(Func <TResult> func, ILog logger, uint maxRetry, string name) { try { TResult result = default(TResult); RetryLogic.DoWithRetry(maxRetry, name, () => { result = func(); }, logger); return(result); } catch (WebServiceException wsex) { //TODO: wrap errors throw; } catch (BaseSpaceException) { //todo: eventually do something here throw; } catch (Exception) { throw; } }
public virtual TResult UploadFile <TResult>(FileUploadRequestBase <TResult> request) where TResult : FileResponse { Logger.DebugFormat("numthreads {0}", request.ThreadCount); TResult file = null; RetryLogic.DoWithRetry(ClientSettings.RetryAttempts, string.Format("Uploading file {0}", request.FileInfo.Name), () => { request.MultiPart = request.FileInfo.Length >= ClientSettings.FileUploadMultipartSizeThreshold; file = request.MultiPart.Value ? UploadFile_MultiPart(request) : WebClient.Send(request); }, Logger, retryHandler: (exc) => { var appExc = exc as ApplicationException; if (appExc != null && appExc.InnerException != null) { var wse = appExc.InnerException as WebServiceException; if (wse != null) { // we need to reupload the file with the conflict error if (wse.StatusCode == 409) { return(true); } } return(RetryLogic.GenericRetryHandler(wse)); } return(false); } ); return(file); }