diff --git a/services/real-time/app/coffee/ChannelManager.coffee b/services/real-time/app/coffee/ChannelManager.coffee index 4d5c843d10..1eca7a9143 100644 --- a/services/real-time/app/coffee/ChannelManager.coffee +++ b/services/real-time/app/coffee/ChannelManager.coffee @@ -9,11 +9,13 @@ ClientMap = new Map() # for each redis client, stores a Set of subscribed channe # handled by RoomManager. module.exports = ChannelManager = - _createNewClientEntry: (rclient) -> - ClientMap.set(rclient, new Set()).get(rclient) + getClientMapEntry: (rclient) -> + # return the rclient channel set if it exists, otherwise create and + # return an empty set for the client. + ClientMap.get(rclient) || ClientMap.set(rclient, new Set()).get(rclient) subscribe: (rclient, baseChannel, id) -> - existingChannelSet = ClientMap.get(rclient) || @_createNewClientEntry(rclient) + existingChannelSet = @getClientMapEntry(rclient) channel = "#{baseChannel}:#{id}" if existingChannelSet.has(channel) logger.error {channel}, "already subscribed - shouldn't happen" @@ -24,7 +26,7 @@ module.exports = ChannelManager = metrics.inc "subscribe.#{baseChannel}" unsubscribe: (rclient, baseChannel, id) -> - existingChannelSet = ClientMap.get(rclient) + existingChannelSet = @getClientMapEntry(rclient) channel = "#{baseChannel}:#{id}" if !existingChannelSet.has(channel) logger.error {channel}, "not subscribed - shouldn't happen" diff --git a/services/real-time/app/coffee/RoomManager.coffee b/services/real-time/app/coffee/RoomManager.coffee index d3a3bea5e8..225dd37f6d 100644 --- a/services/real-time/app/coffee/RoomManager.coffee +++ b/services/real-time/app/coffee/RoomManager.coffee @@ -17,13 +17,13 @@ RoomEvents = new EventEmitter() module.exports = RoomManager = joinProject: (client, project_id) -> - @_join client, "project", project_id + @joinEntity client, "project", project_id joinDoc: (client, doc_id) -> - @_join client, "doc", doc_id + @joinEntity client, "doc", doc_id leaveDoc: (client, doc_id) -> - @_leave client, "doc", doc_id + @leaveEntity client, "doc", doc_id leaveProjectAndDocs: (client) -> # what rooms is this client in? we need to leave them all. socket.io @@ -33,11 +33,36 @@ module.exports = RoomManager = # has not joined any rooms and do a final disconnection. for id in @_roomsClientIsIn(client) entity = IdMap.get(id) - @_leave client, entity, id + @leaveEntity client, entity, id eventSource: () -> return RoomEvents + joinEntity: (client, entity, id) -> + beforeCount = @_clientsInRoom(client, id) + client.join id + afterCount = @_clientsInRoom(client, id) + logger.log {client: client.id, entity, id, beforeCount, afterCount}, "client joined room" + # is this a new room? if so, subscribe + if beforeCount == 0 and afterCount == 1 + logger.log {entity, id}, "room is now active" + RoomEvents.emit "#{entity}-active", id + IdMap.set(id, entity) + + leaveEntity: (client, entity, id) -> + beforeCount = @_clientsInRoom(client, id) + client.leave id + afterCount = @_clientsInRoom(client, id) + logger.log {client: client.id, entity, id, beforeCount, afterCount}, "client left room" + # is the room now empty? if so, unsubscribe + if !entity? + logger.error {entity: id}, "unknown entity when leaving with id" + return + if beforeCount == 1 and afterCount == 0 + logger.log {entity, id}, "room is now empty" + RoomEvents.emit "#{entity}-empty", id + IdMap.delete(id) + # internal functions below, these access socket.io rooms data directly and # will need updating for socket.io v2 @@ -52,25 +77,3 @@ module.exports = RoomManager = [prefix, room] = fullRoomPath.split('/', 2) room return roomList - - _join: (client, entity, id) -> - beforeCount = @_clientsInRoom(client, id) - client.join id - afterCount = @_clientsInRoom(client, id) - logger.log {client: client.id, entity, id, beforeCount, afterCount}, "client joined room" - # is this a new room? if so, subscribe - if beforeCount == 0 and afterCount == 1 - logger.log {entity, id}, "room is now active" - RoomEvents.emit "#{entity}-active", id - IdMap.set(id, entity) - - _leave: (client, entity, id) -> - beforeCount = @_clientsInRoom(client, id) - client.leave id - afterCount = @_clientsInRoom(client, id) - logger.log {client: client.id, entity, id, beforeCount, afterCount}, "client left room" - # is the room now empty? if so, unsubscribe - if beforeCount == 1 and afterCount == 0 - logger.log {entity, id}, "room is now empty" - RoomEvents.emit "#{entity}-empty", id - IdMap.delete(id) \ No newline at end of file