Beispiel #1
0
        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);
            }
        }
Beispiel #4
0
        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}]"));
Beispiel #5
0
 /// <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);
     }
 }
Beispiel #6
0
        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));
        }