Fix Mux Pair
This commit is contained in:
@@ -47,6 +47,11 @@ export async function startBareUserSessionStack(ctx) {
|
||||
})
|
||||
}
|
||||
|
||||
/** Peers may have connected during guest boot; pair chat on those muxes now. */
|
||||
if (disk && typeof disk.pairBareOsChatExistingPeers === 'function') {
|
||||
disk.pairBareOsChatExistingPeers()
|
||||
}
|
||||
|
||||
const order = ['bare-os-www', 'bare-holesail', 'bare-os-chat']
|
||||
for (const name of order) {
|
||||
if (!findBareServiceDefinition(name)) continue
|
||||
|
||||
@@ -595,4 +595,22 @@ export class SwarmDisk {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* When `bareOsChatService` is created after peers already exist (e.g. identity unlock
|
||||
* after guest-phase swarm), pair `bare-os-chat-v1` on their existing Protomux instances.
|
||||
*/
|
||||
pairBareOsChatExistingPeers() {
|
||||
if (!bareOsChatMuxEnabled(globalThis.process?.env)) return
|
||||
const svc = this.bareOsChatService
|
||||
if (!svc || typeof svc.pairOnMux !== 'function') return
|
||||
for (const peer of this.peers) {
|
||||
if (peer.chatChan) continue
|
||||
try {
|
||||
svc.pairOnMux(this, peer.mux, peer.socket, peer)
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,3 +116,74 @@ test('TCP + Protomux — chat event roundtrips Alice → Bob', async (t) => {
|
||||
srvSock.destroy()
|
||||
cliSock.destroy()
|
||||
})
|
||||
|
||||
test('pairBareOsChatExistingPeers wires chat after peers already on disk', async (t) => {
|
||||
process.env.BARE_OS_PROTOMUX_CHAT_CHANNEL = '1'
|
||||
|
||||
const kpAlice = crypto.keyPair()
|
||||
const kpBob = crypto.keyPair()
|
||||
|
||||
const { srvSock, cliSock } = await tcpDuplexPair()
|
||||
|
||||
wireNoiseLikeKeys(cliSock, kpAlice, kpBob)
|
||||
wireNoiseLikeKeys(srvSock, kpBob, kpAlice)
|
||||
|
||||
const diskAlice = new SwarmDisk()
|
||||
diskAlice.localNoiseWirePk = b4a.from(kpAlice.publicKey)
|
||||
|
||||
const diskBob = new SwarmDisk()
|
||||
|
||||
diskAlice.bareOsChatService = createBareOsChatService({
|
||||
env: /** @type {Record<string, string>} */ ({ USER: 'aliceuser' })
|
||||
})
|
||||
diskBob.bareOsChatService = createBareOsChatService({
|
||||
env: /** @type {Record<string, string>} */ ({ USER: 'bobuser' })
|
||||
})
|
||||
|
||||
const muxAlice = new Protomux(cliSock)
|
||||
const muxBob = new Protomux(srvSock)
|
||||
|
||||
const peerAliceToBob = {
|
||||
chan: /** @type {unknown} */ (null),
|
||||
mux: muxAlice,
|
||||
socket: cliSock,
|
||||
id: null,
|
||||
chatChan: null
|
||||
}
|
||||
|
||||
const peerBobFromAlice = {
|
||||
chan: /** @type {unknown} */ (null),
|
||||
mux: muxBob,
|
||||
socket: srvSock,
|
||||
id: null,
|
||||
chatChan: null
|
||||
}
|
||||
|
||||
diskAlice.peers.add(peerAliceToBob)
|
||||
diskBob.peers.add(peerBobFromAlice)
|
||||
|
||||
diskAlice.pairBareOsChatExistingPeers()
|
||||
diskBob.pairBareOsChatExistingPeers()
|
||||
|
||||
await new Promise((r) => setImmediate(r))
|
||||
await new Promise((r) => setImmediate(r))
|
||||
|
||||
/** @type {unknown[]} */
|
||||
const bobRx = []
|
||||
diskBob.bareOsChatService.subscribe((ev) => bobRx.push(ev))
|
||||
|
||||
diskAlice.bareOsChatService.broadcastLocal(diskAlice, 'hello-after-late-pair', {
|
||||
displayName: 'aliceuser'
|
||||
})
|
||||
|
||||
await new Promise((r) => setImmediate(r))
|
||||
await new Promise((r) => setImmediate(r))
|
||||
|
||||
t.ok(bobRx.length >= 1, 'Bob received remote event')
|
||||
const last = /** @type {{ body?: string, local?: boolean }} */ (bobRx[bobRx.length - 1])
|
||||
t.is(last.body, 'hello-after-late-pair')
|
||||
t.absent(last.local)
|
||||
|
||||
srvSock.destroy()
|
||||
cliSock.destroy()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user