public async Task <Result <AbsolutePath> > BackupAsync(OperationContext context, AbsolutePath instancePath, string?name = null) { int numCopiedFiles = 0; AbsolutePath?backupPath = null; return(await context.PerformOperationAsync(_tracer, async() => { var backupTime = _clock.UtcNow.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture); var backupName = backupTime; if (!string.IsNullOrEmpty(name)) { backupName += $"-{name}"; } backupPath = _backupPath / backupName; // Unlikely, but it is possible for GC to start running and think that it should purge this directory, // this avoids the scenario. using var _ = await _locks.AcquireAsync(backupPath); if (_fileSystem.DirectoryExists(backupPath)) { _fileSystem.DeleteDirectory(backupPath, DeleteOptions.All); } _fileSystem.CreateDirectory(backupPath); // See: https://github.com/facebook/rocksdb/wiki/rocksdb-basics#database-debug-logs _fileSystem.EnumerateFiles(instancePath, "*LOG*", false, fileInfo => { var fileName = fileInfo.FullPath.FileName; var targetFilePath = backupPath / fileName; // Do not use Async here: since EnumerateFiles takes an Action, making this async means we'll // need to make the action async as well, which is equivalent to an async void function. That // leads to race conditions. #pragma warning disable AsyncFixer02 // Long running or blocking operations under an async method _fileSystem.CopyFile(fileInfo.FullPath, targetFilePath, replaceExisting: true); #pragma warning restore AsyncFixer02 // Long running or blocking operations under an async method ++numCopiedFiles; }); if (numCopiedFiles == 0) { _fileSystem.DeleteDirectory(backupPath, DeleteOptions.All); } return new Result <AbsolutePath>(backupPath); }, extraEndMessage : _ => $"From=[{instancePath}] To=[{backupPath?.ToString() ?? "Unknown"}] NumCopiedFiles=[{numCopiedFiles}]"));
protected override async Task <BoolResult> StartupCoreAsync(OperationContext context) { await _container.CreateIfNotExistsAsync( accessType : BlobContainerPublicAccessType.Off, options : null, operationContext : null, cancellationToken : context.Token); // Any logs in the staging are basically lost: they were in memory only, and we crashed or failed as we // were writing them. We just recreate the directory. try { _fileSystem.DeleteDirectory(_configuration.StagingFolderPath, DeleteOptions.Recurse); } catch (DirectoryNotFoundException) { } _fileSystem.CreateDirectory(_configuration.StagingFolderPath); _fileSystem.CreateDirectory(_configuration.UploadFolderPath); _writeQueue.Start(WriteBatchAsync); _uploadQueue.Start(UploadBatchAsync); return(RecoverFromCrash(context)); }
/// <summary> /// Remove all contents, subdirectories and files, from a directory. /// </summary> public static void ClearDirectory(this IAbsFileSystem fileSystem, AbsolutePath path, DeleteOptions deleteOptions) { Contract.Requires(fileSystem != null); Contract.Requires(path != null); if (fileSystem.FileExists(path)) { throw new IOException("not a directory"); } var subDirectories = fileSystem.EnumerateDirectories(path, EnumerateOptions.None); if ((deleteOptions & DeleteOptions.Recurse) != 0) { foreach (AbsolutePath directoryPath in subDirectories) { fileSystem.DeleteDirectory(directoryPath, deleteOptions); } } else if (subDirectories.Any()) { throw new IOException("subdirectories not deleted without recurse option"); } foreach (FileInfo fileInfo in fileSystem.EnumerateFiles(path, EnumerateOptions.None)) { fileSystem.DeleteFile(fileInfo.FullPath); } }
public async Task <Result <AbsolutePath> > BackupAsync(OperationContext context, AbsolutePath instancePath, string?name = null) { int numCopiedFiles = 0; AbsolutePath?backupPath = null; return(await context.PerformOperationAsync(_tracer, async() => { var backupTime = _clock.UtcNow.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture); var backupName = backupTime; if (!string.IsNullOrEmpty(name)) { backupName += $"-{name}"; } backupPath = _backupPath / backupName; // Unlikely, but it is possible for GC to start running and think that it should purge this directory, // this avoids the scenario. using var _ = await _locks.AcquireAsync(backupPath); if (_fileSystem.DirectoryExists(backupPath)) { _fileSystem.DeleteDirectory(backupPath, DeleteOptions.All); } _fileSystem.CreateDirectory(backupPath); // See: https://github.com/facebook/rocksdb/wiki/rocksdb-basics#database-debug-logs _fileSystem.EnumerateFiles(instancePath, "*LOG*", false, async fileInfo => { var fileName = fileInfo.FullPath.FileName; var targetFilePath = backupPath / fileName; await _fileSystem.CopyFileAsync(fileInfo.FullPath, targetFilePath, replaceExisting: true); ++numCopiedFiles; }); if (numCopiedFiles == 0) { _fileSystem.DeleteDirectory(backupPath, DeleteOptions.All); } return new Result <AbsolutePath>(backupPath); }, extraEndMessage : _ => $"From=[{instancePath}] To=[{backupPath?.ToString() ?? "Unknown"}] NumCopiedFiles=[{numCopiedFiles}]"));
/// <inheritdoc /> public void Dispose() { try { if (_fileSystem.DirectoryExists(Path)) { _fileSystem.DeleteDirectory(Path, DeleteOptions.All); } } catch (Exception exception) { Debug.WriteLine("Unable to cleanup due to exception: {0}", exception); } }
protected override async Task <BoolResult> StartupCoreAsync(OperationContext context) { await _store.StartupAsync(context).ThrowIfFailure(); if (_fileSystem.DirectoryExists(_rootPath / "temp")) { _fileSystem.DeleteDirectory(_rootPath / "temp", DeleteOptions.All); } await _copier.StartupAsync(context).ThrowIfFailure(); CreateSessionResult <IContentSession> sessionResult = _store.CreateSession(context, SessionName, ImplicitPin.None).ThrowIfFailure(); _session = sessionResult.Session !; return(await _session.StartupAsync(context)); }