/// <summary> /// Uploads the file using the given metadata. /// /// </summary> /// <param name="metadata"></param> private void UploadFile(UploadMetadata metadata) { try { //we need to override the default .NET value for max connections to a host to our number of threads, if necessary (otherwise we won't achieve the parallelism we want) _previousDefaultConnectionLimit = ServicePointManager.DefaultConnectionLimit; ServicePointManager.DefaultConnectionLimit = Math.Max(this.Parameters.ThreadCount, ServicePointManager.DefaultConnectionLimit); //match up the metadata with the information on the server if (this.Parameters.IsResume) { ValidateMetadataForResume(metadata); } else { ValidateMetadataForFreshUpload(metadata); } var segmentProgressTracker = CreateSegmentProgressTracker(metadata); if (metadata.SegmentCount == 0) { // simply create the target stream, overwriting existing streams if they exist _frontEnd.CreateStream(metadata.TargetStreamPath, true, null, 0); } else if (metadata.SegmentCount > 1) { //perform the multi-segment upload var msu = new MultipleSegmentUploader(metadata, this.Parameters.ThreadCount, _frontEnd, _token, segmentProgressTracker); msu.UseSegmentBlockBackOffRetryStrategy = this.Parameters.UseSegmentBlockBackOffRetryStrategy; msu.Upload(); //concatenate the files at the end ConcatenateSegments(metadata); } else { //optimization if we only have one segment: upload it directly to the target stream metadata.Segments[0].Path = metadata.TargetStreamPath; var ssu = new SingleSegmentUploader(0, metadata, _frontEnd, _token, segmentProgressTracker); ssu.UseBackOffRetryStrategy = this.Parameters.UseSegmentBlockBackOffRetryStrategy; ssu.Upload(); } } catch (OperationCanceledException) { // do nothing since we have already marked everything as failed } finally { //revert back the default .NET value for max connections to a host to whatever it was before ServicePointManager.DefaultConnectionLimit = _previousDefaultConnectionLimit; } }
/// <summary> /// Uploads the buffer. /// </summary> /// <param name="buffer">The buffer.</param> /// <param name="bytesToCopy">The bytes to copy.</param> /// <param name="targetStreamOffset">The target stream offset.</param> /// <returns></returns> private long UploadBuffer(byte[] buffer, int bytesToCopy, long targetStreamOffset) { //append it to the remote stream int attemptCount = 0; bool uploadCompleted = false; while (!uploadCompleted && attemptCount < MaxBufferUploadAttemptCount) { _token.ThrowIfCancellationRequested(); attemptCount++; try { if (targetStreamOffset == 0) { _frontEnd.CreateStream(_segmentMetadata.Path, true, buffer, bytesToCopy); } else { _frontEnd.AppendToStream(_segmentMetadata.Path, buffer, targetStreamOffset, bytesToCopy); } uploadCompleted = true; targetStreamOffset += bytesToCopy; ReportProgress(targetStreamOffset, false); } catch { //if we tried more than the number of times we were allowed to, give up and throw the exception if (attemptCount >= MaxBufferUploadAttemptCount) { ReportProgress(targetStreamOffset, true); throw; } else { WaitForRetry(attemptCount, this.UseBackOffRetryStrategy, _token); } } } return(targetStreamOffset); }
/// <summary> /// Uploads the buffer. /// </summary> /// <param name="buffer">The buffer.</param> /// <param name="bytesToCopy">The bytes to copy.</param> /// <param name="targetStreamOffset">The target stream offset.</param> /// <returns></returns> private long UploadBuffer(byte[] buffer, int bytesToCopy, long targetStreamOffset) { //append it to the remote stream int attemptCount = 0; bool uploadCompleted = false; while (!uploadCompleted && attemptCount < MaxBufferUploadAttemptCount) { _token.ThrowIfCancellationRequested(); attemptCount++; try { if (targetStreamOffset == 0) { _frontEnd.CreateStream(_segmentMetadata.Path, true, buffer, bytesToCopy); } else { _frontEnd.AppendToStream(_segmentMetadata.Path, buffer, targetStreamOffset, bytesToCopy); } uploadCompleted = true; targetStreamOffset += bytesToCopy; ReportProgress(targetStreamOffset, false); } catch (AggregateException e) { if (e.InnerExceptions.Count == 1 && e.InnerException is AdlsErrorException) { if (((AdlsErrorException)e.InnerException).Body.RemoteException is AdlsBadOffsetException) { // this means we tried to re-upload at the same location and the upload actually succeeded, which means we should move on. uploadCompleted = true; targetStreamOffset += bytesToCopy; ReportProgress(targetStreamOffset, false); } else { //if we tried more than the number of times we were allowed to, give up and throw the exception if (attemptCount >= MaxBufferUploadAttemptCount) { ReportProgress(targetStreamOffset, true); throw e; } else { WaitForRetry(attemptCount, this.UseBackOffRetryStrategy, _token); } } } else { //if we tried more than the number of times we were allowed to, give up and throw the exception if (attemptCount >= MaxBufferUploadAttemptCount) { ReportProgress(targetStreamOffset, true); throw e; } else { WaitForRetry(attemptCount, this.UseBackOffRetryStrategy, _token); } } } catch (AdlsErrorException e) { if (e.Body.RemoteException is AdlsBadOffsetException) { // this means we tried to re-upload at the same location and the upload actually succeeded, which means we should move on. uploadCompleted = true; targetStreamOffset += bytesToCopy; ReportProgress(targetStreamOffset, false); } else { //if we tried more than the number of times we were allowed to, give up and throw the exception if (attemptCount >= MaxBufferUploadAttemptCount) { ReportProgress(targetStreamOffset, true); throw e; } else { WaitForRetry(attemptCount, this.UseBackOffRetryStrategy, _token); } } } catch (Exception ex) { //if we tried more than the number of times we were allowed to, give up and throw the exception if (attemptCount >= MaxBufferUploadAttemptCount) { ReportProgress(targetStreamOffset, true); throw ex; } else { WaitForRetry(attemptCount, this.UseBackOffRetryStrategy, _token); } } } return(targetStreamOffset); }