public async Task DeleteAsync(Guid id) { var job = state.Value.Jobs.FirstOrDefault(x => x.Id == id); if (job == null) { throw new DomainObjectNotFoundException(id.ToString(), typeof(IBackupJob)); } if (currentJob == job) { currentTask?.Cancel(); } else { var jobId = job.Id.ToString(); await Safe.DeleteAsync(backupArchiveLocation, jobId, log); await Safe.DeleteAsync(assetStore, jobId, log); state.Value.Jobs.Remove(job); await state.WriteAsync(); } }
private async Task CleanupAsync() { await Safe.DeleteAsync(backupArchiveLocation, CurrentJob.Id, log); if (CurrentJob.AppId != Guid.Empty) { foreach (var handler in handlers) { await Safe.CleanupRestoreAsync(handler, CurrentJob.AppId, CurrentJob.Id, log); } } }
private async Task CleanupAsync(IEnumerable <BackupHandler> handlers) { await Safe.DeleteAsync(backupArchiveLocation, CurrentJob.Id.ToString(), log); if (CurrentJob.AppId != Guid.Empty) { foreach (var handler in handlers) { await Safe.CleanupRestoreErrorAsync(handler, CurrentJob.AppId, CurrentJob.Id, log); } } }
private async Task RecoverAfterRestartAsync() { foreach (var job in state.Jobs) { if (!job.Stopped.HasValue) { job.Stopped = clock.GetCurrentInstant(); await Safe.DeleteAsync(backupArchiveLocation, job.Id, log); await Safe.DeleteAsync(assetStore, job.Id, log); job.Status = JobStatus.Failed; await WriteAsync(); } } }
private async Task ProcessAsync(BackupStateJob job, CancellationToken ct) { var jobId = job.Id.ToString(); var handlers = CreateHandlers(); var lastTimestamp = job.Started; try { using (var stream = await backupArchiveLocation.OpenStreamAsync(jobId)) { using (var writer = new BackupWriter(serializer, stream, true)) { await eventStore.QueryAsync(async storedEvent => { var @event = eventDataFormatter.Parse(storedEvent.Data); writer.WriteEvent(storedEvent); foreach (var handler in handlers) { await handler.BackupEventAsync(@event, Key, writer); } job.HandledEvents = writer.WrittenEvents; job.HandledAssets = writer.WrittenAttachments; lastTimestamp = await WritePeriodically(lastTimestamp); }, SquidexHeaders.AppId, Key.ToString(), null, ct); foreach (var handler in handlers) { await handler.BackupAsync(Key, writer); } foreach (var handler in handlers) { await handler.CompleteBackupAsync(Key, writer); } } stream.Position = 0; ct.ThrowIfCancellationRequested(); await assetStore.UploadAsync(jobId, 0, null, stream, false, ct); } job.Status = JobStatus.Completed; } catch (Exception ex) { log.LogError(ex, jobId, (ctx, w) => w .WriteProperty("action", "makeBackup") .WriteProperty("status", "failed") .WriteProperty("backupId", ctx)); job.Status = JobStatus.Failed; } finally { await Safe.DeleteAsync(backupArchiveLocation, jobId, log); job.Stopped = clock.GetCurrentInstant(); await state.WriteAsync(); currentTask = null; currentJob = null; } }
public async Task RunAsync() { if (currentTask != null) { throw new DomainException("Another backup process is already running."); } if (state.Jobs.Count >= MaxBackups) { throw new DomainException($"You cannot have more than {MaxBackups} backups."); } var job = new BackupStateJob { Id = Guid.NewGuid(), Started = clock.GetCurrentInstant(), Status = JobStatus.Started }; currentTask = new CancellationTokenSource(); currentJob = job; var lastTimestamp = job.Started; state.Jobs.Insert(0, job); await WriteAsync(); try { using (var stream = await backupArchiveLocation.OpenStreamAsync(job.Id)) { using (var writer = new BackupWriter(serializer, stream, true)) { await eventStore.QueryAsync(async storedEvent => { var @event = eventDataFormatter.Parse(storedEvent.Data); writer.WriteEvent(storedEvent); foreach (var handler in handlers) { await handler.BackupEventAsync(@event, appId, writer); } job.HandledEvents = writer.WrittenEvents; job.HandledAssets = writer.WrittenAttachments; lastTimestamp = await WritePeriodically(lastTimestamp); }, SquidexHeaders.AppId, appId.ToString(), null, currentTask.Token); foreach (var handler in handlers) { await handler.BackupAsync(appId, writer); } foreach (var handler in handlers) { await handler.CompleteBackupAsync(appId, writer); } } stream.Position = 0; currentTask.Token.ThrowIfCancellationRequested(); await assetStore.UploadAsync(job.Id.ToString(), 0, null, stream, currentTask.Token); } job.Status = JobStatus.Completed; } catch (Exception ex) { log.LogError(ex, w => w .WriteProperty("action", "makeBackup") .WriteProperty("status", "failed") .WriteProperty("backupId", job.Id.ToString())); job.Status = JobStatus.Failed; } finally { await Safe.DeleteAsync(backupArchiveLocation, job.Id, log); job.Stopped = clock.GetCurrentInstant(); await WriteAsync(); currentTask = null; currentJob = null; } }