fix: prevent rerenders from breaking room connection

This commit is contained in:
Jeremy Kahn 2022-08-16 21:57:39 -05:00
parent 9cc26895de
commit 7cb7e5fdd5
5 changed files with 24 additions and 36 deletions

13
package-lock.json generated
View File

@ -20,6 +20,7 @@
"@types/node": "^18.6.5", "@types/node": "^18.6.5",
"@types/react": "^18.0.17", "@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"fast-memoize": "^2.5.2",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-markdown": "^8.0.3", "react-markdown": "^8.0.3",
@ -10501,6 +10502,11 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
}, },
"node_modules/fast-memoize": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz",
"integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw=="
},
"node_modules/fast-write-atomic": { "node_modules/fast-write-atomic": {
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/fast-write-atomic/-/fast-write-atomic-0.2.1.tgz", "resolved": "https://registry.npmjs.org/fast-write-atomic/-/fast-write-atomic-0.2.1.tgz",
@ -31141,6 +31147,11 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
}, },
"fast-memoize": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz",
"integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw=="
},
"fast-write-atomic": { "fast-write-atomic": {
"version": "0.2.1", "version": "0.2.1",
"resolved": "https://registry.npmjs.org/fast-write-atomic/-/fast-write-atomic-0.2.1.tgz", "resolved": "https://registry.npmjs.org/fast-write-atomic/-/fast-write-atomic-0.2.1.tgz",
@ -39552,7 +39563,7 @@
}, },
"trystero": { "trystero": {
"version": "git+ssh://git@github.com/jeremyckahn/trystero.git#91e9f722302597e232e96932424f3ed47d0d0171", "version": "git+ssh://git@github.com/jeremyckahn/trystero.git#91e9f722302597e232e96932424f3ed47d0d0171",
"from": "trystero@jeremyckahn/trystero#bugfix/fully-qualified-module-resolution", "from": "trystero@github:jeremyckahn/trystero#bugfix/fully-qualified-module-resolution",
"requires": { "requires": {
"firebase": "^9.6.5", "firebase": "^9.6.5",
"ipfs-core": "0.9.0", "ipfs-core": "0.9.0",

View File

@ -16,6 +16,7 @@
"@types/node": "^18.6.5", "@types/node": "^18.6.5",
"@types/react": "^18.0.17", "@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"fast-memoize": "^2.5.2",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-markdown": "^8.0.3", "react-markdown": "^8.0.3",

View File

@ -1,6 +1,6 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { PeerRoom, getPeerRoom } from 'services/PeerRoom' import { getPeerRoom } from 'services/PeerRoom'
interface UsePeerRoomProps { interface UsePeerRoomProps {
appId: string appId: string
@ -8,19 +8,11 @@ interface UsePeerRoomProps {
} }
export function usePeerRoom({ appId, roomId }: UsePeerRoomProps) { export function usePeerRoom({ appId, roomId }: UsePeerRoomProps) {
const [peerRoom, setPeerRoom] = useState<PeerRoom | null>(null) const [peerRoom, setPeerRoom] = useState(getPeerRoom({ appId }, roomId))
useEffect(() => { useEffect(() => {
;(async () => { setPeerRoom(getPeerRoom({ appId }, roomId))
setPeerRoom(await getPeerRoom({ appId }, roomId))
})()
}, [appId, roomId]) }, [appId, roomId])
useEffect(() => {
return () => {
peerRoom?.leaveRoom()
}
}, [peerRoom])
return peerRoom return peerRoom
} }

View File

@ -1,4 +1,3 @@
import React from 'react'
import ReactDOM from 'react-dom/client' import ReactDOM from 'react-dom/client'
import { BrowserRouter as Router } from 'react-router-dom' import { BrowserRouter as Router } from 'react-router-dom'
import { ThemeProvider, createTheme } from '@mui/material/styles' import { ThemeProvider, createTheme } from '@mui/material/styles'

View File

@ -1,6 +1,5 @@
import { joinRoom, Room, RoomConfig } from 'trystero' import { joinRoom, Room, RoomConfig } from 'trystero'
import memoize from 'fast-memoize'
import { sleep } from 'utils'
export class PeerRoom { export class PeerRoom {
private room: Room private room: Room
@ -23,24 +22,10 @@ export class PeerRoom {
} }
} }
// This abstraction is necessary because it takes some time for a PeerRoom to // Memoization isn't just a performance optimization here. It is necessary to
// be torn down, and there is no way to detect when that happens. If a new // prevent subsequent calls to getPeerRoom from causing a room collision due to
// PeerRoom is instantiated with the same config and roomId before the previous // the amount of time it takes for Trystero rooms to be torn down (which is an
// one is torn down, an error is thrown. The workaround is to continually // asynchronous operation).
// trying to instantiate a PeerRoom until it succeeds. export const getPeerRoom = memoize((config: RoomConfig, roomId: string) => {
export const getPeerRoom = async (config: RoomConfig, roomId: string) => {
const timeout = 1000
const epoch = Date.now()
do {
if (Date.now() - epoch > timeout) {
throw new Error('Could not create PeerRoom')
}
try {
return new PeerRoom(config, roomId) return new PeerRoom(config, roomId)
} catch (e) {} })
await sleep(100)
} while (true)
}