示例#1
0
        /// <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);
        }
示例#3
0
        /// <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);
        }