Skip to content

Commit

Permalink
allow some operations to proceed in parallel
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
raybellis committed Feb 1, 2019
1 parent fe77899 commit 60decc3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 21 deletions.
14 changes: 10 additions & 4 deletions src/node/db/Pad.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];
Expand All @@ -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; ) {
Expand Down Expand Up @@ -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) {
Expand Down
26 changes: 17 additions & 9 deletions src/node/db/SecurityManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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";
Expand All @@ -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");
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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) {
Expand Down
18 changes: 10 additions & 8 deletions src/node/handler/PadMessageHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -890,8 +890,6 @@ async function handleClientReady(client, message)
return;
}

var historicalAuthorData = {};

hooks.callAll("clientReady", message);

// Get ro/rw id:s
Expand All @@ -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)
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 60decc3

Please sign in to comment.