allow some operations to proceed in parallel

some code chunks previously used `async.parallel` but if you
use `await` that forces them to be run serially.  Instead,
you can initiate the operation (getting a Promise) and then
_later_ `await` the result of that Promise.
This commit is contained in:
Ray Bellis 2019-02-01 09:57:50 +00:00
parent e7c2fad7b0
commit 769933786c
3 changed files with 37 additions and 21 deletions

View file

@ -169,9 +169,8 @@ Pad.prototype.getInternalRevisionAText = async function getInternalRevisionAText
// get all needed data out of the database
// get the atext of the key revision
let _atext = await db.getSub("pad:" + this.id + ":revs:" + keyRev, ["meta", "atext"]);
let atext = Changeset.cloneAText(_atext);
// start to get the atext of the key revision
let p_atext = db.getSub("pad:" + this.id + ":revs:" + keyRev, ["meta", "atext"]);
// get all needed changesets
let changesets = [];
@ -181,6 +180,10 @@ Pad.prototype.getInternalRevisionAText = async function getInternalRevisionAText
});
}));
// we should have the atext by now
let atext = await p_atext;
atext = Changeset.cloneAText(atext);
// apply all changesets to the key changeset
let apool = this.apool();
for (let curRev = keyRev; curRev < targetRev; ) {
@ -455,7 +458,10 @@ Pad.prototype.remove = async function remove() {
// kick everyone from this pad
padMessageHandler.kickSessionsFromPad(padID);
// delete all relations
// delete all relations - the original code used async.parallel but
// none of the operations except getting the group depended on callbacks
// so the database operations here are just started and then left to
// run to completion
// is it a group pad? -> delete the entry of this pad in the group
if (padID.indexOf("$") >= 0) {

View file

@ -49,11 +49,11 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
return deny;
}
// get author for this token
let tokenAuthor = await authorManager.getAuthor4Token(token);
// start to get author for this token
let p_tokenAuthor = authorManager.getAuthor4Token(token);
// check if pad exists
let padExists = await padManager.doesPadExist(padID);
// start to check if pad exists
let p_padExists = padManager.doesPadExist(padID);
if (settings.requireSession) {
// a valid session is required (api-only mode)
@ -67,11 +67,14 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
// it's not a group pad, means we can grant access
// assume user has access
let statusObject = { accessStatus: "grant", authorID: tokenAuthor };
let authorID = await p_tokenAuthor;
let statusObject = { accessStatus: "grant", authorID };
if (settings.editOnly) {
// user can't create pads
let padExists = await p_padExists;
if (!padExists) {
// pad doesn't exist - user can't have access
statusObject.accessStatus = "deny";
@ -96,10 +99,13 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
let sessionIDs = sessionCookie.split(',');
// was previously iterated in parallel using async.forEach
for (let sessionID of sessionIDs) {
try {
let sessionInfo = await sessionManager.getSessionInfo(sessionID);
let sessionInfos = await Promise.all(sessionIDs.map(sessionID => {
return sessionManager.getSessionInfo(sessionID);
}));
// seperated out the iteration of sessioninfos from the (parallel) fetches from the DB
for (let sessionInfo of sessionInfos) {
try {
// is it for this group?
if (sessionInfo.groupID != groupID) {
authLogger.debug("Auth failed: wrong group");
@ -128,6 +134,8 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
}
}
let padExists = await p_padExists;
if (padExists) {
let pad = await padManager.getPad(padID);
@ -205,7 +213,7 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
if (!validSession && padExists) {
// there is no valid session avaiable AND pad exists
let authorID = tokenAuthor;
let authorID = await p_tokenAuthor;
let grant = Object.freeze({ accessStatus: "grant", authorID });
if (isPublic && !isPasswordProtected) {

View file

@ -890,8 +890,6 @@ async function handleClientReady(client, message)
return;
}
var historicalAuthorData = {};
hooks.callAll("clientReady", message);
// Get ro/rw id:s
@ -915,12 +913,12 @@ async function handleClientReady(client, message)
let author = statusObject.authorID;
// get all authordata of this new user, and load the pad-object from the database
// get all authordata of this new user
let value = await authorManager.getAuthor(author);
let authorColorId = value.colorId;
let authorName = value.name;
// get pad
// load the pad-object from the database
let pad = await padManager.getPad(padIds.padId);
// these db requests all need the pad object (timestamp of latest revision, author data)
@ -930,6 +928,7 @@ async function handleClientReady(client, message)
let currentTime = await pad.getRevisionDate(pad.getHeadRevisionNumber());
// get all author data out of the database (in parallel)
let historicalAuthorData = {};
await Promise.all(authors.map(authorId => {
return authorManager.getAuthor(authorId).then(author => {
if (!author) {
@ -1010,12 +1009,15 @@ async function handleClientReady(client, message)
changesets[r] = {};
}
// get changesets, author and timestamp needed for pending revisions
// get changesets, author and timestamp needed for pending revisions (in parallel)
let promises = [];
for (let revNum of revisionsNeeded) {
changesets[revNum]['changeset'] = await pad.getRevisionChangeset(revNum);
changesets[revNum]['author'] = await pad.getRevisionAuthor(revNum);
changesets[revNum]['timestamp'] = await pad.getRevisionDate(revNum);
let cs = changesets[revNum];
promises.push( pad.getRevisionChangeset(revNum).then(result => cs.changeset = result ));
promises.push( pad.getRevisionAuthor(revNum).then(result => cs.author = result ));
promises.push( pad.getRevisionDate(revNum).then(result => cs.timestamp = result ));
}
await Promise.all(promises);
// return pending changesets
for (let r of revisionsNeeded) {