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

Use deterministic ids based on a seed

James Allen 9 лет назад
Родитель
Сommit
ae30f32481

+ 7 - 0
services/web/public/coffee/ide/editor/Document.coffee

@@ -83,6 +83,9 @@ define [
 		
 		setTrackingChanges: (track_changes) ->
 			@doc.track_changes = track_changes
+		
+		setTrackChangesIdSeeds: (id_seeds) ->
+			@doc.track_changes_id_seeds = id_seeds
 
 		_bindToSocketEvents: () ->
 			@_onUpdateAppliedHandler = (update) => @_onUpdateApplied(update)
@@ -319,6 +322,8 @@ define [
 					v: version
 			@doc.on "change", (ops, oldSnapshot, msg) =>
 				@_applyOpsToRanges(ops, oldSnapshot, msg)
+			@doc.on "flipped_pending_to_inflight", () =>
+				@trigger "flipped_pending_to_inflight"
 
 		_onError: (error, meta = {}) ->
 			meta.doc_id = @doc_id
@@ -335,6 +340,8 @@ define [
 		_applyOpsToRanges: (ops = [], oldSnapshot, msg) ->
 			track_changes_as = null
 			remote_op = msg?
+			if msg.meta?.tc?
+				@ranges.setIdSeed(msg.meta.tc)
 			if remote_op and msg.meta?.tc
 				track_changes_as = msg.meta.user_id
 			else if !remote_op and @track_changes_as?

+ 0 - 3
services/web/public/coffee/ide/editor/EditorManager.coffee

@@ -166,14 +166,11 @@ define [
 			if want == have
 				return
 
-			console.log "Trying to set track changes to:", want
 			do tryToggle = () =>
 				saved = !doc.getInflightOp()? and !doc.getPendingOp()?
 				if saved
-					console.log "SUCCESS, changing value", want
 					doc.setTrackingChanges(want)
 					@$scope.$apply () =>
 						@$scope.editor.trackChanges = want
 				else
-					console.log "Still in flight, will try soon"
 					@_syncTimeout = setTimeout tryToggle, 100

+ 4 - 2
services/web/public/coffee/ide/editor/ShareJsDoc.coffee

@@ -24,7 +24,7 @@ define [
 						return
 					if @track_changes
 						update.meta ?= {}
-						update.meta.tc = 1
+						update.meta.tc = @track_changes_id_seeds.inflight
 					@socket.emit "applyOtUpdate", @doc_id, update, (error) =>
 						return @_handleError(error) if error?
 				state: "ok"
@@ -44,6 +44,8 @@ define [
 				# ops as quickly as possible for low latency.
 				@_doc.setFlushDelay(0)
 				@trigger "remoteop", args...
+			@_doc.on "flipped_pending_to_inflight", () =>
+				@trigger "flipped_pending_to_inflight"
 			@_doc.on "error", (e) =>
 				@_handleError(e)
 
@@ -117,7 +119,7 @@ define [
 
 		attachToAce: (ace) -> @_doc.attach_ace(ace, false, window.maxDocLength)
 		detachFromAce: () -> @_doc.detach_ace?()
-	
+
 		INFLIGHT_OP_TIMEOUT: 5000 # Retry sending ops after 5 seconds without an ack
 		WAIT_FOR_CONNECTION_TIMEOUT: 500 # If we're waiting for the project to join, try again in 0.5 seconds
 		_startInflightOpTimeout: (update) ->

+ 2 - 0
services/web/public/coffee/ide/editor/sharejs/vendor/client/doc.coffee

@@ -266,6 +266,8 @@ class Doc
     @pendingOp = null
     @pendingCallbacks = []
 
+    @emit "flipped_pending_to_inflight"
+
     #console.log "SENDING OP TO SERVER", @inflightOp, @version
     @connection.send {doc:@name, op:@inflightOp, v:@version}
 

+ 14 - 20
services/web/public/coffee/ide/review-panel/RangesTracker.coffee

@@ -36,24 +36,18 @@ load = (EventEmitter) ->
 		#     middle of a previous insert by the first user, the original insert will be split into two.
 		constructor: (@changes = [], @comments = []) ->
 
-		@_increment: 0
-		@newId: () ->
-			# Generate a Mongo ObjectId
-			# Reference: https://github.com/dreampulse/ObjectId.js/blob/master/src/main/javascript/Objectid.js
-			@_pid ?= Math.floor(Math.random() * (32767))
-			@_machine ?= Math.floor(Math.random() * (16777216))
-			timestamp = Math.floor(new Date().valueOf() / 1000)
-			@_increment++
-			
-			timestamp = timestamp.toString(16)
-			machine = @_machine.toString(16)
-			pid = @_pid.toString(16)
-			increment = @_increment.toString(16)
-			
-			return '00000000'.substr(0, 8 - timestamp.length) + timestamp +
-				'000000'.substr(0, 6 - machine.length) + machine +
-				'0000'.substr(0, 4 - pid.length) + pid +
-				'000000'.substr(0, 6 - increment.length) + increment;
+		getIdSeed: () ->
+			return @id_seed
+
+		setIdSeed: (seed) ->
+			@id_seed = seed
+			@id_increment = 0
+
+		newId: () ->
+			@id_increment++
+			increment = @id_increment.toString(16)
+			id = @id_seed + '000000'.substr(0, 6 - increment.length) + increment;
+			return id
 		
 		getComment: (comment_id) ->
 			comment = null
@@ -99,7 +93,7 @@ load = (EventEmitter) ->
 		addComment: (op, metadata) ->
 			# TODO: Don't allow overlapping comments?
 			@comments.push comment = {
-				id: RangesTracker.newId()
+				id: @newId()
 				op: # Copy because we'll modify in place
 					c: op.c
 					p: op.p
@@ -390,7 +384,7 @@ load = (EventEmitter) ->
 
 		_addOp: (op, metadata) ->
 			change = {
-				id: RangesTracker.newId()
+				id: @newId()
 				op: op
 				metadata: metadata
 			}

+ 20 - 1
services/web/public/coffee/ide/review-panel/controllers/ReviewPanelController.coffee

@@ -75,12 +75,17 @@ define [
 			if view == $scope.SubViews.OVERVIEW
 				refreshOverviewPanel()
 
-		$scope.$watch "editor.sharejs_doc", (doc) ->
+		$scope.$watch "editor.sharejs_doc", (doc, old_doc) ->
 			return if !doc?
 			# The open doc range tracker is kept up to date in real-time so
 			# replace any outdated info with this
 			rangesTrackers[doc.doc_id] = doc.ranges
 			$scope.reviewPanel.rangesTracker = rangesTrackers[doc.doc_id]
+			if old_doc?
+				old_doc.off "flipped_pending_to_inflight"
+			doc.on "flipped_pending_to_inflight", () ->
+				regenerateTrackChangesId(doc)
+			regenerateTrackChangesId(doc)
 
 		$scope.$watch (() ->
 			entries = $scope.reviewPanel.entries[$scope.editor.open_doc_id] or {}
@@ -94,6 +99,20 @@ define [
 				$scope.$broadcast "review-panel:toggle"
 				$scope.$broadcast "review-panel:layout"
 		
+		regenerateTrackChangesId = (doc) ->
+			old_id = getChangeTracker(doc.doc_id).getIdSeed()
+			# Generate a the first 18 characters of Mongo ObjectId, leaving 6 for the increment part
+			# Reference: https://github.com/dreampulse/ObjectId.js/blob/master/src/main/javascript/Objectid.js
+			pid = Math.floor(Math.random() * (32767)).toString(16)
+			machine = Math.floor(Math.random() * (16777216)).toString(16)
+			timestamp = Math.floor(new Date().valueOf() / 1000).toString(16)
+			new_id = '00000000'.substr(0, 8 - timestamp.length) + timestamp +
+				'000000'.substr(0, 6 - machine.length) + machine +
+				'0000'.substr(0, 4 - pid.length) + pid
+			
+			getChangeTracker(doc.doc_id).setIdSeed(new_id)
+			doc.setTrackChangesIdSeeds({pending: new_id, inflight: old_id})
+		
 		refreshOverviewPanel = () ->
 			$scope.reviewPanel.overview.loading = true
 			$http.get "/project/#{$scope.project_id}/ranges"