@@ -56,6 +56,7 @@ type Session struct {
5656 subscriptions map [string ]* Session
5757 subscribers map [string ]* Session
5858 disconnected bool
59+ replaced bool
5960}
6061
6162func NewSession (manager SessionManager , unicaster Unicaster , broadcaster Broadcaster , rooms RoomStatusManager , buddyImages ImageCache , attestations * securecookie.SecureCookie , id , sid string ) * Session {
@@ -85,16 +86,13 @@ func (s *Session) authenticated() (authenticated bool) {
8586}
8687
8788func (s * Session ) Subscribe (session * Session ) {
88-
8989 s .mutex .Lock ()
9090 s .subscriptions [session .Id ] = session
9191 s .mutex .Unlock ()
9292 session .AddSubscriber (s )
93-
9493}
9594
9695func (s * Session ) Unsubscribe (id string ) {
97-
9896 s .mutex .Lock ()
9997 if session , ok := s .subscriptions [id ]; ok {
10098 delete (s .subscriptions , id )
@@ -103,7 +101,6 @@ func (s *Session) Unsubscribe(id string) {
103101 } else {
104102 s .mutex .Unlock ()
105103 }
106-
107104}
108105
109106func (s * Session ) AddSubscriber (session * Session ) {
@@ -209,33 +206,39 @@ func (s *Session) Close() {
209206 return
210207 }
211208
212- outgoing := & DataOutgoing {
213- From : s .Id ,
214- A : s .attestation .Token (),
215- Data : & DataSession {
216- Type : "Left" ,
217- Id : s .Id ,
218- Status : "hard" ,
219- },
220- }
209+ // TODO(longsleep): Verify that it is ok to not do all this when replaced is true.
210+ if ! s .replaced {
221211
222- if s .Hello {
223- // NOTE(lcooper): If we don't check for Hello here, we could deadlock
224- // when implicitly creating a room while a user is reconnecting.
225- s .Broadcaster .Broadcast (s .Id , s .Roomid , outgoing )
226- s .RoomStatusManager .LeaveRoom (s .Roomid , s .Id )
227- }
212+ outgoing := & DataOutgoing {
213+ From : s .Id ,
214+ A : s .attestation .Token (),
215+ Data : & DataSession {
216+ Type : "Left" ,
217+ Id : s .Id ,
218+ Status : "hard" ,
219+ },
220+ }
228221
229- for _ , session := range s .subscribers {
230- s .Unicaster .Unicast (session .Id , outgoing )
231- }
222+ if s .Hello {
223+ // NOTE(lcooper): If we don't check for Hello here, we could deadlock
224+ // when implicitly creating a room while a user is reconnecting.
225+ s .Broadcaster .Broadcast (s .Id , s .Roomid , outgoing )
226+ s .RoomStatusManager .LeaveRoom (s .Roomid , s .Id )
227+ }
232228
233- for _ , session := range s .subscriptions {
234- session .RemoveSubscriber (s .Id )
235- }
229+ for _ , session := range s .subscribers {
230+ s .Unicaster .Unicast (session .Id , outgoing )
231+ }
232+
233+ for _ , session := range s .subscriptions {
234+ session .RemoveSubscriber (s .Id )
235+ s .Unicaster .Unicast (session .Id , outgoing )
236+ }
236237
237- s .SessionManager .DestroySession (s .Id , s .userid )
238- s .buddyImages .Delete (s .Id )
238+ s .SessionManager .DestroySession (s .Id , s .userid )
239+ s .buddyImages .Delete (s .Id )
240+
241+ }
239242
240243 s .subscriptions = make (map [string ]* Session )
241244 s .subscribers = make (map [string ]* Session )
@@ -244,6 +247,27 @@ func (s *Session) Close() {
244247 s .mutex .Unlock ()
245248}
246249
250+ func (s * Session ) Replace (oldSession * Session ) {
251+
252+ oldSession .mutex .Lock ()
253+ if oldSession .disconnected {
254+ oldSession .mutex .Unlock ()
255+ return
256+ }
257+
258+ s .mutex .Lock ()
259+
260+ s .subscriptions = oldSession .subscriptions
261+ s .subscribers = oldSession .subscribers
262+
263+ s .mutex .Unlock ()
264+
265+ // Mark old session as replaced.
266+ oldSession .replaced = true
267+ oldSession .mutex .Unlock ()
268+
269+ }
270+
247271func (s * Session ) Update (update * SessionUpdate ) uint64 {
248272 s .mutex .Lock ()
249273 defer s .mutex .Unlock ()
0 commit comments