diff --git a/packages/services/src/Domain/Sync/SyncBackoffService.ts b/packages/services/src/Domain/Sync/SyncBackoffService.ts index d0fdfb664fb..08fd6e6db39 100644 --- a/packages/services/src/Domain/Sync/SyncBackoffService.ts +++ b/packages/services/src/Domain/Sync/SyncBackoffService.ts @@ -6,7 +6,7 @@ import { AbstractService } from '../Service/AbstractService' import { InternalEventHandlerInterface } from '../Internal/InternalEventHandlerInterface' import { InternalEventBusInterface } from '../Internal/InternalEventBusInterface' import { InternalEventInterface } from '../Internal/InternalEventInterface' -import { ApplicationEvent } from '../Event/ApplicationEvent' +import { SyncEvent } from '../Event/SyncEvent' export class SyncBackoffService extends AbstractService @@ -63,12 +63,18 @@ export class SyncBackoffService } async handleEvent(event: InternalEventInterface): Promise { - if (event.type === ApplicationEvent.CompletedIncrementalSync) { - for (const payload of (event.payload as Record) - .uploadedPayloads as ServerSyncPushContextualPayload[]) { - this.backoffPenalties.delete(payload.uuid) - this.backoffStartTimestamps.delete(payload.uuid) - } + if ( + event.type !== SyncEvent.PaginatedSyncRequestCompleted || + event.payload === undefined || + (event.payload as Record).uploadedPayloads === undefined + ) { + return + } + + for (const payload of (event.payload as Record) + .uploadedPayloads as ServerSyncPushContextualPayload[]) { + this.backoffPenalties.delete(payload.uuid) + this.backoffStartTimestamps.delete(payload.uuid) } } diff --git a/packages/snjs/lib/Application/Application.ts b/packages/snjs/lib/Application/Application.ts index 0ac889ec8c9..466d42e0456 100644 --- a/packages/snjs/lib/Application/Application.ts +++ b/packages/snjs/lib/Application/Application.ts @@ -116,7 +116,7 @@ import { LoggerInterface, canBlockDeinit, } from '@standardnotes/utils' -import { UuidString, ApplicationEventPayload } from '../Types' +import { UuidString } from '../Types' import { applicationEventForSyncEvent } from '@Lib/Application/Event' import { BackupServiceInterface, FilesClientInterface } from '@standardnotes/files' import { ComputePrivateUsername } from '@standardnotes/encryption' @@ -273,12 +273,12 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli }), ) - const syncEventCallback = async (eventName: SyncEvent) => { + const syncEventCallback = async (eventName: SyncEvent, data?: unknown) => { const appEvent = applicationEventForSyncEvent(eventName) if (appEvent) { await encryptionService.onSyncEvent(eventName) - await this.notifyEvent(appEvent) + await this.notifyEvent(appEvent, data) if (appEvent === ApplicationEvent.CompletedFullSync) { if (!this.handledFullSyncStage) { @@ -529,7 +529,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli return this.addEventObserver(filteredCallback, event) } - private async notifyEvent(event: ApplicationEvent, data?: ApplicationEventPayload) { + private async notifyEvent(event: ApplicationEvent, data?: unknown) { if (event === ApplicationEvent.Started) { this.onStart() } else if (event === ApplicationEvent.Launched) { diff --git a/packages/snjs/lib/Application/Dependencies/DependencyEvents.ts b/packages/snjs/lib/Application/Dependencies/DependencyEvents.ts index 324695984e8..bc0516839fc 100644 --- a/packages/snjs/lib/Application/Dependencies/DependencyEvents.ts +++ b/packages/snjs/lib/Application/Dependencies/DependencyEvents.ts @@ -45,7 +45,7 @@ export function RegisterApplicationServicesEvents(container: Dependencies, event events.addEventHandler(container.get(TYPES.VaultInviteService), ApplicationEvent.Launched) events.addEventHandler(container.get(TYPES.VaultInviteService), SyncEvent.ReceivedSharedVaultInvites) events.addEventHandler(container.get(TYPES.VaultInviteService), WebSocketsServiceEvent.UserInvitedToSharedVault) - events.addEventHandler(container.get(TYPES.SyncBackoffService), ApplicationEvent.CompletedIncrementalSync) + events.addEventHandler(container.get(TYPES.SyncBackoffService), SyncEvent.PaginatedSyncRequestCompleted) if (container.get(TYPES.FilesBackupService)) { events.addEventHandler(container.get(TYPES.FilesBackupService), ApplicationEvent.ApplicationStageChanged) diff --git a/packages/snjs/lib/Services/Sync/SyncService.ts b/packages/snjs/lib/Services/Sync/SyncService.ts index adfdf6e9432..a83f134c00f 100644 --- a/packages/snjs/lib/Services/Sync/SyncService.ts +++ b/packages/snjs/lib/Services/Sync/SyncService.ts @@ -1047,7 +1047,6 @@ export class SyncService } if (response.status === PAYLOAD_TOO_LARGE) { - void this.notifyEvent(SyncEvent.PayloadTooLarge) this.opStatus?.setIsTooLarge() } @@ -1070,6 +1069,10 @@ export class SyncService uuidsToBackOff.push(uuidOrError.getValue()) } + void this.notifyEvent(SyncEvent.PayloadTooLarge, { + uuids: uuidsToBackOff.map((uuid) => uuid.value), + }) + this.syncBackoffService.backoffItems(uuidsToBackOff) } diff --git a/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx b/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx index 27f18642d54..be7037af389 100644 --- a/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx +++ b/packages/web/src/javascripts/Components/ApplicationView/ApplicationView.tsx @@ -117,7 +117,7 @@ const ApplicationView: FunctionComponent = ({ application, mainApplicatio onAppLaunch() } - const removeAppObserver = application.addEventObserver(async (eventName) => { + const removeAppObserver = application.addEventObserver(async (eventName, data) => { switch (eventName) { case ApplicationEvent.Started: onAppStart() @@ -153,12 +153,19 @@ const ApplicationView: FunctionComponent = ({ application, mainApplicatio message: 'Too many requests. Please try again later.', }) break - case ApplicationEvent.SyncPayloadTooLarge: + case ApplicationEvent.SyncPayloadTooLarge: { + if ('uuids' in (data as Record) === false) { + return + } + const notes = application.items.findItems((data as Record).uuids as string[]) + const noteTitles = notes.map((note) => `"${note.title}"`).join(', ') + addToast({ type: ToastType.Error, - message: 'Unable to sync. The payload of the request is too large.', + message: `Unable to sync. The payload of the request is too large for the following notes: ${noteTitles}`, }) break + } } })