Beispiel #1
0
        public async Task <BackblazeApiResponse <UploadPartUrlOutputDTO> > GetUploadPartUrlAsync(
            AuthorizationOutputDTO auth,
            FileDataOutputDTO uploadData,
            CancellationToken cancellationToken = default(CancellationToken)
            )
        {
            var body = SerializeToJsonContent(new UploadPartUrlInputDTO()
            {
                FileId = uploadData.FileId
            });

            var request = new HttpRequestMessage
            {
                Method     = HttpMethod.Post,
                RequestUri = new Uri($"{auth.ApiUrl}/b2api/v2/b2_get_upload_part_url"),
                Content    = body
            };

            request.Headers.TryAddWithoutValidation("Authorization", auth.AuthorizationToken);

            var response = await _client.SendAsync(request, cancellationToken);

            string responseJson = await response.Content.ReadAsStringAsync();

            if (!response.IsSuccessStatusCode)
            {
                return(new BackblazeApiResponse <UploadPartUrlOutputDTO>()
                {
                    Succeeded = response.IsSuccessStatusCode,
                    Error = JsonSerializer.Deserialize <B2ErrorResponseOutputDTO>(responseJson)
                });
            }

            return(new BackblazeApiResponse <UploadPartUrlOutputDTO>()
            {
                Succeeded = response.IsSuccessStatusCode,
                Data = JsonSerializer.Deserialize <UploadPartUrlOutputDTO>(responseJson)
            });
        }
        public async Task <BackblazeApiResponse <FileDataOutputDTO>[]> UploadDynamicBatchAsync(
            AuthorizationOutputDTO auth,
            IEnumerable <UploadFile> files,
            IProgress <TransferProgress> progressData = null,
            int retryTimeoutCount = 5,
            int concurrentUploads = 4,
            string tempDir        = "/tmp",
            CancellationToken cancellationToken = default(CancellationToken)
            )
        {
            FileDataOutputDTO[] result = new FileDataOutputDTO[files.Count()];
            Task <BackblazeApiResponse <FileDataOutputDTO> >[] uploadTasks = new Task <BackblazeApiResponse <FileDataOutputDTO> > [files.Count()];
            Dictionary <string, FileProgress> fileProgress = new Dictionary <string, FileProgress>();

            foreach (var file in files)
            {
                long fileSize = new FileInfo(file.sourceFilePath).Length;

                fileProgress.Add(file.destinationFilename, new FileProgress(filename: file.destinationFilename, totalBytes: fileSize));
            }

            int fileI = 0;

            foreach (var file in files)
            {
                long fileSize = new FileInfo(file.sourceFilePath).Length;

                if (fileSize > auth.RecommendedPartSize)
                {
                    uploadTasks[fileI] = ProcessLargeUploadAsync(
                        auth: auth,
                        file: file,
                        fileProgress: fileProgress,
                        fileSize: fileSize,
                        progressData: progressData,
                        retryTimeoutCount: retryTimeoutCount,
                        cancellationToken: cancellationToken
                        );
                }
                else
                {
                    uploadTasks[fileI] = ProcessSmallUploadAsync(
                        auth: auth,
                        file: file,
                        fileProgress: fileProgress,
                        progressData: progressData,
                        retryTimeoutCount: retryTimeoutCount,
                        cancellationToken: cancellationToken
                        );
                }

                fileI++;
            }

            SemaphoreSlim throttler = new SemaphoreSlim(concurrentUploads, concurrentUploads);
            IEnumerable <Task <BackblazeApiResponse <FileDataOutputDTO> > > tasks = uploadTasks.Select(async input =>
            {
                await throttler.WaitAsync();
                try
                {
                    return(await input);
                }
                finally
                {
                    throttler.Release();
                }
            });

            return(await Task.WhenAll(tasks));
        }
