Skip to content

Commit

Permalink
chore: rely on websockets for autosync if a websocket connection is o…
Browse files Browse the repository at this point in the history
…pen (#2672)
  • Loading branch information
karolsojko authored Dec 4, 2023
1 parent 910f4a6 commit 258422c
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 58 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions packages/services/src/Domain/Api/WebSocketsServiceEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export enum WebSocketsServiceEvent {
NotificationAddedForUser = 'NotificationAddedForUser',
MessageSentToUser = 'MessageSentToUser',
UserInvitedToSharedVault = 'UserInvitedToSharedVault',
ItemsChangedOnServer = 'ItemsChangedOnServer',
}
7 changes: 7 additions & 0 deletions packages/services/src/Domain/Api/WebsocketsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,20 @@ export class WebSocketsService extends AbstractService<WebSocketsServiceEvent, D
}
}

isWebSocketConnectionOpen(): boolean {
return this.webSocket?.readyState === WebSocket.OPEN
}

public closeWebSocketConnection(): void {
this.webSocket?.close()
}

private onWebSocketMessage(messageEvent: MessageEvent) {
const eventData = JSON.parse(messageEvent.data)
switch (eventData.type) {
case 'ITEMS_CHANGED_ON_SERVER':
void this.notifyEvent(WebSocketsServiceEvent.ItemsChangedOnServer, eventData)
break
case 'USER_ROLES_CHANGED':
void this.notifyEvent(WebSocketsServiceEvent.UserRoleMessageReceived, eventData)
break
Expand Down
2 changes: 1 addition & 1 deletion packages/services/src/Domain/Sync/SyncServiceInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface SyncServiceInterface extends AbstractService<SyncEvent> {
isDatabaseLoaded(): boolean
onNewDatabaseCreated(): Promise<void>
loadDatabasePayloads(): Promise<void>

beginAutoSyncTimer(): void
resetSyncState(): void
markAllItemsAsNeedingSyncAndPersist(): Promise<void>
downloadFirstSync(waitTimeOnFailureMs: number, otherSyncOptions?: Partial<SyncOptions>): Promise<void>
Expand Down
17 changes: 1 addition & 16 deletions packages/snjs/lib/Application/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,6 @@ import { TYPES } from './Dependencies/Types'
import { RegisterApplicationServicesEvents } from './Dependencies/DependencyEvents'
import { Result } from '@standardnotes/domain-core'

/** How often to automatically sync, in milliseconds */
const DEFAULT_AUTO_SYNC_INTERVAL = 30_000

type LaunchCallback = {
receiveChallenge: (challenge: Challenge) => void
}
Expand All @@ -165,7 +162,6 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli

private serviceObservers: ObserverRemover[] = []
private managedSubscribers: ObserverRemover[] = []
private autoSyncInterval!: ReturnType<typeof setInterval>

/** True if the result of deviceInterface.openDatabase yields a new database being created */
private createdNewDatabase = false
Expand Down Expand Up @@ -463,7 +459,7 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
throw 'Application has been destroyed.'
}
await this.handleStage(ApplicationStage.LoadedDatabase_12)
this.beginAutoSyncTimer()
this.sync.beginAutoSyncTimer()
await this.sync.sync({
mode: SyncMode.DownloadFirst,
source: SyncSource.External,
Expand Down Expand Up @@ -503,14 +499,6 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
}
}

private beginAutoSyncTimer() {
this.autoSyncInterval = setInterval(() => {
const logger = this.dependencies.get<LoggerInterface>(TYPES.Logger)
logger.info('Syncing from autosync')
void this.sync.sync({ sourceDescription: 'Auto Sync' })
}, DEFAULT_AUTO_SYNC_INTERVAL)
}

private async handleStage(stage: ApplicationStage) {
await this.events.publishSync(
{
Expand Down Expand Up @@ -743,9 +731,6 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
public deinit(mode: DeinitMode, source: DeinitSource): void {
this.dealloced = true

clearInterval(this.autoSyncInterval)
;(this.autoSyncInterval as unknown) = undefined

for (const uninstallObserver of this.serviceObservers) {
uninstallObserver()
}
Expand Down
19 changes: 10 additions & 9 deletions packages/snjs/lib/Application/Dependencies/Dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,15 @@ export class Dependencies {
)
})

this.factory.set(TYPES.WebSocketsService, () => {
return new WebSocketsService(
this.get<DiskStorageService>(TYPES.DiskStorageService),
this.options.webSocketUrl,
this.get<WebSocketApiService>(TYPES.WebSocketApiService),
this.get<InternalEventBus>(TYPES.InternalEventBus),
)
})

this.factory.set(TYPES.SyncService, () => {
return new SyncService(
this.get<ItemManager>(TYPES.ItemManager),
Expand All @@ -1347,6 +1356,7 @@ export class Dependencies {
sleepBetweenBatches: this.options.sleepBetweenBatches,
},
this.get<Logger>(TYPES.Logger),
this.get<WebSocketsService>(TYPES.WebSocketsService),
this.get<InternalEventBus>(TYPES.InternalEventBus),
)
})
Expand Down Expand Up @@ -1390,15 +1400,6 @@ export class Dependencies {
)
})

this.factory.set(TYPES.WebSocketsService, () => {
return new WebSocketsService(
this.get<DiskStorageService>(TYPES.DiskStorageService),
this.options.webSocketUrl,
this.get<WebSocketApiService>(TYPES.WebSocketApiService),
this.get<InternalEventBus>(TYPES.InternalEventBus),
)
})

this.factory.set(TYPES.WebSocketApiService, () => {
return new WebSocketApiService(this.get<WebSocketServer>(TYPES.WebSocketServer))
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export function RegisterApplicationServicesEvents(container: Dependencies, event
events.addEventHandler(container.get(TYPES.SubscriptionManager), ApplicationEvent.UserRolesChanged)
events.addEventHandler(container.get(TYPES.SubscriptionManager), SessionEvent.Restored)
events.addEventHandler(container.get(TYPES.SyncService), IntegrityEvent.IntegrityCheckCompleted)
events.addEventHandler(container.get(TYPES.SyncService), WebSocketsServiceEvent.ItemsChangedOnServer)
events.addEventHandler(container.get(TYPES.UserService), AccountEvent.SignedInOrRegistered)
events.addEventHandler(container.get(TYPES.VaultInviteService), ApplicationEvent.Launched)
events.addEventHandler(container.get(TYPES.VaultInviteService), SyncEvent.ReceivedSharedVaultInvites)
Expand Down
44 changes: 42 additions & 2 deletions packages/snjs/lib/Services/Sync/SyncService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ import {
SyncEventReceivedAsymmetricMessagesData,
SyncOpStatus,
ApplicationSyncOptions,
WebSocketsServiceEvent,
WebSocketsService,
} from '@standardnotes/services'
import { OfflineSyncResponse } from './Offline/Response'
import {
Expand All @@ -98,6 +100,7 @@ import { ContentType } from '@standardnotes/domain-core'

const DEFAULT_MAJOR_CHANGE_THRESHOLD = 15
const INVALID_SESSION_RESPONSE_STATUS = 401
const DEFAULT_AUTO_SYNC_INTERVAL = 30_000

/** Content types appearing first are always mapped first */
const ContentTypeLocalLoadPriorty = [
Expand Down Expand Up @@ -149,6 +152,9 @@ export class SyncService
public lastSyncInvokationPromise?: Promise<unknown>
public currentSyncRequestPromise?: Promise<void>

private autoSyncInterval?: NodeJS.Timer
private wasNotifiedOfItemsChangeOnServer = false

constructor(
private itemManager: ItemManager,
private sessionManager: SessionManager,
Expand All @@ -161,6 +167,7 @@ export class SyncService
private identifier: string,
private readonly options: ApplicationSyncOptions,
private logger: LoggerInterface,
private sockets: WebSocketsService,
protected override internalEventBus: InternalEventBusInterface,
) {
super(internalEventBus)
Expand All @@ -187,6 +194,10 @@ export class SyncService

public override deinit(): void {
this.dealloced = true
if (this.autoSyncInterval) {
clearInterval(this.autoSyncInterval)
}
;(this.autoSyncInterval as unknown) = undefined
;(this.sessionManager as unknown) = undefined
;(this.itemManager as unknown) = undefined
;(this.encryptionService as unknown) = undefined
Expand Down Expand Up @@ -349,6 +360,28 @@ export class SyncService
this.opStatus.setDatabaseLoadStatus(0, 0, true)
}

beginAutoSyncTimer(): void {
this.autoSyncInterval = setInterval(this.autoSync.bind(this), DEFAULT_AUTO_SYNC_INTERVAL)
}

private autoSync(): void {
if (!this.sockets.isWebSocketConnectionOpen()) {
this.logger.debug('WebSocket connection is closed, doing autosync')

void this.sync({ sourceDescription: 'Auto Sync' })

return
}

if (this.wasNotifiedOfItemsChangeOnServer) {
this.logger.debug('Was notified of items changed on server, doing autosync')

this.wasNotifiedOfItemsChangeOnServer = false

void this.sync({ sourceDescription: 'WebSockets Event - Items Changed On Server' })
}
}

private async processPayloadBatch(
batch: FullyFormedPayloadInterface<ItemContent>[],
currentPosition?: number,
Expand Down Expand Up @@ -1400,8 +1433,15 @@ export class SyncService
}

async handleEvent(event: InternalEventInterface): Promise<void> {
if (event.type === IntegrityEvent.IntegrityCheckCompleted) {
await this.handleIntegrityCheckEventResponse(event.payload as IntegrityEventPayload)
switch (event.type) {
case IntegrityEvent.IntegrityCheckCompleted:
await this.handleIntegrityCheckEventResponse(event.payload as IntegrityEventPayload)
break
case WebSocketsServiceEvent.ItemsChangedOnServer:
this.wasNotifiedOfItemsChangeOnServer = true
break
default:
break
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/snjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"@standardnotes/api": "workspace:*",
"@standardnotes/common": "^1.50.0",
"@standardnotes/domain-core": "^1.40.0",
"@standardnotes/domain-events": "^2.122.0",
"@standardnotes/domain-events": "^2.138.1",
"@standardnotes/encryption": "workspace:*",
"@standardnotes/features": "workspace:*",
"@standardnotes/files": "workspace:*",
Expand Down
31 changes: 2 additions & 29 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6610,7 +6610,7 @@ __metadata:
languageName: node
linkType: hard

"@standardnotes/domain-events@npm:2.138.1":
"@standardnotes/domain-events@npm:2.138.1, @standardnotes/domain-events@npm:^2.138.1":
version: 2.138.1
resolution: "@standardnotes/domain-events@npm:2.138.1"
dependencies:
Expand All @@ -6620,16 +6620,6 @@ __metadata:
languageName: node
linkType: hard

"@standardnotes/domain-events@npm:^2.122.0":
version: 2.122.0
resolution: "@standardnotes/domain-events@npm:2.122.0"
dependencies:
"@standardnotes/predicates": 1.6.9
"@standardnotes/security": 1.12.0
checksum: 9dd2f02f1c9c91b3380d0db88dba3e504aaa14b7e58dcb519611dd8b15edb27c111805eb0e34f1612751fb59428296a216e39b5711892f6c8f1fc1f057e61c50
languageName: node
linkType: hard

"@standardnotes/dynamic-theme@npm:^1.2.8":
version: 1.2.8
resolution: "@standardnotes/dynamic-theme@npm:1.2.8"
Expand Down Expand Up @@ -6992,13 +6982,6 @@ __metadata:
languageName: unknown
linkType: soft

"@standardnotes/predicates@npm:1.6.9":
version: 1.6.9
resolution: "@standardnotes/predicates@npm:1.6.9"
checksum: 3b931aaccd763c98d043487e90624507265a350d5656ef55a3355b69fbdae2f718ecd2bde1e402d8fc49355404f91220df99b0a80c081e8da0d515eea1def9e7
languageName: node
linkType: hard

"@standardnotes/predicates@npm:1.8.1":
version: 1.8.1
resolution: "@standardnotes/predicates@npm:1.8.1"
Expand Down Expand Up @@ -7081,16 +7064,6 @@ __metadata:
languageName: node
linkType: hard

"@standardnotes/security@npm:1.12.0":
version: 1.12.0
resolution: "@standardnotes/security@npm:1.12.0"
dependencies:
jsonwebtoken: ^9.0.0
reflect-metadata: ^0.1.13
checksum: 96d42255e79fc2cf4c52f3d370c04ae00296673993e1c0cea2356ca4a6c934d22d6100ba95f9ad602ffb72ee686367ef4a263dc6a6c51795d9b61dc835e635cd
languageName: node
linkType: hard

"@standardnotes/security@npm:1.17.2, @standardnotes/security@npm:^1.17.2":
version: 1.17.2
resolution: "@standardnotes/security@npm:1.17.2"
Expand Down Expand Up @@ -7239,7 +7212,7 @@ __metadata:
"@standardnotes/api": "workspace:*"
"@standardnotes/common": ^1.50.0
"@standardnotes/domain-core": ^1.40.0
"@standardnotes/domain-events": ^2.122.0
"@standardnotes/domain-events": ^2.138.1
"@standardnotes/encryption": "workspace:*"
"@standardnotes/features": "workspace:*"
"@standardnotes/files": "workspace:*"
Expand Down

0 comments on commit 258422c

Please sign in to comment.