Files
standardnotes-app-web/packages/snjs/lib/Services/Sync/SyncOpStatus.ts
2022-07-06 14:04:30 +02:00

126 lines
3.0 KiB
TypeScript

import { SyncEvent, SyncEventReceiver } from '@standardnotes/services'
const HEALTHY_SYNC_DURATION_THRESHOLD_S = 5
const TIMING_MONITOR_POLL_FREQUENCY_MS = 500
export class SyncOpStatus {
error?: any
private interval: any
private receiver: SyncEventReceiver
private completedUpload = 0
private totalUpload = 0
private downloaded = 0
private databaseLoadCurrent = 0
private databaseLoadTotal = 0
private databaseLoadDone = false
private syncing = false
private syncStart!: Date
private timingMonitor?: any
constructor(interval: any, receiver: SyncEventReceiver) {
this.interval = interval
this.receiver = receiver
}
public deinit() {
this.stopTimingMonitor()
}
public setUploadStatus(completed: number, total: number) {
this.completedUpload = completed
this.totalUpload = total
this.receiver(SyncEvent.StatusChanged)
}
public setDownloadStatus(downloaded: number) {
this.downloaded += downloaded
this.receiver(SyncEvent.StatusChanged)
}
public setDatabaseLoadStatus(current: number, total: number, done: boolean) {
this.databaseLoadCurrent = current
this.databaseLoadTotal = total
this.databaseLoadDone = done
if (done) {
this.receiver(SyncEvent.LocalDataLoaded)
} else {
this.receiver(SyncEvent.LocalDataIncrementalLoad)
}
}
public getStats() {
return {
uploadCompletionCount: this.completedUpload,
uploadTotalCount: this.totalUpload,
downloadCount: this.downloaded,
localDataDone: this.databaseLoadDone,
localDataCurrent: this.databaseLoadCurrent,
localDataTotal: this.databaseLoadTotal,
}
}
public setDidBegin() {
this.syncing = true
this.syncStart = new Date()
}
public setDidEnd() {
this.syncing = false
}
get syncInProgress() {
return this.syncing === true
}
get secondsSinceSyncStart() {
return (new Date().getTime() - this.syncStart.getTime()) / 1000
}
/**
* Notifies receiver if current sync request is taking too long to complete.
*/
startTimingMonitor(): void {
if (this.timingMonitor) {
this.stopTimingMonitor()
}
this.timingMonitor = this.interval(() => {
if (this.secondsSinceSyncStart > HEALTHY_SYNC_DURATION_THRESHOLD_S) {
this.receiver(SyncEvent.SyncTakingTooLong)
this.stopTimingMonitor()
}
}, TIMING_MONITOR_POLL_FREQUENCY_MS)
}
stopTimingMonitor(): void {
if (Object.prototype.hasOwnProperty.call(this.interval, 'cancel')) {
this.interval.cancel(this.timingMonitor)
} else {
clearInterval(this.timingMonitor)
}
this.timingMonitor = null
}
hasError(): boolean {
return !!this.error
}
setError(error: any): void {
this.error = error
}
clearError() {
this.error = null
}
reset() {
this.downloaded = 0
this.completedUpload = 0
this.totalUpload = 0
this.syncing = false
this.error = null
this.stopTimingMonitor()
this.receiver(SyncEvent.StatusChanged)
}
}