/// <summary> /// Restores the checkpoint for a given checkpoint id. /// </summary> public Task <BoolResult> RestoreCheckpointAsync(OperationContext context, string checkpointId) { context = context.CreateNested(); return(context.PerformOperationAsync( _tracer, async() => { bool successfullyUpdatedIncrementalState = false; try { bool isIncrementalCheckpoint = false; var checkpointFileExtension = ".zip"; if (checkpointId.EndsWith(IncrementalCheckpointIdSuffix, StringComparison.OrdinalIgnoreCase)) { isIncrementalCheckpoint = true; checkpointFileExtension = ".txt"; // Remove the suffix to get the real checkpoint id used with central storage checkpointId = checkpointId.Substring(0, checkpointId.Length - IncrementalCheckpointIdSuffix.Length); } var checkpointFile = _checkpointStagingDirectory / $"chkpt{checkpointFileExtension}"; var extractedCheckpointDirectory = _checkpointStagingDirectory / "chkpt"; FileUtilities.DeleteDirectoryContents(_checkpointStagingDirectory.ToString()); FileUtilities.DeleteDirectoryContents(extractedCheckpointDirectory.ToString()); // Creating a working temporary folder using (new DisposableDirectory(_fileSystem, _checkpointStagingDirectory)) { // Getting the checkpoint from the central store await _storage.TryGetFileAsync(context, checkpointId, checkpointFile).ThrowIfFailure(); if (isIncrementalCheckpoint) { var incrementalRestoreResult = await RestoreCheckpointIncrementalAsync(context, checkpointFile, extractedCheckpointDirectory); successfullyUpdatedIncrementalState = incrementalRestoreResult.Succeeded; incrementalRestoreResult.ThrowIfFailure(); } else { RestoreFullCheckpointAsync(checkpointFile, extractedCheckpointDirectory); } // Restoring the checkpoint return _database.RestoreCheckpoint(context, extractedCheckpointDirectory); } } finally { ClearIncrementalCheckpointStateIfNeeded(context, successfullyUpdatedIncrementalState); } }, extraStartMessage: $"CheckpointId=[{checkpointId}]", extraEndMessage: _ => $"CheckpointId=[{checkpointId}]")); }
/// <summary> /// Restores the checkpoint for a given checkpoint id. /// </summary> public Task <BoolResult> RestoreCheckpointAsync(OperationContext context, CheckpointState checkpointState) { context = context.CreateNested(nameof(CheckpointManager)); var checkpointId = checkpointState.CheckpointId; return(context.PerformOperationWithTimeoutAsync( _tracer, async nestedContext => { bool successfullyUpdatedIncrementalState = false; try { bool isIncrementalCheckpoint = false; var checkpointFileExtension = ".zip"; if (checkpointId.EndsWith(IncrementalCheckpointIdSuffix, StringComparison.OrdinalIgnoreCase)) { isIncrementalCheckpoint = true; checkpointFileExtension = ".txt"; // Remove the suffix to get the real checkpoint id used with central storage checkpointId = checkpointId.Substring(0, checkpointId.Length - IncrementalCheckpointIdSuffix.Length); } var checkpointFile = _checkpointStagingDirectory / $"chkpt{checkpointFileExtension}"; var extractedCheckpointDirectory = _checkpointStagingDirectory / "chkpt"; FileUtilities.DeleteDirectoryContents(_checkpointStagingDirectory.ToString()); FileUtilities.DeleteDirectoryContents(extractedCheckpointDirectory.ToString()); // Creating a working temporary folder using (new DisposableDirectory(_fileSystem, _checkpointStagingDirectory)) { // Getting the checkpoint from the central store await _storage.TryGetFileAsync(nestedContext, checkpointId, checkpointFile, isImmutable: true).ThrowIfFailure(); if (isIncrementalCheckpoint) { var incrementalRestoreResult = await RestoreCheckpointIncrementalAsync(nestedContext, checkpointFile, extractedCheckpointDirectory); incrementalRestoreResult.ThrowIfFailure(); } else { RestoreFullCheckpoint(checkpointFile, extractedCheckpointDirectory); } // Restoring the checkpoint _database.RestoreCheckpoint(nestedContext, extractedCheckpointDirectory).ThrowIfFailure(); // Save latest checkpoint info to file in case we get restarded and want to know about the previous checkpoint. WriteLatestCheckpoint(nestedContext, checkpointState); successfullyUpdatedIncrementalState = true; return BoolResult.Success; } } finally { ClearIncrementalCheckpointStateIfNeeded(nestedContext, successfullyUpdatedIncrementalState); } }, extraStartMessage: $"CheckpointId=[{checkpointId}]", extraEndMessage: _ => $"CheckpointId=[{checkpointId}]", timeout: _configuration.RestoreCheckpointTimeout)); }