6
6
"log"
7
7
"os"
8
8
"strings"
9
+ "sync"
9
10
10
11
"github.com/thanhhaudev/github-stats/pkg/clock"
11
12
"github.com/thanhhaudev/github-stats/pkg/github"
@@ -166,6 +167,8 @@ func (d *DataContainer) InitCommits(ctx context.Context) error {
166
167
errChan := make (chan error , repoCount )
167
168
commitChan := make (chan []github.Commit , repoCount )
168
169
seenOIDs := make (map [string ]bool )
170
+ var mu sync.Mutex
171
+
169
172
mask := func (input string ) string {
170
173
length := len (input )
171
174
if length <= 2 {
@@ -184,13 +187,17 @@ func (d *DataContainer) InitCommits(ctx context.Context) error {
184
187
if repoCount == 1 {
185
188
return "repository"
186
189
}
187
-
188
190
return "repositories"
189
191
}())
190
192
}
191
193
194
+ var wg sync.WaitGroup
195
+ semaphore := make (chan struct {}, 5 ) // Limit to 5 concurrent goroutines
196
+
192
197
for _ , repo := range d .Data .Repositories {
198
+ wg .Add (1 )
193
199
go func (repo github.Repository ) {
200
+ defer wg .Done ()
194
201
if fetchAllBranches {
195
202
if ! hiddenRepoInfo {
196
203
d .Logger .Println ("Fetching commits from all branches of repository:" , mask (repo .Name ))
@@ -202,17 +209,30 @@ func (d *DataContainer) InitCommits(ctx context.Context) error {
202
209
return
203
210
}
204
211
212
+ var branchWg sync.WaitGroup
205
213
var allCommits []github.Commit
206
214
for _ , branch := range branches {
207
- commits , err := d .ClientManager .GetCommits (ctx , repo .Owner .Login , repo .Name , d .Data .Viewer .ID , fmt .Sprintf ("refs/heads/%s" , branch .Name ), commitPerQuery )
208
- if err != nil {
209
- errChan <- err
210
- return
211
- }
212
-
213
- allCommits = append (allCommits , commits ... )
215
+ branchWg .Add (1 )
216
+ semaphore <- struct {}{} // Acquire a slot
217
+ go func (branch github.Branch ) {
218
+ defer branchWg .Done ()
219
+ defer func () { <- semaphore }() // Release the slot
220
+ commits , err := d .ClientManager .GetCommits (ctx , repo .Owner .Login , repo .Name , d .Data .Viewer .ID , fmt .Sprintf ("refs/heads/%s" , branch .Name ), commitPerQuery )
221
+ if err != nil {
222
+ errChan <- err
223
+ return
224
+ }
225
+
226
+ mu .Lock ()
227
+ allCommits = append (allCommits , commits ... )
228
+ if ! hiddenRepoInfo {
229
+ log .Printf ("Fetched %d commits from branch %s of repository %s" , len (commits ), mask (branch .Name ), mask (repo .Name ))
230
+ }
231
+ mu .Unlock ()
232
+ }(branch )
214
233
}
215
234
235
+ branchWg .Wait ()
216
236
commitChan <- allCommits
217
237
} else {
218
238
if ! hiddenRepoInfo {
@@ -238,14 +258,18 @@ func (d *DataContainer) InitCommits(ctx context.Context) error {
238
258
}(repo )
239
259
}
240
260
241
- for i := 0 ; i < len (d .Data .Repositories ); i ++ {
261
+ go func () {
262
+ wg .Wait ()
263
+ close (commitChan )
264
+ close (errChan )
265
+ }()
266
+
267
+ for i := 0 ; i < repoCount ; i ++ {
242
268
if err := <- errChan ; err != nil {
243
269
return err
244
270
}
245
271
}
246
272
247
- close (commitChan ) // Close the channel to signal that all commits have been fetched
248
-
249
273
// Deduplicate commits
250
274
for commits := range commitChan {
251
275
for _ , commit := range commits {
@@ -258,7 +282,6 @@ func (d *DataContainer) InitCommits(ctx context.Context) error {
258
282
}
259
283
260
284
d .Logger .Println ("Fetched commits successfully" )
261
-
262
285
return nil
263
286
}
264
287
0 commit comments