@@ -27,7 +27,6 @@ import (
27
27
"mime/multipart"
28
28
"net/http"
29
29
"net/textproto"
30
- "sync"
31
30
32
31
"firebase.google.com/go/v4/internal"
33
32
)
@@ -165,53 +164,85 @@ func (c *fcmClient) sendEachInBatch(ctx context.Context, messages []*Message, dr
165
164
return nil , fmt .Errorf ("messages must not contain more than %d elements" , maxMessages )
166
165
}
167
166
168
- var responses []* SendResponse = make ([]* SendResponse , len (messages ))
169
- var wg sync.WaitGroup
170
-
171
167
for idx , m := range messages {
172
168
if err := validateMessage (m ); err != nil {
173
169
return nil , fmt .Errorf ("invalid message at index %d: %v" , idx , err )
174
170
}
175
- wg .Add (1 )
176
- go func (idx int , m * Message , dryRun bool , responses []* SendResponse ) {
177
- defer wg .Done ()
178
- var resp string
179
- var err error
180
- if dryRun {
181
- resp , err = c .SendDryRun (ctx , m )
182
- } else {
183
- resp , err = c .Send (ctx , m )
184
- }
185
- if err == nil {
186
- responses [idx ] = & SendResponse {
187
- Success : true ,
188
- MessageID : resp ,
189
- }
190
- } else {
191
- responses [idx ] = & SendResponse {
192
- Success : false ,
193
- Error : err ,
194
- }
195
- }
196
- }(idx , m , dryRun , responses )
197
171
}
198
- // Wait for all SendDryRun/Send calls to finish
199
- wg .Wait ()
172
+
173
+ const numWorkers = 50
174
+ jobs := make (chan job , len (messages ))
175
+ results := make (chan result , len (messages ))
176
+
177
+ responses := make ([]* SendResponse , len (messages ))
178
+
179
+ for w := 0 ; w < numWorkers ; w ++ {
180
+ go worker (ctx , c , dryRun , jobs , results )
181
+ }
182
+
183
+ for idx , m := range messages {
184
+ jobs <- job {message : m , index : idx }
185
+ }
186
+ close (jobs )
187
+
188
+ for i := 0 ; i < len (messages ); i ++ {
189
+ res := <- results
190
+ responses [res .index ] = res .response
191
+ }
200
192
201
193
successCount := 0
194
+ failureCount := 0
202
195
for _ , r := range responses {
203
196
if r .Success {
204
197
successCount ++
198
+ } else {
199
+ failureCount ++
205
200
}
206
201
}
207
202
208
203
return & BatchResponse {
209
204
Responses : responses ,
210
205
SuccessCount : successCount ,
211
- FailureCount : len ( responses ) - successCount ,
206
+ FailureCount : failureCount ,
212
207
}, nil
213
208
}
214
209
210
+ type job struct {
211
+ message * Message
212
+ index int
213
+ }
214
+
215
+ type result struct {
216
+ response * SendResponse
217
+ index int
218
+ }
219
+
220
+ func worker (ctx context.Context , c * fcmClient , dryRun bool , jobs <- chan job , results chan <- result ) {
221
+ for j := range jobs {
222
+ var respMsg string
223
+ var err error
224
+ if dryRun {
225
+ respMsg , err = c .SendDryRun (ctx , j .message )
226
+ } else {
227
+ respMsg , err = c .Send (ctx , j .message )
228
+ }
229
+
230
+ var sr * SendResponse
231
+ if err == nil {
232
+ sr = & SendResponse {
233
+ Success : true ,
234
+ MessageID : respMsg ,
235
+ }
236
+ } else {
237
+ sr = & SendResponse {
238
+ Success : false ,
239
+ Error : err ,
240
+ }
241
+ }
242
+ results <- result {response : sr , index : j .index }
243
+ }
244
+ }
245
+
215
246
// SendAll sends the messages in the given array via Firebase Cloud Messaging.
216
247
//
217
248
// The messages array may contain up to 500 messages. SendAll employs batching to send the entire
0 commit comments