| OLD | NEW |
| 1 package search | 1 package search |
| 2 | 2 |
| 3 import ( | 3 import ( |
| 4 "fmt" | 4 "fmt" |
| 5 "sort" |
| 5 "strconv" | 6 "strconv" |
| 6 "strings" | 7 "strings" |
| 7 "sync" | 8 "sync" |
| 8 | 9 |
| 9 "go.skia.org/infra/golden/go/storage" | 10 "go.skia.org/infra/golden/go/storage" |
| 10 "go.skia.org/infra/golden/go/trybot" | 11 "go.skia.org/infra/golden/go/trybot" |
| 11 ) | 12 ) |
| 12 | 13 |
| 13 // TrybotIssue is the output structure for a Rietveld issue that has | 14 // TrybotIssue is the output structure for a Rietveld issue that has |
| 14 // trybot runs assoicated with it. | 15 // trybot runs assoicated with it. |
| 15 type TrybotIssue struct { | 16 type TrybotIssue struct { |
| 16 » ID int64 `json:"id"` | 17 » ID int64 `json:"id"` |
| 17 » Subject string `json:"subject"` | 18 » Subject string `json:"subject"` |
| 18 » Owner string `json:"owner"` | 19 » Owner string `json:"owner"` |
| 19 » Updated int64 `json:"updated"` | 20 » Updated int64 `json:"updated"` |
| 20 » URL string `json:"url"` | 21 » URL string `json:"url"` |
| 22 » CurrentPatchset int `json:"currentPatchset"` |
| 21 } | 23 } |
| 22 | 24 |
| 23 // ListTrybotIssues returns the most recently updated trybot issues in reverse | 25 // ListTrybotIssues returns the most recently updated trybot issues in reverse |
| 24 // chronological order. offset and size determine the page and size of the | 26 // chronological order. offset and size determine the page and size of the |
| 25 // returned list. The second return value is the total number of items | 27 // returned list. The second return value is the total number of items |
| 26 // available to facilitate pagination. | 28 // available to facilitate pagination. |
| 27 func ListTrybotIssues(storages *storage.Storage, offset, size int) ([]*TrybotIss
ue, int, error) { | 29 func ListTrybotIssues(storages *storage.Storage, offset, size int) ([]*TrybotIss
ue, int, error) { |
| 28 issueInfos, total, err := storages.TrybotResults.List(offset, size) | 30 issueInfos, total, err := storages.TrybotResults.List(offset, size) |
| 29 if err != nil { | 31 if err != nil { |
| 30 return nil, 0, err | 32 return nil, 0, err |
| 31 } | 33 } |
| 32 | 34 |
| 33 if len(issueInfos) == 0 { | 35 if len(issueInfos) == 0 { |
| 34 return []*TrybotIssue{}, 0, nil | 36 return []*TrybotIssue{}, 0, nil |
| 35 } | 37 } |
| 36 | 38 |
| 37 ch := make(chan error, len(issueInfos)) | 39 ch := make(chan error, len(issueInfos)) |
| 38 var wg sync.WaitGroup | 40 var wg sync.WaitGroup |
| 39 retMap := map[string]*TrybotIssue{} | 41 retMap := map[string]*TrybotIssue{} |
| 40 var mutex sync.Mutex | 42 var mutex sync.Mutex |
| 41 | 43 |
| 42 for _, issueInfo := range issueInfos { | 44 for _, issueInfo := range issueInfos { |
| 43 wg.Add(1) | 45 wg.Add(1) |
| 44 go func(issueInfo *trybot.IssueListItem) { | 46 go func(issueInfo *trybot.IssueListItem) { |
| 45 defer wg.Done() | 47 defer wg.Done() |
| 46 | 48 |
| 47 » » » intIssueId, err := strconv.Atoi(issueInfo.Issue) | 49 » » » intIssueId, err := strconv.ParseInt(issueInfo.Issue, 10,
64) |
| 48 if err != nil { | 50 if err != nil { |
| 49 ch <- fmt.Errorf("Unable to parse issue id %s. G
ot error: %s", issueInfo.Issue, err) | 51 ch <- fmt.Errorf("Unable to parse issue id %s. G
ot error: %s", issueInfo.Issue, err) |
| 50 return | 52 return |
| 51 } | 53 } |
| 52 result, err := storages.RietveldAPI.GetIssueProperties(i
nt64(intIssueId), false) | 54 result, err := storages.RietveldAPI.GetIssueProperties(i
nt64(intIssueId), false) |
| 53 if err != nil { | 55 if err != nil { |
| 54 ch <- fmt.Errorf("Error retrieving rietveld info
rmaton for issue: %s: %s", issueInfo.Issue, err) | 56 ch <- fmt.Errorf("Error retrieving rietveld info
rmaton for issue: %s: %s", issueInfo.Issue, err) |
| 55 return | 57 return |
| 56 } | 58 } |
| 57 | 59 |
| 60 // Retrieve the owner via the patchset via Rietveld. |
| 61 owner := result.Owner |
| 62 if len(result.Patchsets) > 0 { |
| 63 ps, err := storages.RietveldAPI.GetPatchset(intI
ssueId, result.Patchsets[0]) |
| 64 if err != nil { |
| 65 ch <- fmt.Errorf("Error retrieving patch
set %d for issue %s: %s", result.Patchsets[0], issueInfo.Issue, err) |
| 66 return |
| 67 } |
| 68 owner = ps.OwnerEmail |
| 69 } |
| 70 |
| 58 ret := &TrybotIssue{ | 71 ret := &TrybotIssue{ |
| 59 » » » » ID: result.Issue, | 72 » » » » ID: result.Issue, |
| 60 » » » » Owner: result.Owner, | 73 » » » » Owner: owner, |
| 61 » » » » Subject: result.Subject, | 74 » » » » Subject: result.Subject, |
| 62 » » » » Updated: result.Modified.Unix(), | 75 » » » » Updated: result.Modified.Unix(), |
| 63 » » » » URL: strings.TrimSuffix(storages.RietveldAPI
.Url(), "/") + fmt.Sprintf("/%d", result.Issue), | 76 » » » » URL: strings.TrimSuffix(storages.Rie
tveldAPI.Url(), "/") + fmt.Sprintf("/%d", result.Issue), |
| 77 » » » » CurrentPatchset: sort.Search(len(result.Patchset
s), func(i int) bool { return result.Patchsets[i] >= issueInfo.MaxPatchset }) +
1, |
| 64 } | 78 } |
| 65 | 79 |
| 66 mutex.Lock() | 80 mutex.Lock() |
| 67 retMap[issueInfo.Issue] = ret | 81 retMap[issueInfo.Issue] = ret |
| 68 mutex.Unlock() | 82 mutex.Unlock() |
| 69 | 83 |
| 70 }(issueInfo) | 84 }(issueInfo) |
| 71 } | 85 } |
| 72 wg.Wait() | 86 wg.Wait() |
| 73 close(ch) | 87 close(ch) |
| 74 | 88 |
| 75 for err := range ch { | 89 for err := range ch { |
| 76 return nil, 0, err | 90 return nil, 0, err |
| 77 } | 91 } |
| 78 | 92 |
| 79 ret := make([]*TrybotIssue, 0, len(retMap)) | 93 ret := make([]*TrybotIssue, 0, len(retMap)) |
| 80 for _, issueInfo := range issueInfos { | 94 for _, issueInfo := range issueInfos { |
| 81 ret = append(ret, retMap[issueInfo.Issue]) | 95 ret = append(ret, retMap[issueInfo.Issue]) |
| 82 } | 96 } |
| 83 | 97 |
| 84 return ret, total, nil | 98 return ret, total, nil |
| 85 } | 99 } |
| OLD | NEW |