Просмотр исходного кода

Don't care if user key has expired when we receive a cursor update

James Allen 12 лет назад
Родитель
Сommit
1c68ea7328

+ 12 - 10
services/web/app/coffee/Features/ConnectedUsers/ConnectedUsersManager.coffee

@@ -19,18 +19,27 @@ buildUserKey = (project_id, client_id)-> return "connected_user:#{project_id}:#{
 
 module.exports =
 
-	markUserAsConnected: (project_id, client_id, user, callback = (err)->)->
+	# Use the same method for when a user connects, and when a user sends a cursor
+	# update. This way we don't care if the connected_user key has expired when
+	# we receive a cursor update. 
+	updateUserPosition: (project_id, client_id, user, cursorData, callback = (err)->)->
 		logger.log project_id:project_id, client_id:client_id, "marking user as connected"
 
 		multi = rclient.multi()
-		multi.sadd buildProjectSetKey(project_id), client_id
+		
+		multi.sadd   buildProjectSetKey(project_id), client_id
 		multi.expire buildProjectSetKey(project_id), FOUR_DAYS_IN_S
-		multi.hset buildUserKey(project_id, client_id), "connected_at", Date.now()
+		
+		multi.hset buildUserKey(project_id, client_id), "last_updated_at", Date.now()
 		multi.hset buildUserKey(project_id, client_id), "user_id", user._id
 		multi.hset buildUserKey(project_id, client_id), "first_name", user.first_name
 		multi.hset buildUserKey(project_id, client_id), "last_name", user.last_name
 		multi.hset buildUserKey(project_id, client_id), "email", user.email
+		
+		if cursorData?
+			multi.hset buildUserKey(project_id, client_id), "cursorData", JSON.stringify(cursorData)
 		multi.expire buildUserKey(project_id, client_id), USER_TIMEOUT_IN_S
+		
 		multi.exec (err)->
 			if err?
 				logger.err err:err, project_id:project_id, client_id:client_id, "problem marking user as connected"
@@ -58,13 +67,6 @@ module.exports =
 					result.cursorData = JSON.parse(result.cursorData)
 			callback err, result
 
-	setUserCursorPosition: (project_id, client_id, cursorData, callback)->
-		multi = rclient.multi()
-		multi.hset buildUserKey(project_id, client_id), "cursorData", JSON.stringify(cursorData)
-		multi.expire buildUserKey(project_id, client_id), USER_TIMEOUT_IN_S
-		multi.exec callback
-
-
 	getConnectedUsers: (project_id, callback)->
 		self = @
 		rclient.smembers buildProjectSetKey(project_id), (err, results)->

+ 7 - 2
services/web/app/coffee/Features/Editor/EditorController.coffee

@@ -59,7 +59,7 @@ module.exports = EditorController =
 							callback null, ProjectEditorHandler.buildProjectModelView(project), privilegeLevel, EditorController.protocolVersion
 
 							# can be done affter the connection has happened
-							ConnectedUsersManager.markUserAsConnected project_id, client.id, user, ->
+							ConnectedUsersManager.updateUserPosition project_id, client.id, user, null, ->
 
 	leaveProject: (client, user) ->
 		self = @
@@ -124,7 +124,12 @@ module.exports = EditorController =
 			cursorData.email = email if email?
 			if first_name? and last_name?
 				cursorData.name = first_name + " " + last_name
