From b49621b3e9da275018fadabe929c9729d382acf3 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Thu, 26 Sep 2019 10:14:49 +0100 Subject: [PATCH] add comments --- .../app/coffee/DeleteQueueManager.coffee | 15 +++++++++++++++ .../app/coffee/RedisManager.coffee | 8 +++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/services/document-updater/app/coffee/DeleteQueueManager.coffee b/services/document-updater/app/coffee/DeleteQueueManager.coffee index cad65ae2f5..835f718615 100644 --- a/services/document-updater/app/coffee/DeleteQueueManager.coffee +++ b/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() diff --git a/services/document-updater/app/coffee/RedisManager.coffee b/services/document-updater/app/coffee/RedisManager.coffee index f5530b99fd..7f62fe1e7e 100644 --- a/services/document-updater/app/coffee/RedisManager.coffee +++ b/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