Optimize VM listing logic with singleflight to deduplicate concurrent request

This commit is contained in:
Fedor Korotkov 2026-02-05 11:33:09 +01:00
parent c7f669d23c
commit f07ed68a84
2 changed files with 35 additions and 17 deletions

View File

@ -312,26 +312,40 @@ func (controller *Controller) listVMs(ctx *gin.Context) responder.Responder {
}
}
return controller.storeView(func(txn storepkg.Transaction) responder.Responder {
allVMs, err := txn.ListVMs()
allVMs, err, _ := controller.single.Do("list-vms", func() (interface{}, error) {
var vms []v1.VM
if err != nil {
return responder.Error(err)
}
viewErr := controller.store.View(func(txn storepkg.Transaction) (err error) {
vms, err = txn.ListVMs()
return
})
vms := make([]v1.VM, 0)
Outer:
for _, vm := range allVMs {
for _, filter := range filters {
if !vm.Match(filter) {
continue Outer
}
}
vms = append(vms, vm)
}
return responder.JSON(http.StatusOK, vms)
return vms, viewErr
})
if err != nil {
return responder.Error(err)
}
vmList, ok := allVMs.([]v1.VM)
if !ok {
controller.logger.Errorf("failed to cast list-vms result to []v1.VM: %T", allVMs)
return responder.Code(http.StatusInternalServerError)
}
vms := make([]v1.VM, 0, len(vmList))
Outer:
for _, vm := range vmList {
for _, filter := range filters {
if !vm.Match(filter) {
continue Outer
}
}
vms = append(vms, vm)
}
return responder.JSON(http.StatusOK, vms)
}
func (controller *Controller) deleteVM(ctx *gin.Context) responder.Responder {

View File

@ -29,6 +29,7 @@ import (
"golang.org/x/crypto/ssh"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"golang.org/x/sync/singleflight"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
)
@ -73,6 +74,8 @@ type Controller struct {
sshNoClientAuth bool
sshServer *sshserver.SSHServer
single singleflight.Group
rpc.UnimplementedControllerServer
}
@ -83,6 +86,7 @@ func New(opts ...Option) (*Controller, error) {
workerOfflineTimeout: 3 * time.Minute,
maxWorkersPerLicense: maxWorkersPerDefaultLicense,
pingInterval: 30 * time.Second,
single: singleflight.Group{},
}
// Apply options