Skip to content

Commit fc2885c

Browse files
committed
fix: prevent race condition in session creation
1 parent 942b403 commit fc2885c

1 file changed

Lines changed: 25 additions & 20 deletions

File tree

bindings/src/components/MultisynqRoot.tsx

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { useEffect, useState, useRef, useCallback } from 'react'
2-
import { MultisynqSession, App } from '@multisynq/client'
3-
import { MultisynqReactView } from '../MultisynqReactView'
4-
import { setSyncedCallback } from '../MultisynqReactView'
5-
import { MultisynqContext } from './MultisynqContext'
1+
import { App, MultisynqSession } from '@multisynq/client'
2+
import { useCallback, useEffect, useRef, useState } from 'react'
63
import { createMultisynqSession, MultisynqReactSessionParameters } from '../createMultisynqSession'
4+
import { MultisynqReactView, setSyncedCallback } from '../MultisynqReactView'
75
import { ReactModel } from '../ReactModel'
6+
import { MultisynqContext } from './MultisynqContext'
87

98
export interface ReactSessionParameters<M extends ReactModel> extends Omit<MultisynqReactSessionParameters<M>, 'name'> {
109
name?: string
@@ -39,11 +38,11 @@ export function MultisynqRoot<M extends ReactModel>({
3938
const [multisynqSession, setMultisynqSession] = useState<MultisynqSession<MultisynqReactView<M>> | null>(null)
4039
const [multisynqView, setMultisynqView] = useState<MultisynqReactView<M> | null>(null)
4140
const [currentSessionParams, setCurrentSessionParams] = useState<SessionParamsState<M>>(() => {
42-
if(!deferSession) {
43-
if(!sessionParams.name) {
41+
if (!deferSession) {
42+
if (!sessionParams.name) {
4443
sessionParams.name = App.randomSession()
4544
}
46-
if(!sessionParams.password) {
45+
if (!sessionParams.password) {
4746
sessionParams.password = App.randomPassword()
4847
}
4948
}
@@ -122,20 +121,30 @@ export function MultisynqRoot<M extends ReactModel>({
122121
join: true,
123122
}
124123

125-
if(!newParams.name) {
124+
if (!newParams.name) {
126125
newParams.name = App.randomSession()
127126
}
128-
if(!newParams.password) {
127+
if (!newParams.password) {
129128
newParams.password = App.randomPassword()
130129
}
131130

132131
// eslint-disable-next-line @typescript-eslint/no-unused-vars
133132
const { join, ...args } = newParams
134133

135-
createMultisynqSession(args).then((newSession) => {
136-
nextSessionRef.current = newSession
137-
setCurrentSessionParams(newParams)
138-
})
134+
try {
135+
const newSession = await createMultisynqSession(args)
136+
// Verify if the next session is null, if so, set the new session to the next session
137+
// and update the current session params
138+
if (nextSessionRef.current === null) {
139+
nextSessionRef.current = newSession
140+
setCurrentSessionParams(newParams)
141+
} else {
142+
// Another session was created in the meantime
143+
newSession.leave()
144+
}
145+
} catch (error) {
146+
console.error('Failed to create session:', error)
147+
}
139148
},
140149
[setCurrentSessionParams, currentSessionParams]
141150
)
@@ -152,13 +161,9 @@ export function MultisynqRoot<M extends ReactModel>({
152161
view: multisynqView,
153162
model: multisynqView?.model || null,
154163
setSession,
155-
leaveSession
164+
leaveSession,
156165
}
157-
return (
158-
<MultisynqContext.Provider value={contextValue}>
159-
{children}
160-
</MultisynqContext.Provider>
161-
)
166+
return <MultisynqContext.Provider value={contextValue}>{children}</MultisynqContext.Provider>
162167
}
163168
return null
164169
}

0 commit comments

Comments
 (0)