Cache parsed go-import and go-source data to prevent more than one HTTP request per dependency.

This commit is contained in:
Stanislav Nikitin 2020-02-07 21:31:45 +05:00
parent f423fb9ac7
commit 208eab65e4
No known key found for this signature in database
GPG Key ID: 106900B32F8192EE
2 changed files with 41 additions and 0 deletions

View File

@ -11,6 +11,8 @@ import (
func Initialize() (parserinterface.Interface, string) { func Initialize() (parserinterface.Interface, string) {
log.Println("Initializing Golang projects parser") log.Println("Initializing Golang projects parser")
goDatas = make(map[string]*godata)
p := &golangParser{} p := &golangParser{}
return parserinterface.Interface(p), "golang" return parserinterface.Interface(p), "golang"
} }

View File

@ -8,6 +8,7 @@ import (
"log" "log"
"net/http" "net/http"
"strings" "strings"
"sync"
// local // local
"go.dev.pztrn.name/glp/configuration" "go.dev.pztrn.name/glp/configuration"
@ -15,6 +16,20 @@ import (
"go.dev.pztrn.name/glp/structs" "go.dev.pztrn.name/glp/structs"
) )
var (
goDatas map[string]*godata
goDatasMutex sync.Mutex
)
// This structure used for caching data about dependencies and prevent
// unneeded requests.
type godata struct {
SourceURLDirTemplate string
SourceURLFileTemplate string
VCSPath string
VCS string
}
// attrValue returns the attribute value for the case-insensitive key // attrValue returns the attribute value for the case-insensitive key
// `name', or the empty string if nothing is found. // `name', or the empty string if nothing is found.
func attrValue(attrs []xml.Attr, name string) string { func attrValue(attrs []xml.Attr, name string) string {
@ -28,6 +43,20 @@ func attrValue(attrs []xml.Attr, name string) string {
// Gets go-import and go-source data and fill it in dependency. // Gets go-import and go-source data and fill it in dependency.
func getGoData(dependency *structs.Dependency) { func getGoData(dependency *structs.Dependency) {
// Check if information about that dependency already cached.
// Use cached data if so.
goDatasMutex.Lock()
depInfo, cached := goDatas[dependency.Name+"@"+dependency.Version]
goDatasMutex.Unlock()
if cached {
dependency.VCS.SourceURLDirTemplate = depInfo.SourceURLDirTemplate
dependency.VCS.SourceURLFileTemplate = depInfo.SourceURLFileTemplate
dependency.VCS.VCS = depInfo.VCS
dependency.VCS.VCSPath = depInfo.VCSPath
return
}
// Dependencies are imported using URL which can be called with // Dependencies are imported using URL which can be called with
// "?go-get=1" parameter to obtain required VCS data. // "?go-get=1" parameter to obtain required VCS data.
req, _ := http.NewRequest("GET", "http://"+dependency.Name, nil) req, _ := http.NewRequest("GET", "http://"+dependency.Name, nil)
@ -101,4 +130,14 @@ func getGoData(dependency *structs.Dependency) {
if configuration.Cfg.Log.Debug { if configuration.Cfg.Log.Debug {
log.Printf("go-import and go-source data parsed: %+v\n", dependency.VCS) log.Printf("go-import and go-source data parsed: %+v\n", dependency.VCS)
} }
// Cache parsed data.
goDatasMutex.Lock()
goDatas[dependency.Name+"@"+dependency.Version] = &godata{
SourceURLDirTemplate: dependency.VCS.SourceURLDirTemplate,
SourceURLFileTemplate: dependency.VCS.SourceURLFileTemplate,
VCS: dependency.VCS.VCS,
VCSPath: dependency.VCS.VCSPath,
}
goDatasMutex.Unlock()
} }