[misc] exportProject: collect and send user ids of updates in trailer

This commit is contained in:
Jakob Ackermann
2021-02-25 09:52:54 +00:00
parent f411049b82
commit ed70b99d8a
5 changed files with 49 additions and 18 deletions
@@ -209,7 +209,7 @@ module.exports = HttpController = {
logger.log({ project_id }, 'exporting project history')
UpdatesManager.exportProject(project_id, function (
err,
updates,
{ updates, userIds },
confirmWrite
) {
const abortStreaming = req.aborted || res.finished || res.destroyed
@@ -236,6 +236,7 @@ module.exports = HttpController = {
// The first write will emit the 200 status, headers and start of the
// response payload (open array)
res.setHeader('Content-Type', 'application/json')
res.setHeader('Trailer', 'X-User-Ids')
res.writeHead(200)
res.write('[')
}
@@ -255,7 +256,8 @@ module.exports = HttpController = {
if (isLastWrite) {
// The last write will have no updates and will finish the response
// payload (close array).
// payload (close array) and emit the userIds as trailer.
res.addTrailers({ 'X-User-Ids': JSON.stringify(userIds) })
res.end(']')
}
})
@@ -641,6 +641,8 @@ module.exports = UpdatesManager = {
PackManager.makeProjectIterator(projectId, before, (err, iterator) => {
if (err) return consumer(err)
const accumulatedUserIds = new Set()
async.whilst(
() => !iterator.done(),
@@ -654,13 +656,26 @@ module.exports = UpdatesManager = {
// call.
return cb()
}
updatesFromASinglePack.forEach((update) => {
accumulatedUserIds.add(
// Super defensive access on update details.
String(update && update.meta && update.meta.user_id)
)
})
// Emit updates and wait for the consumer.
consumer(null, updatesFromASinglePack, cb)
consumer(null, { updates: updatesFromASinglePack }, cb)
}),
(err) => {
if (err) return consumer(err)
consumer(null, [])
// Adding undefined can happen for broken updates.
accumulatedUserIds.delete('undefined')
consumer(null, {
updates: [],
userIds: Array.from(accumulatedUserIds).sort()
})
}
)
})