Skip to content

Commit

Permalink
fix: remove replication error when core is closed
Browse files Browse the repository at this point in the history
If a core is closed, we can't replicate it.

This can happen if you leave a project while offline, then reconnect. I
added a test for this case and fixed the issue. (The fix is just one
line, but it took a whole day to figure that out.)

Fixes [#584].

[#584]: #584
  • Loading branch information
EvanHahn committed May 7, 2024
1 parent 7f8fcdd commit f1958d3
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/sync/peer-sync-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ export class PeerSyncController {
* @param {import('hypercore')<'binary', any>} core
*/
#replicateCore(core) {
if (core.closed) return

Check failure on line 232 in src/sync/peer-sync-controller.js

View workflow job for this annotation

GitHub Actions / build (macos-latest, 18.x)

Property 'closed' does not exist on type 'Hypercore<"binary", any>'. Did you mean 'close'?

Check failure on line 232 in src/sync/peer-sync-controller.js

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 18.x)

Property 'closed' does not exist on type 'Hypercore<"binary", any>'. Did you mean 'close'?

Check failure on line 232 in src/sync/peer-sync-controller.js

View workflow job for this annotation

GitHub Actions / build (windows-latest, 18.x)

Property 'closed' does not exist on type 'Hypercore<"binary", any>'. Did you mean 'close'?
if (this.#replicatingCores.has(core)) return
this.#log('replicating core %k', core.key)
core.replicate(this.#protomux)
Expand Down
44 changes: 44 additions & 0 deletions test-e2e/project-leave.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,4 +284,48 @@ test('Data access after leaving project', async (t) => {
await disconnectPeers(managers)
})

test('leaving a project while disconnected', async (t) => {
const managers = await createManagers(2, t)

let disconnectPeers = connectPeers(managers)
t.teardown(() => disconnectPeers())

await waitForPeers(managers)

const [creator, member] = managers
const projectId = await creator.createProject({ name: 'mapeo' })

await invite({
invitor: creator,
invitees: [member],
projectId,
roleId: MEMBER_ROLE_ID,
})

const projects = await Promise.all(
managers.map((m) => m.getProject(projectId))
)
const [creatorProject] = projects

await disconnectPeers()

await member.leaveProject(projectId)

t.ok(
await creatorProject.$member.getById(member.deviceId),
'creator still thinks member is part of project'
)

disconnectPeers = connectPeers(managers)
await waitForPeers(managers)

await waitForSync(projects, 'initial')

t.is(
(await creatorProject.$member.getById(member.deviceId)).role.roleId,
LEFT_ROLE_ID,
'creator no longer thinks member is part of project'
)
})

// TODO: Add test for leaving and rejoining a project

0 comments on commit f1958d3

Please sign in to comment.