diff --git a/PowerSync/PowerSync.Common/Attachments/SyncingService.cs b/PowerSync/PowerSync.Common/Attachments/SyncingService.cs index 12dcaea..7dfdf74 100644 --- a/PowerSync/PowerSync.Common/Attachments/SyncingService.cs +++ b/PowerSync/PowerSync.Common/Attachments/SyncingService.cs @@ -113,40 +113,36 @@ private async Task StopSyncInternalAsync() /// Runs one sync pass: fetches active attachments, processes them, then prunes archived rows. /// /// A task that completes when the pass has finished. - public Task RunSyncPassAsync() => attachmentService.WithContextAsync(async ctx => + public async Task RunSyncPassAsync() { - var active = await ctx.GetActiveAttachmentsAsync(); - await ProcessAttachmentsAsync(active, ctx); - await DeleteArchivedAttachmentsAsync(ctx); - }); + var active = await attachmentService.WithContextAsync(ctx => ctx.GetActiveAttachmentsAsync()); + await ProcessAttachmentsAsync(active); + await attachmentService.WithContextAsync(ctx => DeleteArchivedAttachmentsAsync(ctx)); + } /// - /// Processes attachments based on their state. Updates are saved in a single batch. + /// Processes attachments based on their state. Each state change is persisted as soon as its + /// transfer completes. /// /// Attachment records to process. - /// Attachment context for database operations. - /// A task that completes once all attachments have been processed and saved. - public async Task ProcessAttachmentsAsync(IReadOnlyList attachments, AttachmentContext context) + /// A task that completes once all attachments have been processed. + public async Task ProcessAttachmentsAsync(IReadOnlyList attachments) { - var updates = new List(); - foreach (var attachment in attachments) { Attachment? changed = attachment.State switch { AttachmentState.QueuedUpload => await UploadAttachmentAsync(attachment), AttachmentState.QueuedDownload => await DownloadAttachmentAsync(attachment), - AttachmentState.QueuedDelete => await DeleteAttachmentAsync(attachment, context), + AttachmentState.QueuedDelete => await DeleteAttachmentAsync(attachment), _ => null, }; if (changed is not null) { - updates.Add(changed); + await attachmentService.WithContextAsync(ctx => ctx.SaveAttachmentsAsync([changed])); } } - - await context.SaveAttachmentsAsync(updates); } /// @@ -231,9 +227,8 @@ public async Task ProcessAttachmentsAsync(IReadOnlyList attachments, /// On failure, defers to or archives. /// /// The attachment to delete. - /// The attachment context for database operations. /// The archived attachment, or null on success or retry. - public async Task DeleteAttachmentAsync(Attachment attachment, AttachmentContext context) + public async Task DeleteAttachmentAsync(Attachment attachment) { try { @@ -243,7 +238,7 @@ public async Task ProcessAttachmentsAsync(IReadOnlyList attachments, await localStorage.DeleteFileAsync(attachment.LocalUri); } - await context.DeleteAttachmentAsync(attachment.Id); + await attachmentService.WithContextAsync(ctx => ctx.DeleteAttachmentAsync(attachment.Id)); return null; } catch (Exception error)