Skip to content

Commit 2734b4f

Browse files
authored
[Storage] [DataMovement] Fix Pause and Resume on Cleaning up unfinished transfers during a Pause (Azure#47521)
* WIP * Fixed bug where delete was using an already invoked cancellation token, failing the cancellation * Cleanup * Update tests * Change finally block to catch block
1 parent 3019474 commit 2734b4f

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

sdk/storage/Azure.Storage.DataMovement/src/JobPartInternal.cs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,6 @@ await PartTransferStatusEventHandler.RaiseAsync(
441441
{
442442
await TriggerCancellationAsync().ConfigureAwait(false);
443443
}
444-
await CheckAndUpdateCancellationStateAsync().ConfigureAwait(false);
445444
}
446445
catch (Exception cancellationException)
447446
{
@@ -460,6 +459,31 @@ await TransferFailedEventHandler.RaiseAsync(
460459
ClientDiagnostics)
461460
.ConfigureAwait(false);
462461
}
462+
463+
// Whether or not we were able to trigger the cancellation and successfully clean up
464+
// we should always call CheckAndUpdateCancellationStateAsync to correctly make
465+
// sure the job part is in the correct state.
466+
try
467+
{
468+
await CheckAndUpdateCancellationStateAsync().ConfigureAwait(false);
469+
}
470+
catch (Exception checkUpdateException)
471+
{
472+
// If an exception is thrown while trying to clean up,
473+
// raise the failed event and prevent the transfer from hanging
474+
await TransferFailedEventHandler.RaiseAsync(
475+
new TransferItemFailedEventArgs(
476+
_dataTransfer.Id,
477+
_sourceResource,
478+
_destinationResource,
479+
checkUpdateException,
480+
false,
481+
_cancellationToken),
482+
nameof(JobPartInternal),
483+
nameof(TransferFailedEventHandler),
484+
ClientDiagnostics)
485+
.ConfigureAwait(false);
486+
}
463487
}
464488

465489
/// <summary>
@@ -472,12 +496,25 @@ public async virtual Task CleanupAbortedJobPartAsync()
472496
// If the failure occurred due to the file already existing or authentication,
473497
// and overwrite wasn't enabled, don't delete the existing file. We can remove
474498
// the unfinished file for other error types.
475-
if (JobPartFailureType.Other == _failureType)
499+
// If a Pause was called, we can remove the unfinished file.
500+
if (JobPartFailureType.Other == _failureType || DataTransferState.Pausing == JobPartStatus.State)
476501
{
477502
// If the job part is paused or ended with failures
478503
// delete the destination resource because it could be unfinished or corrupted
479504
// If we resume we would have to start from the beginning anyways.
480-
await _destinationResource.DeleteIfExistsAsync(_cancellationToken).ConfigureAwait(false);
505+
try
506+
{
507+
// We can't pass the cancellation token
508+
// here due to the fact that the job's cancellation token has already been called.
509+
// We are cleaning up / deleting optimistically, which means that if
510+
// the clean / delete attempt fails, then we continue on. The failure may be due
511+
// to the overall reason why the job was cancelled in the first place.
512+
await _destinationResource.DeleteIfExistsAsync().ConfigureAwait(false);
513+
}
514+
catch
515+
{
516+
// We are cleaning up / deleting optimistically, move on if it fails.
517+
}
481518
}
482519
}
483520

sdk/storage/Azure.Storage.DataMovement/tests/TransferManagerTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,11 +532,11 @@ public async Task TransferFailAtPartProcess(
532532
Assert.That(transfer.TransferStatus.HasFailedItems);
533533
Assert.That(failures, Is.Not.Empty);
534534

535-
Assert.That(capturedTransferStatuses.Count, Is.EqualTo(3)); // TODO should be 4
535+
Assert.That(capturedTransferStatuses.Count, Is.EqualTo(4));
536536
Assert.That(capturedTransferStatuses[0].State, Is.EqualTo(DataTransferState.InProgress));
537537
Assert.That(capturedTransferStatuses[1].State, Is.EqualTo(DataTransferState.InProgress));
538538
Assert.That(capturedTransferStatuses[2].State, Is.EqualTo(DataTransferState.Stopping));
539-
//Assert.That(capturedTransferStatuses[3].IsCompletedWithFailedItems); // TODO this should exist
539+
Assert.That(capturedTransferStatuses[3].IsCompletedWithFailedItems);
540540
}
541541

542542
[Test]

0 commit comments

Comments
 (0)