Fix reset flow

This commit is contained in:
Andras Schmelczer 2025-03-22 17:21:59 +00:00
parent bd44fe9c74
commit 8cfbaa1bda
No known key found for this signature in database
GPG key ID: FC8F2C3D3D1A718C
4 changed files with 28 additions and 3 deletions

View file

@ -39,8 +39,11 @@ export class ConnectionStatus {
return input.url; return input.url;
} }
public reset(): void { public startReset(): void {
this.rejectUntil(new SyncResetError()); this.rejectUntil(new SyncResetError());
}
public finishReset(): void {
[this.until, this.resolveUntil, this.rejectUntil] = createPromise(); [this.until, this.resolveUntil, this.rejectUntil] = createPromise();
} }

View file

@ -162,8 +162,8 @@ export class SyncClient {
} }
public async waitAndStop(): Promise<void> { public async waitAndStop(): Promise<void> {
await this.syncer.waitForSyncQueue();
await this.syncer.applyRemoteChangesLocally(); await this.syncer.applyRemoteChangesLocally();
await this.syncer.waitForSyncQueue();
this.stop(); this.stop();
} }
@ -172,11 +172,12 @@ export class SyncClient {
/// The SyncClient can be used again after calling this method. /// The SyncClient can be used again after calling this method.
public async reset(): Promise<void> { public async reset(): Promise<void> {
this.stop(); this.stop();
this.connectionStatus.reset(); this.connectionStatus.startReset();
await this.syncer.reset(); await this.syncer.reset();
this.history.reset(); this.history.reset();
this.database.reset(); this.database.reset();
this._logger.reset(); this._logger.reset();
this.connectionStatus.finishReset();
void this.start(); void this.start();
} }

View file

@ -11,6 +11,7 @@ import type { FileOperations } from "../file-operations/file-operations";
import { findMatchingFile } from "../utils/find-matching-file"; import { findMatchingFile } from "../utils/find-matching-file";
import { UnrestrictedSyncer } from "./unrestricted-syncer"; import { UnrestrictedSyncer } from "./unrestricted-syncer";
import { createPromise } from "../utils/create-promise"; import { createPromise } from "../utils/create-promise";
import { SyncResetError } from "../services/sync-reset-error";
export class Syncer { export class Syncer {
private readonly remainingOperationsListeners: (( private readonly remainingOperationsListeners: ((
@ -203,6 +204,12 @@ export class Syncer {
await this.runningScheduleSyncForOfflineChanges; await this.runningScheduleSyncForOfflineChanges;
this.logger.info(`All local changes have been applied remotely`); this.logger.info(`All local changes have been applied remotely`);
} catch (e) { } catch (e) {
if (e instanceof SyncResetError) {
this.logger.info(
"Failed to apply local changes remotely due to a reset"
);
return;
}
this.logger.error( this.logger.error(
`Not all local changes have been applied remotely: ${e}` `Not all local changes have been applied remotely: ${e}`
); );
@ -226,6 +233,12 @@ export class Syncer {
await this.runningApplyRemoteChangesLocally; await this.runningApplyRemoteChangesLocally;
this.logger.info("All remote changes have been applied locally"); this.logger.info("All remote changes have been applied locally");
} catch (e) { } catch (e) {
if (e instanceof SyncResetError) {
this.logger.info(
"Failed to apply remote changes locally due to a reset"
);
return;
}
this.logger.error(`Failed to apply remote changes locally: ${e}`); this.logger.error(`Failed to apply remote changes locally: ${e}`);
throw e; throw e;
} finally { } finally {

View file

@ -16,6 +16,7 @@ import type { FileOperations } from "../file-operations/file-operations";
import { DocumentLocks } from "../file-operations/document-locks"; import { DocumentLocks } from "../file-operations/document-locks";
import { createPromise } from "../utils/create-promise"; import { createPromise } from "../utils/create-promise";
import { FileNotFoundError } from "../file-operations/file-not-found-error"; import { FileNotFoundError } from "../file-operations/file-not-found-error";
import { SyncResetError } from "../services/sync-reset-error";
export class UnrestrictedSyncer { export class UnrestrictedSyncer {
private readonly locks: DocumentLocks; private readonly locks: DocumentLocks;
@ -402,6 +403,13 @@ export class UnrestrictedSyncer {
this.logger.info( this.logger.info(
`Skip ${syncSource.toLocaleLowerCase()} file because it no longer exists when trying to ${syncType.toLocaleLowerCase()} it` `Skip ${syncSource.toLocaleLowerCase()} file because it no longer exists when trying to ${syncType.toLocaleLowerCase()} it`
); );
return;
}
if (e instanceof SyncResetError) {
this.logger.info(
`Interrupting sync operation because of a reset`
);
return;
} else { } else {
this.history.addHistoryEntry({ this.history.addHistoryEntry({
status: SyncStatus.ERROR, status: SyncStatus.ERROR,