Skip to content

Commit 191cf21

Browse files
authored
Merge pull request #40 from shanep/clone-add-channels
Update ListAllAcceptedAssignments to use channels
2 parents 2d9c71d + ef0a543 commit 191cf21

File tree

2 files changed

+72
-20
lines changed

2 files changed

+72
-20
lines changed

cmd/gh-classroom/shared/shared.go

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package shared
22

33
import (
44
"errors"
5+
"math"
6+
"sync"
57

68
"github.com/AlecAivazis/survey/v2"
79
"github.com/cli/go-gh/pkg/api"
@@ -109,30 +111,59 @@ func ListAcceptedAssignments(client api.RESTClient, assignmentID int, page int,
109111
return acceptedAssignmentList, nil
110112
}
111113

114+
type assignmentList struct {
115+
assignments []classroom.AcceptedAssignment
116+
Error error
117+
}
118+
112119
func ListAllAcceptedAssignments(client api.RESTClient, assignmentID int, perPage int) (classroom.AcceptedAssignmentList, error) {
113-
var page = 1
114-
response, err := classroom.GetAssignmentList(client, assignmentID, page, perPage)
120+
121+
//Calculate the number of go channels to create. We will assign 1 channel per page
122+
//so we don't put too much pressure on the API all at once
123+
assignment, err := classroom.GetAssignment(client, assignmentID)
115124
if err != nil {
116125
return classroom.AcceptedAssignmentList{}, err
117126
}
118-
119-
if len(response) == 0 {
120-
return classroom.AcceptedAssignmentList{}, nil
121-
}
122-
123-
//keep calling getAssignmentList until we get them all
124-
var nextList []classroom.AcceptedAssignment
125-
for hasNext := true; hasNext; {
126-
page += 1
127-
nextList, err = classroom.GetAssignmentList(client, assignmentID, page, perPage)
128-
if err != nil {
129-
return classroom.AcceptedAssignmentList{}, err
130-
}
131-
hasNext = len(nextList) > 0
132-
response = append(response, nextList...)
127+
numChannels := int(math.Ceil(float64(assignment.Accepted) / float64(perPage)))
128+
129+
ch := make(chan assignmentList)
130+
var wg sync.WaitGroup
131+
for page := 1; page <= numChannels; page++ {
132+
wg.Add(1)
133+
go func(pg int) {
134+
defer wg.Done()
135+
response, err := classroom.GetAssignmentList(client, assignmentID, pg, perPage)
136+
ch <- assignmentList{
137+
assignments: response,
138+
Error: err,
139+
}
140+
}(page)
141+
}
142+
143+
var mu sync.Mutex
144+
assignments := make([]classroom.AcceptedAssignment, 0, assignment.Accepted)
145+
var hadErr error = nil
146+
for page := 1; page <= numChannels; page++ {
147+
wg.Add(1)
148+
go func() {
149+
defer wg.Done()
150+
result := <-ch
151+
if result.Error != nil {
152+
hadErr = result.Error
153+
} else {
154+
mu.Lock()
155+
assignments = append(assignments, result.assignments...)
156+
mu.Unlock()
157+
}
158+
}()
159+
}
160+
161+
wg.Wait()
162+
close(ch)
163+
164+
if hadErr != nil {
165+
return classroom.AcceptedAssignmentList{}, err
133166
}
134167

135-
acceptedAssignmentList := classroom.NewAcceptedAssignmentList(response)
136-
137-
return acceptedAssignmentList, nil
168+
return classroom.NewAcceptedAssignmentList(assignments), nil
138169
}

cmd/gh-classroom/shared/shared_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,30 @@ func TestListAcceptedAssignments(t *testing.T) {
9696
}
9797

9898
func TestListAllAcceptedAssignments(t *testing.T) {
99+
//This test should be OK however be aware that gock is not fully thread safe
100+
//https://github.com/h2non/gock#race-conditions
101+
//So if this test has intermittent failures this is the first place to look :)
99102
t.Setenv("GITHUB_TOKEN", "999")
100103
defer gock.Off()
101104

105+
gock.New("https://api.github.com").
106+
Get("/assignments/1").
107+
Reply(200).
108+
JSON(`{"id": 1,
109+
"title": "Assignment 1",
110+
"description": "This is the first assignment",
111+
"due_date": "2018-01-01",
112+
"accepted": 2,
113+
"classroom": {
114+
"id": 1,
115+
"name": "Classroom Name"
116+
},
117+
"starter_code_repository": {
118+
"id": 1,
119+
"full_name": "org1/starter-code-repo"
120+
}
121+
}`)
122+
102123
gock.New("https://api.github.com").
103124
Get("/assignments/1/accepted_assignments").
104125
Reply(200).

0 commit comments

Comments
 (0)