mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
make history update more atomic
This commit is contained in:
parent
ce5b7957a5
commit
79d8fced49
4 changed files with 17 additions and 24 deletions
|
@ -8,13 +8,9 @@ module.exports = HistoryRedisManager =
|
|||
pushUncompressedHistoryOps: (project_id, doc_id, ops = [], callback = (error, length) ->) ->
|
||||
if ops.length == 0
|
||||
return callback(new Error("cannot push no ops")) # This should never be called with no ops, but protect against a redis error if we sent an empty array to rpush
|
||||
opVersions = ops.map (op) -> op?.v
|
||||
logger.log project_id: project_id, doc_id: doc_id, op_versions: opVersions, "pushing uncompressed history ops"
|
||||
jsonOps = ops.map (op) -> JSON.stringify op
|
||||
async.parallel [
|
||||
(cb) -> rclient.rpush Keys.uncompressedHistoryOps({doc_id}), jsonOps..., cb
|
||||
(cb) -> rclient.sadd Keys.docsWithHistoryOps({project_id}), doc_id, cb
|
||||
], (error, results) ->
|
||||
logger.log project_id: project_id, doc_id: doc_id, "marking doc in project for history ops"
|
||||
rclient.sadd Keys.docsWithHistoryOps({project_id}), doc_id, (error) ->
|
||||
return callback(error) if error?
|
||||
[length, _] = results
|
||||
callback(error, length)
|
||||
rclient.llen Keys.uncompressedHistoryOps({doc_id}), (error, length) ->
|
||||
return callback(error) if error?
|
||||
callback(null, length)
|
||||
|
|
|
@ -25,6 +25,7 @@ MEGABYTES = 1024 * 1024
|
|||
MAX_RANGES_SIZE = 3 * MEGABYTES
|
||||
|
||||
keys = Settings.redis.documentupdater.key_schema
|
||||
historyKeys = Settings.redis.history.key_schema
|
||||
|
||||
module.exports = RedisManager =
|
||||
rclient: rclient
|
||||
|
@ -167,9 +168,10 @@ module.exports = RedisManager =
|
|||
logger.error err: error, doc_id: doc_id, newDocLines: newDocLines, error.message
|
||||
return callback(error)
|
||||
newHash = RedisManager._computeHash(newDocLines)
|
||||
|
||||
logger.log doc_id: doc_id, version: newVersion, hash: newHash, "updating doc in redis"
|
||||
|
||||
|
||||
opVersions = appliedOps.map (op) -> op?.v
|
||||
logger.log doc_id: doc_id, version: newVersion, hash: newHash, op_versions: opVersions, "updating doc in redis"
|
||||
|
||||
RedisManager._serializeRanges ranges, (error, ranges) ->
|
||||
if error?
|
||||
logger.error {err: error, doc_id}, error.message
|
||||
|
@ -180,6 +182,7 @@ module.exports = RedisManager =
|
|||
multi.set keys.docHash(doc_id:doc_id), newHash
|
||||
if jsonOps.length > 0
|
||||
multi.rpush keys.docOps(doc_id: doc_id), jsonOps...
|
||||
multi.rpush historyKeys.uncompressedHistoryOps(doc_id: doc_id), jsonOps...
|
||||
multi.expire keys.docOps(doc_id: doc_id), RedisManager.DOC_OPS_TTL
|
||||
multi.ltrim keys.docOps(doc_id: doc_id), -RedisManager.DOC_OPS_MAX_LENGTH, -1
|
||||
if ranges?
|
||||
|
|
|
@ -27,7 +27,7 @@ describe "HistoryRedisManager", ->
|
|||
describe "pushUncompressedHistoryOps", ->
|
||||
beforeEach ->
|
||||
@ops = [{ op: [{ i: "foo", p: 4 }] },{ op: [{ i: "bar", p: 56 }] }]
|
||||
@rclient.rpush = sinon.stub().yields(null, @length = 42)
|
||||
@rclient.llen = sinon.stub().yields(null, @length = 42)
|
||||
@rclient.sadd = sinon.stub().yields()
|
||||
|
||||
describe "with ops", ->
|
||||
|
@ -36,11 +36,6 @@ describe "HistoryRedisManager", ->
|
|||
@callback(args...)
|
||||
done()
|
||||
|
||||
it "should push the doc op into the doc ops list as JSON", ->
|
||||
@rclient.rpush
|
||||
.calledWith("UncompressedHistoryOps:#{@doc_id}", JSON.stringify(@ops[0]), JSON.stringify(@ops[1]))
|
||||
.should.equal true
|
||||
|
||||
it "should add the doc_id to the set of which records the project docs", ->
|
||||
@rclient.sadd
|
||||
.calledWith("DocsWithHistoryOps:#{@project_id}", @doc_id)
|
||||
|
@ -55,11 +50,6 @@ describe "HistoryRedisManager", ->
|
|||
@callback(args...)
|
||||
done()
|
||||
|
||||
it "should not push the doc op into the doc ops list as JSON", ->
|
||||
@rclient.rpush
|
||||
.called
|
||||
.should.equal false
|
||||
|
||||
it "should not add the doc_id to the set of which records the project docs", ->
|
||||
@rclient.sadd
|
||||
.called
|
||||
|
|
|
@ -19,7 +19,7 @@ describe "RedisManager", ->
|
|||
documentupdater: {logHashErrors: {write:true, read:true}}
|
||||
redis:
|
||||
documentupdater:
|
||||
key_schema:
|
||||
key_schema:
|
||||
blockingKey: ({doc_id}) -> "Blocking:#{doc_id}"
|
||||
docLines: ({doc_id}) -> "doclines:#{doc_id}"
|
||||
docOps: ({doc_id}) -> "DocOps:#{doc_id}"
|
||||
|
@ -29,6 +29,10 @@ describe "RedisManager", ->
|
|||
pendingUpdates: ({doc_id}) -> "PendingUpdates:#{doc_id}"
|
||||
docsInProject: ({project_id}) -> "DocsIn:#{project_id}"
|
||||
ranges: ({doc_id}) -> "Ranges:#{doc_id}"
|
||||
history:
|
||||
key_schema:
|
||||
uncompressedHistoryOps: ({doc_id}) -> "UncompressedHistoryOps:#{doc_id}"
|
||||
docsWithHistoryOps: ({project_id}) -> "DocsWithHistoryOps:#{project_id}"
|
||||
}
|
||||
"redis-sharelatex":
|
||||
createClient: () => @rclient
|
||||
|
|
Loading…
Reference in a new issue