Brian Gough 7 лет назад
Родитель
Сommit
b49621b3e9

+ 15 - 0
services/document-updater/app/coffee/DeleteQueueManager.coffee

@@ -4,6 +4,21 @@ logger = require "logger-sharelatex"
 metrics = require "./Metrics"
 async = require "async"
 
+# Maintain a sorted set of project flushAndDelete requests, ordered by timestamp
+# (ZADD), and process them from oldest to newest. A flushAndDelete request comes
+# from real-time and is triggered when a user leaves a project. 
+#
+# The aim is to remove the project from redis 5 minutes after the last request
+# if there has been no activity (document updates) in that time.  If there is
+# activity we can expect a further flushAndDelete request when the editing user
+# leaves the project. 
+#
+# If a new flushAndDelete request comes in while an existing request is already
+# in the queue we update the timestamp as we can postpone flushing further.
+#
+# Documents are processed by checking the queue, seeing if the first entry is
+# older than 5 minutes, and popping it from the queue in that case.
+
 module.exports = DeleteQueueManager =
     flushAndDeleteOldProjects: (options, callback) ->
         startTime = Date.now()

+ 5 - 3
services/document-updater/app/coffee/RedisManager.coffee

@@ -295,17 +295,19 @@ module.exports = RedisManager =
 		multi.exec callback
 
 	queueFlushAndDeleteProject: (project_id, callback) ->
+		# store the project id in a sorted set ordered by time
 		rclient.zadd keys.flushAndDeleteQueue(), Date.now(), project_id, callback
 
 	getNextProjectToFlushAndDelete: (cutoffTime, callback = (error, key, timestamp)->) ->
-		# find the oldest queued flush
+		# find the oldest queued flush that is before the cutoff time
 		rclient.zrangebyscore keys.flushAndDeleteQueue(), 0, cutoffTime, "WITHSCORES", "LIMIT", 0, 1, (err, reply) ->
 			return callback(err) if err?
-			return callback() if !reply?.length
+			return callback() if !reply?.length # return if no projects ready to be processed
+			# pop the oldest entry (get and remove in a multi)
 			multi = rclient.multi()
 			multi.zrange keys.flushAndDeleteQueue(), 0, 0, "WITHSCORES"
 			multi.zremrangebyrank keys.flushAndDeleteQueue(), 0, 0
-			multi.zcard keys.flushAndDeleteQueue()
+			multi.zcard keys.flushAndDeleteQueue() # the total length of the queue (for metrics)
 			multi.exec (err, reply) ->
 				return callback(err) if err?
 				return callback() if !reply?.length