Skip to content

Commit be2316c

Browse files
feat: resolve plugins in parallel
1 parent df1cf3d commit be2316c

File tree

3 files changed

+51
-17
lines changed

3 files changed

+51
-17
lines changed

cmd/plugin-registry/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ func run(log *logrus.Logger) error {
3737
// set global version
3838
cfg.Version = version
3939

40+
if cfg.DisableRequestCache {
41+
log.Warn("request cache disabled")
42+
}
43+
4044
log.Infof("connecting to database (stage=%s)...", cfg.Stage)
4145
// set global collection prefix
4246
plugin.CollectionPrefix = cfg.Stage

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ require (
1919
github.com/spf13/cobra v1.6.1
2020
github.com/stretchr/testify v1.8.1
2121
golang.org/x/oauth2 v0.4.0
22+
golang.org/x/sync v0.1.0
2223
)
2324

2425
require (
@@ -54,7 +55,6 @@ require (
5455
go.opencensus.io v0.24.0 // indirect
5556
golang.org/x/crypto v0.5.0 // indirect
5657
golang.org/x/net v0.5.0 // indirect
57-
golang.org/x/sync v0.1.0 // indirect
5858
golang.org/x/sys v0.4.0 // indirect
5959
golang.org/x/text v0.6.0 // indirect
6060
golang.org/x/time v0.3.0 // indirect

internal/server/handler_batch.go

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,18 @@ import (
1616
"github.com/go-semantic-release/plugin-registry/internal/batch"
1717
"github.com/go-semantic-release/plugin-registry/internal/config"
1818
"github.com/go-semantic-release/plugin-registry/pkg/registry"
19+
"golang.org/x/sync/errgroup"
1920
)
2021

22+
type pluginBatchError struct {
23+
PluginName string
24+
Err error
25+
}
26+
27+
func (e *pluginBatchError) Error() string {
28+
return fmt.Sprintf("plugin batch error (%s): %s", e.PluginName, e.Err.Error())
29+
}
30+
2131
func validateAndCreatePluginResponses(batchRequest *registry.BatchRequest) (registry.BatchResponsePlugins, error) {
2232
err := batchRequest.Validate()
2333
if err != nil {
@@ -82,23 +92,42 @@ func (s *Server) batchGetPlugins(w http.ResponseWriter, r *http.Request) {
8292
return
8393
}
8494

95+
// TODO: this could be done in parallel
96+
errGroup, groupCtx := errgroup.WithContext(r.Context())
97+
errGroup.SetLimit(5)
8598
for _, pluginResponse := range batchResponse.Plugins {
86-
p := config.Plugins.Find(pluginResponse.FullName)
87-
foundRelease, rErr := p.GetReleaseWithVersionConstraint(r.Context(), s.db, pluginResponse.VersionConstraint)
88-
if rErr != nil {
89-
s.writeJSONError(w, r, http.StatusBadRequest, rErr, fmt.Sprintf("could not resolve plugin %s", pluginResponse.FullName))
90-
return
91-
}
92-
foundAsset := foundRelease.Assets[batchResponse.GetOSArch()]
93-
if foundAsset == nil {
94-
s.writeJSONError(w, r, http.StatusBadRequest, fmt.Errorf("could not find %s asset for plugin %s", batchResponse.GetOSArch(), pluginResponse.FullName))
95-
return
96-
}
97-
98-
pluginResponse.Version = foundRelease.Version
99-
pluginResponse.FileName = foundAsset.FileName
100-
pluginResponse.URL = foundAsset.URL
101-
pluginResponse.Checksum = foundAsset.Checksum
99+
pluginResponse := pluginResponse
100+
errGroup.Go(func() error {
101+
p := config.Plugins.Find(pluginResponse.FullName)
102+
foundRelease, rErr := p.GetReleaseWithVersionConstraint(groupCtx, s.db, pluginResponse.VersionConstraint)
103+
if rErr != nil {
104+
return &pluginBatchError{
105+
PluginName: pluginResponse.FullName,
106+
Err: rErr,
107+
}
108+
}
109+
foundAsset := foundRelease.Assets[batchResponse.GetOSArch()]
110+
if foundAsset == nil {
111+
return &pluginBatchError{
112+
PluginName: pluginResponse.FullName,
113+
Err: fmt.Errorf("could not find %s asset", batchResponse.GetOSArch()),
114+
}
115+
}
116+
pluginResponse.Version = foundRelease.Version
117+
pluginResponse.FileName = foundAsset.FileName
118+
pluginResponse.URL = foundAsset.URL
119+
pluginResponse.Checksum = foundAsset.Checksum
120+
return nil
121+
})
122+
}
123+
err = errGroup.Wait()
124+
pbErr := &pluginBatchError{}
125+
if errors.As(err, &pbErr) {
126+
s.writeJSONError(w, r, http.StatusBadRequest, pbErr, fmt.Sprintf("could not resolve plugin %s", pbErr.PluginName))
127+
return
128+
} else if err != nil {
129+
s.writeJSONError(w, r, http.StatusBadRequest, err, "could not resolve plugins")
130+
return
102131
}
103132

104133
// calculate the hash of the response, this now includes the plugin versions
@@ -108,6 +137,7 @@ func (s *Server) batchGetPlugins(w http.ResponseWriter, r *http.Request) {
108137
batchResponse.DownloadURL = s.config.GetPublicPluginCacheDownloadURL(archiveKey)
109138

110139
// allow only one batch archive process at a time
140+
// TODO: this might be to conservative, we could allow multiple archives to be created at the same time
111141
s.batchMu.Lock()
112142
defer s.batchMu.Unlock()
113143

0 commit comments

Comments
 (0)