-				ConnectedUsersManager.setUserCursorPosition(project_id, client.id, {
+				ConnectedUsersManager.updateUserPosition(project_id, client.id, {
+					first_name: first_name,
+					last_name:  last_name,
+					email:      email,
+					user_id:    user_id
+				}, {
 					row: cursorData.row,
 					column: cursorData.column,
 					doc_id: cursorData.doc_id

+ 18 - 29
services/web/test/UnitTests/coffee/ConnectedUsers/ConnectedUsersManagerTests.coffee

@@ -44,54 +44,60 @@ describe "ConnectedUsersManager", ->
 			last_name: "Bloggs"
 			email: "joe@example.com"
 		}
+		@cursorData = { row: 12, column: 9, doc_id: '53c3b8c85fee64000023dc6e' }
 
 	afterEach -> 
 		tk.reset()
 
-	describe "markUserAsConnected", ->
+	describe "updateUserPosition", ->
 		beforeEach ->
 			@rClient.exec.callsArgWith(0)
 
 		it "should set a key with the date and give it a ttl", (done)->
-			@ConnectedUsersManager.markUserAsConnected @project_id, @client_id, @user, (err)=>
-				@rClient.hset.calledWith("connected_user:#{@project_id}:#{@client_id}", "connected_at", Date.now()).should.equal true
+			@ConnectedUsersManager.updateUserPosition @project_id, @client_id, @user, null, (err)=>
+				@rClient.hset.calledWith("connected_user:#{@project_id}:#{@client_id}", "last_updated_at", Date.now()).should.equal true
 				done()
 
 		it "should set a key with the user_id", (done)->
-			@ConnectedUsersManager.markUserAsConnected @project_id, @client_id, @user, (err)=>
+			@ConnectedUsersManager.updateUserPosition @project_id, @client_id, @user, null, (err)=>
 				@rClient.hset.calledWith("connected_user:#{@project_id}:#{@client_id}", "user_id", @user._id).should.equal true
 				done()
 
 		it "should set a key with the first_name", (done)->
-			@ConnectedUsersManager.markUserAsConnected @project_id, @client_id, @user, (err)=>
+			@ConnectedUsersManager.updateUserPosition @project_id, @client_id, @user, null, (err)=>
 				@rClient.hset.calledWith("connected_user:#{@project_id}:#{@client_id}", "first_name", @user.first_name).should.equal true
 				done()
 
 		it "should set a key with the last_name", (done)->
-			@ConnectedUsersManager.markUserAsConnected @project_id, @client_id, @user, (err)=>
+			@ConnectedUsersManager.updateUserPosition @project_id, @client_id, @user, null, (err)=>
 				@rClient.hset.calledWith("connected_user:#{@project_id}:#{@client_id}", "last_name", @user.last_name).should.equal true
 				done()
 
 		it "should set a key with the email", (done)->
-			@ConnectedUsersManager.markUserAsConnected @project_id, @client_id, @user, (err)=>
+			@ConnectedUsersManager.updateUserPosition @project_id, @client_id, @user, null, (err)=>
 				@rClient.hset.calledWith("connected_user:#{@project_id}:#{@client_id}", "email", @user.email).should.equal true
 				done()
 
 		it "should push the client_id on to the project list", (done)->
-			@ConnectedUsersManager.markUserAsConnected @project_id, @client_id, @user, (err)=>
+			@ConnectedUsersManager.updateUserPosition @project_id, @client_id, @user, null, (err)=>
 				@rClient.sadd.calledWith("clients_in_project:#{@project_id}", @client_id).should.equal true
 				done()
 
-		it "should add a ttl to the connected user set so it stays clean", (done)->
-			@ConnectedUsersManager.markUserAsConnected @project_id, @client_id, @user, (err)=>
+		it "should add a ttl to the project set so it stays clean", (done)->
+			@ConnectedUsersManager.updateUserPosition @project_id, @client_id, @user, null, (err)=>
 				@rClient.expire.calledWith("clients_in_project:#{@project_id}", 24 * 4 * 60 * 60).should.equal true
 				done()
 
-		it "should add a ttl to the connected user so it stays clean", (done)->
-			@ConnectedUsersManager.markUserAsConnected @project_id, @client_id, @user, (err)=>
+		it "should add a ttl to the connected user so it stays clean", (done) ->
+			@ConnectedUsersManager.updateUserPosition @project_id, @client_id, @user, null, (err)=>
 				@rClient.expire.calledWith("connected_user:#{@project_id}:#{@client_id}", 60 * 15).should.equal true
 				done()
 
+		it "should set the cursor position when provided", (done)->
+			@ConnectedUsersManager.updateUserPosition @project_id, @client_id, @user, @cursorData, (err)=>
+				@rClient.hset.calledWith("connected_user:#{@project_id}:#{@client_id}", "cursorData", JSON.stringify(@cursorData)).should.equal true
+				done()
+
 	describe "markUserAsDisconnected", ->
 		beforeEach ->
 			@rClient.exec.callsArgWith(0)
@@ -146,20 +152,3 @@ describe "ConnectedUsersManager", ->
 				users[1].should.deep.equal {client_id:@users[2], connected:true}
 				done()
 
-	describe "setUserCursorPosition", ->
-
-		beforeEach ->
-			@cursorData = { row: 12, column: 9, doc_id: '53c3b8c85fee64000023dc6e' }
-			@rClient.exec.callsArgWith(0)
-
-		it "should add the cursor data to the users hash", (done)->
-			@ConnectedUsersManager.setUserCursorPosition @project_id, @client_id, @cursorData, (err)=>
-				@rClient.hset.calledWith("connected_user:#{@project_id}:#{@client_id}", "cursorData", JSON.stringify(@cursorData)).should.equal true
-				done()
-
-
-		it "should add the ttl on", (done)->
-			@ConnectedUsersManager.setUserCursorPosition @project_id, @client_id, @cursorData, (err)=>
-				@rClient.expire.calledWith("connected_user:#{@project_id}:#{@client_id}", 60 * 15).should.equal true
-				done()
-

+ 11 - 7
services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee

@@ -55,8 +55,7 @@ describe "EditorController", ->
 			deleteProject: sinon.stub()
 		@ConnectedUsersManager =
 			markUserAsDisconnected:sinon.stub()
-			markUserAsConnected:sinon.stub()
-			setUserCursorPosition:sinon.stub()
+			updateUserPosition:sinon.stub()
 
 		@EditorController = SandboxedModule.require modulePath, requires:
 			"../../infrastructure/Server" : io : @io
@@ -91,7 +90,7 @@ describe "EditorController", ->
 			@ProjectGetter.populateProjectWithUsers = sinon.stub().callsArgWith(1, null, @project)
 			@AuthorizationManager.setPrivilegeLevelOnClient = sinon.stub()
 			@EditorRealTimeController.emitToRoom = sinon.stub()
-			@ConnectedUsersManager.markUserAsConnected.callsArgWith(3)
+			@ConnectedUsersManager.updateUserPosition.callsArgWith(4)
 
 		describe "when authorized", ->
 			beforeEach ->
@@ -124,7 +123,7 @@ describe "EditorController", ->
 				@callback.calledWith(null, @projectModelView, "owner", @EditorController.protocolVersion).should.equal true
 
 			it "should mark the user as connected with the ConnectedUsersManager", ->
-				@ConnectedUsersManager.markUserAsConnected.calledWith(@project_id, @client.id, @user).should.equal true
+				@ConnectedUsersManager.updateUserPosition.calledWith(@project_id, @client.id, @user, null).should.equal true
 
 
 		describe "when not authorized", ->
@@ -257,7 +256,7 @@ describe "EditorController", ->
 	describe "updateClientPosition", ->
 		beforeEach ->
 			@EditorRealTimeController.emitToRoom = sinon.stub()
-			@ConnectedUsersManager.setUserCursorPosition.callsArgWith(3)
+			@ConnectedUsersManager.updateUserPosition.callsArgWith(4)
 			@update = {
 				doc_id: @doc_id = "doc-id-123"
 				row: @row = 42
@@ -290,7 +289,12 @@ describe "EditorController", ->
 				@EditorRealTimeController.emitToRoom.calledWith(@project_id, "clientTracking.clientUpdated", @populatedCursorData).should.equal true
 
 			it "should send the  cursor data to the connected user manager", (done)->
-				@ConnectedUsersManager.setUserCursorPosition.calledWith(@project_id, @client.id, {
+				@ConnectedUsersManager.updateUserPosition.calledWith(@project_id, @client.id, {
+					user_id: @user_id,
+					email: @email,
+					first_name: @first_name,
+					last_name: @last_name
+				}, {
 					row: @row
 					column: @column
 					doc_id: @doc_id
@@ -317,7 +321,7 @@ describe "EditorController", ->
 					.should.equal true
 				
 			it "should not send cursor data to the connected user manager", (done)->
-				@ConnectedUsersManager.setUserCursorPosition.called.should.equal false
+				@ConnectedUsersManager.updateUserPosition.called.should.equal false
 				done()
 
 	describe "addUserToProject", ->