Skip to content

Commit

Permalink
fix: sync restart on errors (#1767)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheSlimvReal authored Mar 15, 2023
1 parent 9ee705e commit ffcdf1c
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe("SyncedSessionService", () => {
>;
let dbUser: AuthUser;
let syncSpy: jasmine.Spy<() => Promise<void>>;
let liveSyncSpy: jasmine.Spy<() => void>;
let liveSyncSpy: jasmine.Spy<() => any>;
let mockAuthService: jasmine.SpyObj<AuthService>;
let mockLocation: jasmine.SpyObj<Location>;

Expand Down Expand Up @@ -267,6 +267,56 @@ describe("SyncedSessionService", () => {
expect(sessionService.checkPassword("TestUser", "wrongPW")).toBeFalse();
});

it("should restart the sync if it is canceled at one point", fakeAsync(() => {
let errorCallback, completeCallback, pauseCallback;
const syncHandle = {
on: (action, callback) => {
if (action === "error") {
errorCallback = callback;
}
if (action === "complete") {
completeCallback = callback;
}
if (action === "paused") {
pauseCallback = callback;
}
return syncHandle;
},
cancel: () => undefined,
};
syncSpy = jasmine.createSpy().and.returnValue(syncHandle);
liveSyncSpy.and.callThrough();
spyOn(localSession, "getDatabase").and.returnValue({
getPouchDB: () => ({ sync: syncSpy }),
} as any);

passRemoteLogin();
sessionService.login(TEST_USER, TEST_PASSWORD);
flush();

// error -> sync should restart
syncSpy.calls.reset();
errorCallback();
expect(syncSpy).toHaveBeenCalled();

// complete -> sync should restart
syncSpy.calls.reset();
completeCallback();
expect(syncSpy).toHaveBeenCalled();

// pause -> no restart required
syncSpy.calls.reset();
pauseCallback();
expect(syncSpy).not.toHaveBeenCalled();

// logout + complete -> no restart
syncSpy.calls.reset();
sessionService.logout();
tick();
completeCallback();
expect(syncSpy).not.toHaveBeenCalled();
}));

testSessionServiceImplementation(() => Promise.resolve(sessionService));

function passRemoteLogin(response: AuthUser = { name: "", roles: [] }) {
Expand Down
23 changes: 14 additions & 9 deletions src/app/core/session/session-service/synced-session.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,15 +226,20 @@ export class SyncedSessionService extends SessionService {
// replication was resumed: either because new things to sync or because connection is available again. info contains the direction
this.syncState.next(SyncState.STARTED);
})
.on("error", (err) => {
// totally unhandled error (shouldn't happen)
this.loggingService.error("sync failed" + err);
.on("error", this.handleStoppedSync("error"))
.on("complete", this.handleStoppedSync("complete"));
}

private handleStoppedSync(reason: string) {
return (info) => {
if (this.isLoggedIn()) {
this.syncState.next(SyncState.FAILED);
})
.on("complete", (info) => {
// replication was canceled!
this._liveSyncHandle = null;
});
this.loggingService.warn(
`Live sync stopped "${reason}": ${JSON.stringify(info)}`
);
this.liveSync();
}
};
}

/**
Expand Down Expand Up @@ -283,9 +288,9 @@ export class SyncedSessionService extends SessionService {
*/
public async logout() {
this.cancelLoginOfflineRetry();
this.cancelLiveSync();
this.localSession.logout();
await this.remoteSession.logout();
this.cancelLiveSync();
this.location.reload();
this.loginState.next(LoginState.LOGGED_OUT);
}
Expand Down

0 comments on commit ffcdf1c

Please sign in to comment.