Query godoc.org concurrently and timeout.

This commit is contained in:
Gustavo Niemeyer 2014-04-08 10:17:48 -03:00
parent 828a3107e2
commit 538a704495

78
page.go
View File

@ -11,6 +11,8 @@ import (
"os" "os"
"regexp" "regexp"
"sort" "sort"
"sync"
"time"
) )
const packageTemplateString = `<!DOCTYPE html> const packageTemplateString = `<!DOCTYPE html>
@ -240,36 +242,66 @@ func renderPackagePage(resp http.ResponseWriter, req *http.Request, repo *Repo)
} }
sort.Sort(sort.Reverse(data.LatestVersions)) sort.Sort(sort.Reverse(data.LatestVersions))
godocResp, err := http.Get("http://godoc.org/" + repo.GopkgPath()) var dataMutex sync.Mutex
if err == nil { wantResps := 2
godocRespBytes, err := ioutil.ReadAll(godocResp.Body) gotResp := make(chan bool, wantResps)
godocResp.Body.Close()
if err == nil {
matches := regexpPackageName.FindSubmatch(godocRespBytes)
if len(matches) == 2 {
data.PackageName = string(matches[1])
}
}
}
// retrieve synopsis go func() {
searchResp, err := http.Get("http://api.godoc.org/search?q=" + url.QueryEscape(repo.GopkgPath())) // Retrieve package name from godoc.org. This should be on a proper API.
if err == nil { godocResp, err := http.Get("http://godoc.org/" + repo.GopkgPath())
searchResults := &SearchResults{}
err = json.NewDecoder(searchResp.Body).Decode(&searchResults)
searchResp.Body.Close()
if err == nil { if err == nil {
gopkgPath := repo.GopkgPath() godocRespBytes, err := ioutil.ReadAll(godocResp.Body)
for _, result := range searchResults.Results { godocResp.Body.Close()
if result.Path == gopkgPath { if err == nil {
data.Synopsis = result.Synopsis matches := regexpPackageName.FindSubmatch(godocRespBytes)
break if matches != nil {
dataMutex.Lock()
data.PackageName = string(matches[1])
dataMutex.Unlock()
} }
} }
} }
gotResp <- true
}()
go func() {
// Retrieve synopsis from godoc.org. This should be on a package path API
// rather than a search.
searchResp, err := http.Get("http://api.godoc.org/search?q=" + url.QueryEscape(repo.GopkgPath()))
if err == nil {
searchResults := &SearchResults{}
err = json.NewDecoder(searchResp.Body).Decode(&searchResults)
searchResp.Body.Close()
if err == nil {
gopkgPath := repo.GopkgPath()
for _, result := range searchResults.Results {
if result.Path == gopkgPath {
dataMutex.Lock()
data.Synopsis = result.Synopsis
dataMutex.Unlock()
break
}
}
}
}
gotResp <- true
}()
r := 0
for r < wantResps {
select {
case <-gotResp:
r++
case <-time.After(3 * time.Second):
r = wantResps
}
} }
err = packageTemplate.Execute(resp, data) dataMutex.Lock()
defer dataMutex.Unlock()
err := packageTemplate.Execute(resp, data)
if err != nil { if err != nil {
log.Printf("error executing package page template: %v", err) log.Printf("error executing package page template: %v", err)
} }