@@ -10,7 +10,9 @@ import (
10
10
"context"
11
11
"sync"
12
12
13
+ "github.com/gammazero/workerpool"
13
14
"github.com/jinzhu/copier"
15
+ "github.com/panjf2000/ants/v2"
14
16
"golang.org/x/sync/errgroup"
15
17
"google.golang.org/protobuf/types/known/timestamppb"
16
18
@@ -68,6 +70,99 @@ func (b *userBiz) List(ctx context.Context, rq *v1.ListUserRequest) (*v1.ListUse
68
70
return & v1.ListUserResponse {TotalCount : count , Users : users }, nil
69
71
}
70
72
73
+ // ListWithWorkerPool retrieves a list of all users from the database use workerpool package.
74
+ // Concurrency limits can effectively protect downstream services and control the resource
75
+ // consumption of components.
76
+ func (b * userBiz ) ListWithWorkerPool (ctx context.Context , rq * v1.ListUserRequest ) (* v1.ListUserResponse , error ) {
77
+ count , list , err := b .ds .Users ().List (ctx , meta .WithOffset (rq .Offset ), meta .WithLimit (rq .Limit ))
78
+ if err != nil {
79
+ log .C (ctx ).Errorw (err , "Failed to list users from storage" )
80
+ return nil , err
81
+ }
82
+
83
+ var m sync.Map
84
+ wp := workerpool .New (100 )
85
+
86
+ // Use goroutine to improve interface performance
87
+ for _ , user := range list {
88
+ wp .Submit (func () {
89
+ count , _ , err := b .ds .Secrets ().List (ctx , user .UserID )
90
+ if err != nil {
91
+ log .C (ctx ).Errorw (err , "Failed to list secrets" )
92
+ return
93
+ }
94
+
95
+ u := ModelToReply (user )
96
+ u .Secrets = count
97
+ m .Store (user .ID , u )
98
+
99
+ return
100
+ })
101
+ }
102
+
103
+ wp .StopWait ()
104
+
105
+ // The following code block is used to maintain the consistency of query order.
106
+ users := make ([]* v1.UserReply , 0 , len (list ))
107
+ for _ , item := range list {
108
+ user , _ := m .Load (item .ID )
109
+ users = append (users , user .(* v1.UserReply ))
110
+ }
111
+
112
+ log .C (ctx ).Debugw ("Get users from backend storage" , "count" , len (users ))
113
+
114
+ return & v1.ListUserResponse {TotalCount : count , Users : users }, nil
115
+ }
116
+
117
+ // ListWithAnts retrieves a list of all users from the database use ants package.
118
+ // Concurrency limits can effectively protect downstream services and control the
119
+ // resource consumption of components.
120
+ func (b * userBiz ) ListWithAnts (ctx context.Context , rq * v1.ListUserRequest ) (* v1.ListUserResponse , error ) {
121
+ count , list , err := b .ds .Users ().List (ctx , meta .WithOffset (rq .Offset ), meta .WithLimit (rq .Limit ))
122
+ if err != nil {
123
+ log .C (ctx ).Errorw (err , "Failed to list users from storage" )
124
+ return nil , err
125
+ }
126
+
127
+ var m sync.Map
128
+ var wg sync.WaitGroup
129
+ pool , _ := ants .NewPool (100 )
130
+ defer pool .Release ()
131
+
132
+ // Use goroutine to improve interface performance
133
+ for _ , user := range list {
134
+ wg .Add (1 )
135
+ _ = pool .Submit (func () {
136
+ defer wg .Done ()
137
+
138
+ count , _ , err := b .ds .Secrets ().List (ctx , user .UserID )
139
+ if err != nil {
140
+ log .C (ctx ).Errorw (err , "Failed to list secrets" )
141
+ return
142
+ }
143
+
144
+ u := ModelToReply (user )
145
+ u .Secrets = count
146
+ m .Store (user .ID , u )
147
+
148
+ return
149
+ })
150
+ }
151
+
152
+ wg .Wait ()
153
+
154
+ // The following code block is used to maintain the consistency of query order.
155
+ users := make ([]* v1.UserReply , 0 , len (list ))
156
+ for _ , item := range list {
157
+ user , _ := m .Load (item .ID )
158
+ users = append (users , user .(* v1.UserReply ))
159
+ }
160
+
161
+ log .C (ctx ).Debugw ("Get users from backend storage" , "count" , len (users ))
162
+
163
+ return & v1.ListUserResponse {TotalCount : count , Users : users }, nil
164
+ }
165
+
71
166
// ListWithBadPerformance is a poor performance implementation of List.
72
167
func (b * userBiz ) ListWithBadPerformance (ctx context.Context , rq * v1.ListUserRequest ) (* v1.ListUserResponse , error ) {
73
168
count , list , err := b .ds .Users ().List (ctx , meta .WithOffset (rq .Offset ), meta .WithLimit (rq .Limit ))
0 commit comments