@@ -27,7 +27,6 @@ import (
2727 "mime/multipart"
2828 "net/http"
2929 "net/textproto"
30- "sync"
3130
3231 "firebase.google.com/go/v4/internal"
3332)
@@ -165,53 +164,85 @@ func (c *fcmClient) sendEachInBatch(ctx context.Context, messages []*Message, dr
165164 return nil , fmt .Errorf ("messages must not contain more than %d elements" , maxMessages )
166165 }
167166
168- var responses []* SendResponse = make ([]* SendResponse , len (messages ))
169- var wg sync.WaitGroup
170-
171167 for idx , m := range messages {
172168 if err := validateMessage (m ); err != nil {
173169 return nil , fmt .Errorf ("invalid message at index %d: %v" , idx , err )
174170 }
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 )
197171 }
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+ }
200192
201193 successCount := 0
194+ failureCount := 0
202195 for _ , r := range responses {
203196 if r .Success {
204197 successCount ++
198+ } else {
199+ failureCount ++
205200 }
206201 }
207202
208203 return & BatchResponse {
209204 Responses : responses ,
210205 SuccessCount : successCount ,
211- FailureCount : len ( responses ) - successCount ,
206+ FailureCount : failureCount ,
212207 }, nil
213208}
214209
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+
215246// SendAll sends the messages in the given array via Firebase Cloud Messaging.
216247//
217248// The messages array may contain up to 500 messages. SendAll employs batching to send the entire
0 commit comments