Skip to content

Commit 81bf517

Browse files
authored
feat: add API to change sync auto-stop timeout (#747)
`project.$sync.setAutostopDataSyncTimeout(1234)` sets the auto-stop timeout to 1234 milliseconds without changing the enabled state of sync. Closes [#746]. [#746]: #746
1 parent 3537d5b commit 81bf517

File tree

2 files changed

+125
-8
lines changed

2 files changed

+125
-8
lines changed

src/sync/sync-api.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,13 @@ export class SyncApi extends TypedEmitter {
244244
* happens after this duration in milliseconds, sync will be automatically
245245
* stopped as if {@link stop} was called.
246246
*/
247-
start({ autostopDataSyncAfter = null } = {}) {
248-
assertAutostopDataSyncAfterIsValid(autostopDataSyncAfter)
247+
start({ autostopDataSyncAfter } = {}) {
249248
this.#wantsToSyncData = true
250-
this.#autostopDataSyncAfter = autostopDataSyncAfter
251-
// Ensure the timeout is started anew.
252-
this.#clearAutostopDataSyncTimeoutIfExists()
253-
this.#updateState()
249+
if (autostopDataSyncAfter === undefined) {
250+
this.#updateState()
251+
} else {
252+
this.setAutostopDataSyncTimeout(autostopDataSyncAfter)
253+
}
254254
}
255255

256256
/**
@@ -279,6 +279,17 @@ export class SyncApi extends TypedEmitter {
279279
this.#updateState()
280280
}
281281

282+
/**
283+
* @param {null | number} autostopDataSyncAfter
284+
* @returns {void}
285+
*/
286+
setAutostopDataSyncTimeout(autostopDataSyncAfter) {
287+
assertAutostopDataSyncAfterIsValid(autostopDataSyncAfter)
288+
this.#clearAutostopDataSyncTimeoutIfExists()
289+
this.#autostopDataSyncAfter = autostopDataSyncAfter
290+
this.#updateState()
291+
}
292+
282293
/**
283294
* @param {SyncType} type
284295
* @returns {Promise<void>}

test-e2e/sync.js

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ test('auto-stop', async (t) => {
257257
)
258258
const [invitorProject, inviteeProject] = projects
259259

260-
const generatedObservations = generate('observation', { count: 2 })
260+
const generatedObservations = generate('observation', { count: 3 })
261261

262262
invitorProject.$sync.start({ autostopDataSyncAfter: 10_000 })
263263
inviteeProject.$sync.start({ autostopDataSyncAfter: 10_000 })
@@ -302,7 +302,7 @@ test('auto-stop', async (t) => {
302302
"invitee hasn't auto-stopped yet because the timer has been restarted"
303303
)
304304

305-
const invitorProjectOnSyncDisabled = pEvent(
305+
let invitorProjectOnSyncDisabled = pEvent(
306306
invitorProject.$sync,
307307
'sync-state',
308308
({ data: { isSyncEnabled } }) => !isSyncEnabled
@@ -327,6 +327,109 @@ test('auto-stop', async (t) => {
327327
!inviteeProject.$sync.getState().data.isSyncEnabled,
328328
'invitee has auto-stopped'
329329
)
330+
331+
invitorProject.$sync.setAutostopDataSyncTimeout(20_000)
332+
assert(
333+
!invitorProject.$sync.getState().data.isSyncEnabled,
334+
'invitor is still stopped'
335+
)
336+
337+
invitorProject.$sync.start()
338+
339+
const observation3 = await invitorProject.observation.create(
340+
valueOf(generatedObservations[2])
341+
)
342+
await waitForSync(projects, 'full')
343+
assert(
344+
await inviteeProject.observation.getByDocId(observation3.docId),
345+
'invitee receives doc'
346+
)
347+
348+
await clock.tickAsync(19_000)
349+
350+
assert(
351+
invitorProject.$sync.getState().data.isSyncEnabled,
352+
"invitor hasn't auto-stopped"
353+
)
354+
355+
invitorProjectOnSyncDisabled = pEvent(
356+
invitorProject.$sync,
357+
'sync-state',
358+
({ data: { isSyncEnabled } }) => !isSyncEnabled
359+
)
360+
361+
clock.tick(2_000)
362+
363+
await invitorProjectOnSyncDisabled
364+
assert(
365+
!invitorProject.$sync.getState().data.isSyncEnabled,
366+
'invitor has auto-stopped'
367+
)
368+
369+
invitorProject.$sync.start({ autostopDataSyncAfter: 999_999 })
370+
invitorProject.$sync.setAutostopDataSyncTimeout(20_000)
371+
372+
assert(
373+
invitorProject.$sync.getState().data.isSyncEnabled,
374+
'invitor has not yet auto-stopped'
375+
)
376+
377+
invitorProjectOnSyncDisabled = pEvent(
378+
invitorProject.$sync,
379+
'sync-state',
380+
({ data: { isSyncEnabled } }) => !isSyncEnabled
381+
)
382+
clock.tick(21_000)
383+
await invitorProjectOnSyncDisabled
384+
385+
assert(
386+
!invitorProject.$sync.getState().data.isSyncEnabled,
387+
'invitor has auto-stopped'
388+
)
389+
})
390+
391+
test('disabling auto-stop timeout', async (t) => {
392+
const clock = FakeTimers.install({ shouldAdvanceTime: true })
393+
t.after(() => clock.uninstall())
394+
395+
const managers = await createManagers(2, t)
396+
const [invitor, ...invitees] = managers
397+
398+
const disconnect = connectPeers(managers, { discovery: false })
399+
t.after(disconnect)
400+
401+
const projectId = await invitor.createProject({ name: 'mapeo' })
402+
await invite({ invitor, invitees, projectId })
403+
404+
const projects = await Promise.all(
405+
managers.map((m) => m.getProject(projectId))
406+
)
407+
const [invitorProject, inviteeProject] = projects
408+
409+
invitorProject.$sync.start({ autostopDataSyncAfter: 10_000 })
410+
invitorProject.$sync.setAutostopDataSyncTimeout(null)
411+
412+
inviteeProject.$sync.start()
413+
414+
assert(
415+
invitorProject.$sync.getState().data.isSyncEnabled,
416+
"invitor hasn't auto-stopped yet"
417+
)
418+
419+
const observation1 = await invitorProject.observation.create(
420+
valueOf(generate('observation')[0])
421+
)
422+
await waitForSync(projects, 'full')
423+
assert(
424+
await inviteeProject.observation.getByDocId(observation1.docId),
425+
'invitee receives doc'
426+
)
427+
428+
await clock.tickAsync(999_999_999)
429+
assert(
430+
invitorProject.$sync.getState().data.isSyncEnabled,
431+
"invitor still hasn't auto-stopped"
432+
)
330433
})
331434

332435
test('validates auto-stop timeouts', async (t) => {
@@ -339,6 +442,9 @@ test('validates auto-stop timeouts', async (t) => {
339442
assert.throws(() => {
340443
project.$sync.start({ autostopDataSyncAfter })
341444
})
445+
assert.throws(() => {
446+
project.$sync.setAutostopDataSyncTimeout(autostopDataSyncAfter)
447+
})
342448
}
343449

344450
assert(!project.$sync.getState().data.isSyncEnabled, 'sync is not enabled')

0 commit comments

Comments
 (0)