Beispiel #3
0
        public async Task <BackblazeApiResponse <UploadedPartOutputDTO> > UploadLargeFilePartAsync(
            AuthorizationOutputDTO auth,
            FileDataOutputDTO fileData,
            Stream partStream,
            int partNumber,
            int retryTimeoutCount = 5,
            IProgress <FilePartProgress> progressData = null,
            CancellationToken cancellationToken       = default(CancellationToken)
            )
        {
            if (partStream == null)
            {
                throw new NullReferenceException("partStream");
            }

            if (!partStream.CanRead)
            {
                throw new InvalidDataException();
            }

            int retryCount = 0;

Retry:
            var uploadUrlResponse = await GetUploadPartUrlAsync(auth, fileData, cancellationToken);

            if (!uploadUrlResponse.Succeeded)
            {
                return(new BackblazeApiResponse <UploadedPartOutputDTO>()
                {
                    Succeeded = uploadUrlResponse.Succeeded,
                    Error = uploadUrlResponse.Error
                });
            }

            UploadedPartOutputDTO uploadPart = null;
            var uploadPartResponse           = await UploadLargeFilePartAsync(uploadUrlResponse.Data, partStream, fileData.FileName, partNumber, progressData, cancellationToken);

            if (uploadPartResponse.Succeeded)
            {
                uploadPart = uploadPartResponse.Data;
            }
            else
            {
                if (ErrorHelper.IsRecoverableError(uploadPartResponse.Error))
                {
                    if (retryCount > retryTimeoutCount)
                    {
                        uploadPartResponse.Error.Message = $"Hit retry max on error: {uploadPartResponse.Error.Message}";

                        return(new BackblazeApiResponse <UploadedPartOutputDTO>()
                        {
                            Succeeded = false,
                            Error = uploadPartResponse.Error
                        });
                    }

                    retryCount++;
                    goto Retry;
                }
                else
                {
                    return(new BackblazeApiResponse <UploadedPartOutputDTO>()
                    {
                        Succeeded = false,
                        Error = uploadPartResponse.Error
                    });
                }
            }

            return(new BackblazeApiResponse <UploadedPartOutputDTO>()
            {
                Succeeded = uploadUrlResponse.Succeeded,
                Data = uploadPart
            });
        }
Beispiel #4
0
        /// <summary>
        /// Upload a file with attempted recovery from errors
        /// </summary>
        public async Task <BackblazeApiResponse <FileDataOutputDTO> > UploadSmallFileAsync(
            AuthorizationOutputDTO auth,
            string bucketId,
            string sourcePath,
            string destinationFilename,
            int retryTimeoutCount = 5,
            IProgress <FileProgress> progressData = null,
            CancellationToken cancellationToken   = default(CancellationToken)
            )
        {
            int retryCount = 0;

Retry:
            var uploadUrlResponse = await GetUploadUrlAsync(auth, bucketId, cancellationToken);

            if (!uploadUrlResponse.Succeeded)
            {
                return(new BackblazeApiResponse <FileDataOutputDTO>()
                {
                    Succeeded = uploadUrlResponse.Succeeded,
                    Error = uploadUrlResponse.Error
                });
            }

            FileDataOutputDTO uploadData = null;
            var uploadDataResponse       = await UploadSmallFileAsync(uploadUrlResponse.Data, sourcePath, destinationFilename, progressData, cancellationToken);

            if (uploadDataResponse.Succeeded)
            {
                uploadData = uploadDataResponse.Data;
            }
            else
            {
                if (ErrorHelper.IsRecoverableError(uploadDataResponse.Error))
                {
                    if (retryCount > retryTimeoutCount)
                    {
                        uploadDataResponse.Error.Message = $"Hit retry max on error: {uploadDataResponse.Error.Message}";

                        return(new BackblazeApiResponse <FileDataOutputDTO>()
                        {
                            Succeeded = false,
                            Error = uploadDataResponse.Error
                        });
                    }

                    retryCount++;
                    goto Retry;
                }
                else
                {
                    return(new BackblazeApiResponse <FileDataOutputDTO>()
                    {
                        Succeeded = false,
                        Error = uploadDataResponse.Error
                    });
                }
            }

            return(new BackblazeApiResponse <FileDataOutputDTO>()
            {
                Succeeded = uploadDataResponse.Succeeded,
                Data = uploadData
            });
        }