adds /flush_all_projects project

This commit is contained in:
Henry Oswald 2019-05-02 16:30:36 +01:00
parent 70c505830b
commit d5d1736a5e
3 changed files with 78 additions and 0 deletions

View file

@ -59,6 +59,8 @@ app.post '/project/:project_id/doc/:doc_id/change/:change_id/accept', HttpCont
app.post '/project/:project_id/doc/:doc_id/change/accept', HttpController.acceptChanges
app.del '/project/:project_id/doc/:doc_id/comment/:comment_id', HttpController.deleteComment
app.get '/flush_all_projects', HttpController.flushAllProjects
app.get '/total', (req, res)->
timer = new Metrics.Timer("http.allDocList")
RedisManager.getCountOfDocsInMemory (err, count)->

View file

@ -4,6 +4,8 @@ ProjectManager = require "./ProjectManager"
Errors = require "./Errors"
logger = require "logger-sharelatex"
Metrics = require "./Metrics"
ProjectFlusher = require("./ProjectFlusher")
TWO_MEGABYTES = 2 * 1024 * 1024
@ -179,3 +181,16 @@ module.exports = HttpController =
return next(error) if error?
logger.log {project_id}, "queued project history resync via http"
res.send 204
flushAllProjects: (req, res, next = (error)-> )->
res.setTimeout(5 * 60 * 1000)
limit = req.query.limit || 1000
concurrency = req.query.concurrency || 5
ProjectFlusher.flushAllProjects limit, concurrency, (err, project_ids)->
if err?
logger.err err:err, "error bulk flushing projects"
res.send 500
else
res.send project_ids

View file

@ -0,0 +1,61 @@
request = require("request")
Settings = require('settings-sharelatex')
RedisManager = require("./RedisManager")
rclient = RedisManager.rclient
docUpdaterKeys = Settings.redis.documentupdater.key_schema
async = require("async")
ProjectManager = require("./ProjectManager")
_ = require("lodash")
ProjectFlusher =
# iterate over keys asynchronously using redis scan (non-blocking)
# handle all the cluster nodes or single redis server
_getKeys: (pattern, limit, callback) ->
nodes = rclient.nodes?('master') || [ rclient ];
doKeyLookupForNode = (node, cb) ->
ProjectFlusher._getKeysFromNode node, pattern, limit, cb
async.concatSeries nodes, doKeyLookupForNode, callback
_getKeysFromNode: (node, pattern, limit = 1000, callback) ->
cursor = 0 # redis iterator
keySet = {} # use hash to avoid duplicate results
batchSize = if limit? then Math.min(limit, 1000) else 1000
# scan over all keys looking for pattern
doIteration = (cb) ->
node.scan cursor, "MATCH", pattern, "COUNT", batchSize, (error, reply) ->
return callback(error) if error?
[cursor, keys] = reply
for key in keys
keySet[key] = true
keys = Object.keys(keySet)
noResults = cursor == "0" # redis returns string results not numeric
limitReached = (limit? && keys.length >= limit)
if noResults || limitReached
return callback(null, keys)
else
setTimeout doIteration, 10 # avoid hitting redis too hard
doIteration()
# extract ids from keys like DocsWithHistoryOps:57fd0b1f53a8396d22b2c24b
# or docsInProject:{57fd0b1f53a8396d22b2c24b} (for redis cluster)
_extractIds: (keyList) ->
ids = for key in keyList
m = key.match(/:\{?([0-9a-f]{24})\}?/) # extract object id
m[1]
return ids
flushAllProjects: (limit, concurrency = 5, callback)->
ProjectFlusher._getKeys docUpdaterKeys.docsInProject({project_id:"*"}), limit, (error, project_keys) ->
if error?
logger.err err:error, "error getting keys for flushing"
return callback(error)
project_ids = ProjectFlusher._extractIds(project_keys)
jobs = _.map project_ids, (project_id)->
return (cb)->
ProjectManager.flushAndDeleteProjectWithLocks project_id, cb
async.parallelLimit jobs, concurrency, (error)->
return callback(error, project_ids)
module.exports = ProjectFlusher