replace isSyncing and emit with an Observable SyncStatus

This commit is contained in:
Bruno Windels 2020-04-19 19:52:26 +02:00
parent 80f7caadbe
commit 72b0eefccb
3 changed files with 41 additions and 32 deletions

View file

@ -41,11 +41,12 @@ rooms should report how many messages they have queued up, and each time they se
- add waitFor (won't this leak if the promise never resolves?) - add waitFor (won't this leak if the promise never resolves?)
- decide whether we want to inherit (no?) - decide whether we want to inherit (no?)
- DONE: cleanup Reconnector with recent changes, move generic code, make imports work - DONE: cleanup Reconnector with recent changes, move generic code, make imports work
- add SyncStatus as ObservableValue of enum in Sync - DONE: add SyncStatus as ObservableValue of enum in Sync
- show load progress in LoginView/SessionPickView and do away with loading screen - cleanup SessionContainer
- change main.js to pass in a creation function of a SessionContainer instead of everything it is replacing - change main.js to pass in a creation function of a SessionContainer instead of everything it is replacing
- show load progress in LoginView/SessionPickView and do away with loading screen
- adjust BrawlViewModel, SessionPickViewModel and LoginViewModel to use a SessionContainer - adjust BrawlViewModel, SessionPickViewModel and LoginViewModel to use a SessionContainer
- rename SessionsStore to SessionInfoStorage - DONE: rename SessionsStore to SessionInfoStorage
- make sure we've renamed all \*State enums and fields to \*Status - make sure we've renamed all \*State enums and fields to \*Status
- add pendingMessageCount prop to SendQueue and Room, aggregate this in Session - add pendingMessageCount prop to SendQueue and Room, aggregate this in Session
- add completedFirstSync to Sync, so we can check if the catchup or initial sync is still in progress - add completedFirstSync to Sync, so we can check if the catchup or initial sync is still in progress

View file

@ -6,8 +6,7 @@ export const LoadStatus = createEnum(
"LoginFailed", "LoginFailed",
"Loading", "Loading",
"Migrating", //not used atm, but would fit here "Migrating", //not used atm, but would fit here
"InitialSync", "FirstSync",
"CatchupSync",
"Error", "Error",
"Ready", "Ready",
); );
@ -127,7 +126,6 @@ export class SessionContainer {
if (!needsInitialSync) { if (!needsInitialSync) {
this._status.set(LoadStatus.CatchupSync); this._status.set(LoadStatus.CatchupSync);
} else { } else {
this._status.set(LoadStatus.InitialSync);
} }
this._sync = new Sync({hsApi, storage, session: this._session}); this._sync = new Sync({hsApi, storage, session: this._session});
@ -148,7 +146,8 @@ export class SessionContainer {
async _waitForFirstSync() { async _waitForFirstSync() {
try { try {
await this._sync.start(); this._sync.start();
this._status.set(LoadStatus.FirstSync);
} catch (err) { } catch (err) {
// swallow ConnectionError here and continue, // swallow ConnectionError here and continue,
// as the reconnector above will call // as the reconnector above will call

View file

@ -1,9 +1,17 @@
import {AbortError} from "./error.js"; import {AbortError} from "./error.js";
import EventEmitter from "../EventEmitter.js"; import ObservableValue from "../observable/ObservableValue.js";
import {createEnum} from "../utils/enum.js";
const INCREMENTAL_TIMEOUT = 30000; const INCREMENTAL_TIMEOUT = 30000;
const SYNC_EVENT_LIMIT = 10; const SYNC_EVENT_LIMIT = 10;
export const SyncStatus = createEnum(
"InitialSync",
"CatchupSync",
"Syncing",
"Stopped"
);
function parseRooms(roomsSection, roomCallback) { function parseRooms(roomsSection, roomCallback) {
if (roomsSection) { if (roomsSection) {
const allMemberships = ["join", "invite", "leave"]; const allMemberships = ["join", "invite", "leave"];
@ -19,53 +27,54 @@ function parseRooms(roomsSection, roomCallback) {
return []; return [];
} }
export default class Sync extends EventEmitter { export default class Sync {
constructor({hsApi, session, storage}) { constructor({hsApi, session, storage}) {
super();
this._hsApi = hsApi; this._hsApi = hsApi;
this._session = session; this._session = session;
this._storage = storage; this._storage = storage;
this._isSyncing = false;
this._currentRequest = null; this._currentRequest = null;
this._status = new ObservableValue(SyncStatus.Stopped);
this._error = null;
} }
get isSyncing() { get status() {
return this._isSyncing; return this._status;
} }
// this should not throw? /** the error that made the sync stop */
// returns when initial sync is done get error() {
async start() { return this._error;
if (this._isSyncing) { }
start() {
// not already syncing?
if (this._status.get() !== SyncStatus.Stopped) {
return; return;
} }
this._isSyncing = true;
this.emit("status", "started");
let syncToken = this._session.syncToken; let syncToken = this._session.syncToken;
// do initial sync if needed if (syncToken) {
if (!syncToken) { this._status.set(SyncStatus.CatchupSync);
// need to create limit filter here } else {
syncToken = await this._syncRequest(); this._status.set(SyncStatus.InitialSync);
} }
this._syncLoop(syncToken); this._syncLoop(syncToken);
} }
async _syncLoop(syncToken) { async _syncLoop(syncToken) {
// if syncToken is falsy, it will first do an initial sync ... // if syncToken is falsy, it will first do an initial sync ...
while(this._isSyncing) { while(this._status.get() !== SyncStatus.Stopped) {
try { try {
console.log(`starting sync request with since ${syncToken} ...`); console.log(`starting sync request with since ${syncToken} ...`);
syncToken = await this._syncRequest(syncToken, INCREMENTAL_TIMEOUT); const timeout = syncToken ? INCREMENTAL_TIMEOUT : undefined;
syncToken = await this._syncRequest(syncToken, timeout);
this._status.set(SyncStatus.Syncing);
} catch (err) { } catch (err) {
this._isSyncing = false;
if (!(err instanceof AbortError)) { if (!(err instanceof AbortError)) {
console.error("stopping sync because of error"); this._error = err;
console.error(err); this._status.set(SyncStatus.Stopped);
this.emit("status", "error", err);
} }
} }
} }
this.emit("status", "stopped");
} }
async _syncRequest(syncToken, timeout) { async _syncRequest(syncToken, timeout) {
@ -128,10 +137,10 @@ export default class Sync extends EventEmitter {
} }
stop() { stop() {
if (!this._isSyncing) { if (this._status.get() === SyncStatus.Stopped) {
return; return;
} }
this._isSyncing = false; this._status.set(SyncStatus.Stopped);
if (this._currentRequest) { if (this._currentRequest) {
this._currentRequest.abort(); this._currentRequest.abort();
this._currentRequest = null; this._currentRequest = null;