diff --git a/src/controllers/accounts/groups.js b/src/controllers/accounts/groups.js index fbe9a39407..8abcd25894 100644 --- a/src/controllers/accounts/groups.js +++ b/src/controllers/accounts/groups.js @@ -15,9 +15,8 @@ groupsController.get = async function (req, res) { const payload = res.locals.userData; - let groupsData = await groups.getUserGroups([res.locals.uid]); - groupsData = groupsData[0]; - const groupNames = groupsData.filter(Boolean).map(group => group.name); + const groupsData = payload.groups.filter(Boolean); + const groupNames = groupsData.map(group => group.name); const members = await groups.getMemberUsers(groupNames, 0, 3); groupsData.forEach((group, index) => { group.members = members[index]; diff --git a/src/groups/create.js b/src/groups/create.js index aea069c829..be21f1d0a2 100644 --- a/src/groups/create.js +++ b/src/groups/create.js @@ -4,6 +4,7 @@ const meta = require('../meta'); const plugins = require('../plugins'); const slugify = require('../slugify'); const db = require('../database'); +const cache = require('../cache'); module.exports = function (Groups) { Groups.create = async function (data) { @@ -47,7 +48,7 @@ module.exports = function (Groups) { await db.sortedSetAdd('groups:createtime', groupData.createtime, groupData.name); await db.setObject(`group:${groupData.name}`, groupData); - + cache.del(`zset:groups:createtime`); if (data.hasOwnProperty('ownerUid')) { await db.setAdd(`group:${groupData.name}:owners`, data.ownerUid); await db.sortedSetAdd(`group:${groupData.name}:members`, timestamp, data.ownerUid); diff --git a/src/groups/delete.js b/src/groups/delete.js index 449640c190..129e8dd9c2 100644 --- a/src/groups/delete.js +++ b/src/groups/delete.js @@ -4,6 +4,7 @@ const plugins = require('../plugins'); const slugify = require('../slugify'); const db = require('../database'); const batch = require('../batch'); +const cache = require('../cache'); module.exports = function (Groups) { Groups.destroy = async function (groupNames) { @@ -44,6 +45,7 @@ module.exports = function (Groups) { removeGroupsFromPrivilegeGroups(groupNames), ]); Groups.cache.reset(); + cache.del(`zset:groups:createtime`); plugins.hooks.fire('action:groups.destroy', { groups: groupsData }); }; diff --git a/src/groups/index.js b/src/groups/index.js index b71145304a..e4f24e5335 100644 --- a/src/groups/index.js +++ b/src/groups/index.js @@ -5,6 +5,7 @@ const db = require('../database'); const plugins = require('../plugins'); const privileges = require('../privileges'); const slugify = require('../slugify'); +const cache = require('../cache'); const Groups = module.exports; @@ -99,8 +100,10 @@ Groups.getNonPrivilegeGroups = async function (set, start, stop, flags) { ephemeral: true, }; } - - let groupNames = await db.getSortedSetRevRange(set, start, stop); + const useCache = set === 'groups:createtime' && parseInt(start, 10) === 0 && parseInt(stop, 10) === -1; + let groupNames = useCache ? + await Groups.getAllGroupNames('groups:createtime') : + await db.getSortedSetRevRange(set, start, stop); groupNames = groupNames.filter(groupName => !Groups.isPrivilegeGroup(groupName)); if (flags.ephemeral) { groupNames = groupNames.concat(Groups.ephemeralGroups); @@ -110,6 +113,17 @@ Groups.getNonPrivilegeGroups = async function (set, start, stop, flags) { return groupsData.filter(Boolean); }; +Groups.getAllGroupNames = async function (set) { + const cacheKey = `zset:${set}`; + let names = cache.get(cacheKey); + if (names !== undefined) { + return [...names]; + } + names = await db.getSortedSetRevRange(set, 0, -1); + cache.set(names); + return [...names]; +}; + Groups.getGroups = async function (set, start, stop) { return await db.getSortedSetRevRange(set, start, stop); }; diff --git a/src/groups/leave.js b/src/groups/leave.js index f9af8a34ff..ca591a5957 100644 --- a/src/groups/leave.js +++ b/src/groups/leave.js @@ -105,7 +105,7 @@ module.exports = function (Groups) { } Groups.leaveAllGroups = async function (uid) { - const groups = await db.getSortedSetRange('groups:createtime', 0, -1); + const groups = await Groups.getAllGroupNames('groups:createtime'); await Promise.all([ Groups.leave(groups, uid), Groups.rejectMembership( diff --git a/src/privileges/helpers.js b/src/privileges/helpers.js index 08fc60e320..6ba57cdf66 100644 --- a/src/privileges/helpers.js +++ b/src/privileges/helpers.js @@ -158,7 +158,7 @@ helpers.getUserPrivileges = async function (cid, userPrivileges) { helpers.getGroupPrivileges = async function (cid, groupPrivileges) { const [memberSets, allGroupNames] = await Promise.all([ groups.getMembersOfGroups(groupPrivileges.map(privilege => `cid:${cid}:privileges:${privilege}`)), - groups.getGroups('groups:createtime', 0, -1), + groups.getAllGroupNames('groups:createtime'), ]); const uniqueGroups = _.uniq(_.flatten(memberSets));