예제 #1
0
        /// <summary>
        /// Sends the transfer payload to the target providers.
        /// </summary>
        /// <param name="file"></param>
        /// <param name="source"></param>
        /// <param name="payload"></param>
        /// <param name="cancelToken"></param>
        /// <returns></returns>
        private async Task SendTransferPayloadToFileTargetsAsync(BackupFile file, SourceLocation source, TransferPayload payload, CancellationToken cancelToken)
        {
            var directory = await Database.GetDirectoryMapItemAsync(file.Directory).ConfigureAwait(false);

            foreach (var providerName in payload.DestinationProviders)
            {
                var destination = Providers[providerName];

                try
                {
                    // upload this chunk to the destination cloud provider.
                    // note: the provider implementation will automatically handle retries of transient issues.
                    await destination.UploadFileBlockAsync(file, source, directory,
                                                           payload.Data, (int)payload.CurrentBlockNumber, (int)payload.TotalBlocks, cancelToken).ConfigureAwait(false);

                    // flag the chunk as sent in the file status.
                    file.SetBlockAsSent((int)payload.CurrentBlockNumber, providerName);
                }
                catch (OperationCanceledException)
                {
                    // cancellation was requested.
                    // bubble up to the next level.
                    throw;
                }
                catch (Exception ex)
                {
                    Logger.WriteTraceError("An error occurred during a file transfer.", ex, Logger.GenerateFullContextStackTrace(), InstanceID);
                    file.SetProviderToFailed(providerName);

                    // sets the error message/stack trace
                    await Database.SetBackupFileAsFailedAsync(file, ex.ToString()).ConfigureAwait(false);

                    await Database.RemoveFileFromBackupQueueAsync(file).ConfigureAwait(false);
                }
                finally
                {
                    // commit the status changes to the local state database.
                    await Database.UpdateBackupFileCopyStateAsync(file).ConfigureAwait(false);
                }
            }
        }