mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-21 07:56:16 -04:00
SessionManager: Use .setSub()
and parallel queries to avoid races
This also simplfies the code.
This commit is contained in:
parent
3070cee9ca
commit
9d63700da0
1 changed files with 17 additions and 51 deletions
|
@ -134,41 +134,14 @@ exports.createSession = async (groupID, authorID, validUntil) => {
|
||||||
// set the session into the database
|
// set the session into the database
|
||||||
await db.set(`session:${sessionID}`, {groupID, authorID, validUntil});
|
await db.set(`session:${sessionID}`, {groupID, authorID, validUntil});
|
||||||
|
|
||||||
// get the entry
|
// Add the session ID to the group2sessions and author2sessions records after creating the session
|
||||||
let group2sessions = await db.get(`group2sessions:${groupID}`);
|
// so that the state is consistent.
|
||||||
|
await Promise.all([
|
||||||
/*
|
// UeberDB's setSub() method atomically reads the record, updates the appropriate (sub)object
|
||||||
* In some cases, the db layer could return "undefined" as well as "null".
|
// property, and writes the result.
|
||||||
* Thus, it is not possible to perform strict null checks on group2sessions.
|
db.setSub(`group2sessions:${groupID}`, ['sessionIDs', sessionID], 1),
|
||||||
* In a previous version of this code, a strict check broke session
|
db.setSub(`author2sessions:${authorID}`, ['sessionIDs', sessionID], 1),
|
||||||
* management.
|
]);
|
||||||
*
|
|
||||||
* See: https://github.com/ether/etherpad-lite/issues/3567#issuecomment-468613960
|
|
||||||
*/
|
|
||||||
if (!group2sessions || !group2sessions.sessionIDs) {
|
|
||||||
// the entry doesn't exist so far, let's create it
|
|
||||||
group2sessions = {sessionIDs: {}};
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the entry for this session
|
|
||||||
group2sessions.sessionIDs[sessionID] = 1;
|
|
||||||
|
|
||||||
// save the new element back
|
|
||||||
await db.set(`group2sessions:${groupID}`, group2sessions);
|
|
||||||
|
|
||||||
// get the author2sessions entry
|
|
||||||
let author2sessions = await db.get(`author2sessions:${authorID}`);
|
|
||||||
|
|
||||||
if (author2sessions == null || author2sessions.sessionIDs == null) {
|
|
||||||
// the entry doesn't exist so far, let's create it
|
|
||||||
author2sessions = {sessionIDs: {}};
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the entry for this session
|
|
||||||
author2sessions.sessionIDs[sessionID] = 1;
|
|
||||||
|
|
||||||
// save the new element back
|
|
||||||
await db.set(`author2sessions:${authorID}`, author2sessions);
|
|
||||||
|
|
||||||
return {sessionID};
|
return {sessionID};
|
||||||
};
|
};
|
||||||
|
@ -200,23 +173,16 @@ exports.deleteSession = async (sessionID) => {
|
||||||
const groupID = session.groupID;
|
const groupID = session.groupID;
|
||||||
const authorID = session.authorID;
|
const authorID = session.authorID;
|
||||||
|
|
||||||
// get the group2sessions and author2sessions entries
|
await Promise.all([
|
||||||
const group2sessions = await db.get(`group2sessions:${groupID}`);
|
// UeberDB's setSub() method atomically reads the record, updates the appropriate (sub)object
|
||||||
const author2sessions = await db.get(`author2sessions:${authorID}`);
|
// property, and writes the result. Setting a property to `undefined` deletes that property
|
||||||
|
// (JSON.stringify() ignores such properties).
|
||||||
|
db.setSub(`group2sessions:${groupID}`, ['sessionIDs', sessionID], undefined),
|
||||||
|
db.setSub(`author2sessions:${authorID}`, ['sessionIDs', sessionID], undefined),
|
||||||
|
]);
|
||||||
|
|
||||||
// remove session from group2sessions
|
// Delete the session record after updating group2sessions and author2sessions so that the state
|
||||||
if (group2sessions != null) { // Maybe the group was already deleted
|
// is consistent.
|
||||||
delete group2sessions.sessionIDs[sessionID];
|
|
||||||
await db.set(`group2sessions:${groupID}`, group2sessions);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove session from author2sessions
|
|
||||||
if (author2sessions != null) { // Maybe the author was already deleted
|
|
||||||
delete author2sessions.sessionIDs[sessionID];
|
|
||||||
await db.set(`author2sessions:${authorID}`, author2sessions);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove the session
|
|
||||||
await db.remove(`session:${sessionID}`);
|
await db.remove(`session:${sessionID}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue