فهرست منبع

[web] fetch project members in a single db query (#25662)

* [web] fetch project members in a single db query

GitOrigin-RevId: ca749327d4783c67a3ad81f611cd7d3e7fa84028
Jakob Ackermann 1 سال پیش
والد
کامیت
e3e8d944b2

+ 28 - 30
services/web/app/src/Features/Collaborators/CollaboratorsGetter.js

@@ -385,34 +385,32 @@ function _getMemberIdsWithPrivilegeLevelsFromFields(
 }
 
 async function _loadMembers(members) {
-  const limit = pLimit(3)
-  const results = await Promise.all(
-    members.map(member =>
-      limit(async () => {
-        const user = await UserGetter.promises.getUser(member.id, {
-          _id: 1,
-          email: 1,
-          features: 1,
-          first_name: 1,
-          last_name: 1,
-          signUpDate: 1,
-        })
-        if (user != null) {
-          const record = {
-            user,
-            privilegeLevel: member.privilegeLevel,
-          }
-          if (member.pendingEditor) {
-            record.pendingEditor = true
-          } else if (member.pendingReviewer) {
-            record.pendingReviewer = true
-          }
-          return record
-        } else {
-          return null
-        }
-      })
-    )
-  )
-  return results.filter(r => r != null)
+  const userIds = Array.from(new Set(members.map(m => m.id)))
+  const users = new Map()
+  for (const user of await UserGetter.promises.getUsers(userIds, {
+    _id: 1,
+    email: 1,
+    features: 1,
+    first_name: 1,
+    last_name: 1,
+    signUpDate: 1,
+  })) {
+    users.set(user._id.toString(), user)
+  }
+  return members
+    .map(member => {
+      const user = users.get(member.id)
+      if (!user) return null
+      const record = {
+        user,
+        privilegeLevel: member.privilegeLevel,
+      }
+      if (member.pendingEditor) {
+        record.pendingEditor = true
+      } else if (member.pendingReviewer) {
+        record.pendingReviewer = true
+      }
+      return record
+    })
+    .filter(r => r != null)
 }

+ 13 - 24
services/web/test/unit/src/Collaborators/CollaboratorsGetterTests.js

@@ -52,6 +52,7 @@ describe('CollaboratorsGetter', function () {
     this.UserGetter = {
       promises: {
         getUser: sinon.stub().resolves(null),
+        getUsers: sinon.stub().resolves([]),
       },
     }
     this.ProjectMock = sinon.mock(Project)
@@ -205,21 +206,13 @@ describe('CollaboratorsGetter', function () {
 
   describe('getInvitedMembersWithPrivilegeLevels', function () {
     beforeEach(function () {
-      this.UserGetter.promises.getUser
-        .withArgs(this.readOnlyRef1.toString())
-        .resolves({ _id: this.readOnlyRef1 })
-      this.UserGetter.promises.getUser
-        .withArgs(this.readOnlyTokenRef.toString())
-        .resolves({ _id: this.readOnlyTokenRef })
-      this.UserGetter.promises.getUser
-        .withArgs(this.readWriteRef2.toString())
-        .resolves({ _id: this.readWriteRef2 })
-      this.UserGetter.promises.getUser
-        .withArgs(this.readWriteTokenRef.toString())
-        .resolves({ _id: this.readWriteTokenRef })
-      this.UserGetter.promises.getUser
-        .withArgs(this.reviewer1Ref.toString())
-        .resolves({ _id: this.reviewer1Ref })
+      this.UserGetter.promises.getUsers.resolves([
+        { _id: this.readOnlyRef1 },
+        { _id: this.readOnlyTokenRef },
+        { _id: this.readWriteRef2 },
+        { _id: this.readWriteTokenRef },
+        { _id: this.reviewer1Ref },
+      ])
     })
 
     it('should return an array of invited members with their privilege levels', async function () {
@@ -416,15 +409,11 @@ describe('CollaboratorsGetter', function () {
           { _id: this.reviewUser._id, email: this.reviewUser.email },
         ],
       }
-      this.UserGetter.promises.getUser
-        .withArgs(this.owningUser._id.toString())
-        .resolves(this.owningUser)
-      this.UserGetter.promises.getUser
-        .withArgs(this.readWriteUser._id.toString())
-        .resolves(this.readWriteUser)
-      this.UserGetter.promises.getUser
-        .withArgs(this.reviewUser._id.toString())
-        .resolves(this.reviewUser)
+      this.UserGetter.promises.getUsers.resolves([
+        this.owningUser,
+        this.readWriteUser,
+        this.reviewUser,
+      ])
       this.ProjectEditorHandler.buildOwnerAndMembersViews.returns(this.views)
       this.result =
         await this.CollaboratorsGetter.promises.getAllInvitedMembers(