Refactor listing VMs (#399)

* Removed unnesesary ListOptions

* Refactor genericList to accept string prefixes instead of byte slices

* Optimize VM listing logic with singleflight to deduplicate concurrent request

* Refactor VM listing logic: rename variables for clarity and update error messages

* fix: address PR review feedback

- use singleflight DoChan with context cancellation for list VMs

🤖 Generated with [Codex](https://chatgpt.com/codex)

Co-Authored-By: Codex <codex@openai.com>

---------

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Fedor Korotkov
2026-02-05 18:51:45 +01:00
committed by GitHub
co-authored by Codex
parent 230a83c740
commit be869f10d4
8 changed files with 55 additions and 56 deletions
@@ -3,8 +3,6 @@ package badger
import (
"encoding/json"
storepkg "github.com/cirruslabs/orchard/internal/controller/store"
v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
"github.com/dgraph-io/badger/v3"
)
@@ -53,30 +51,21 @@ func genericGet[T any, PT interface {
func genericList[T any, PT interface {
SetVersion(uint64)
Match(v1.Filter) bool
*T
}](txn *Transaction, prefix []byte, opts ...storepkg.ListOption) (_ []T, err error) {
}](txn *Transaction, prefix string) (_ []T, err error) {
defer func() {
err = mapErr(err)
}()
// Apply options
listInput := &storepkg.ListInput{}
for _, opt := range opts {
opt(listInput)
}
// Declare an empty, non-nil slice to
// return [] when no objects are found
result := []T{}
it := txn.badgerTxn.NewIterator(badger.IteratorOptions{
Prefix: prefix,
Prefix: []byte(prefix),
})
defer it.Close()
Outer:
for it.Rewind(); it.Valid(); it.Next() {
item := it.Item()
@@ -91,12 +80,6 @@ Outer:
return nil, err
}
for _, filter := range listInput.Filters {
if !PT(&obj).Match(filter) {
continue Outer
}
}
PT(&obj).SetVersion(item.Version())
result = append(result, obj)
@@ -25,5 +25,5 @@ func (txn *Transaction) DeleteServiceAccount(name string) error {
}
func (txn *Transaction) ListServiceAccounts() ([]v1.ServiceAccount, error) {
return genericList[v1.ServiceAccount](txn, []byte(SpaceServiceAccounts))
return genericList[v1.ServiceAccount](txn, SpaceServiceAccounts)
}
@@ -4,7 +4,6 @@ package badger
import (
"path"
storepkg "github.com/cirruslabs/orchard/internal/controller/store"
"github.com/cirruslabs/orchard/pkg/resource/v1"
)
@@ -26,6 +25,6 @@ func (txn *Transaction) DeleteVM(name string) error {
return genericDelete(txn, VMKey(name))
}
func (txn *Transaction) ListVMs(opts ...storepkg.ListOption) ([]v1.VM, error) {
return genericList[v1.VM](txn, []byte(SpaceVMs), opts...)
func (txn *Transaction) ListVMs() ([]v1.VM, error) {
return genericList[v1.VM](txn, SpaceVMs)
}
@@ -26,5 +26,5 @@ func (txn *Transaction) DeleteWorker(name string) error {
}
func (txn *Transaction) ListWorkers() ([]v1.Worker, error) {
return genericList[v1.Worker](txn, []byte(SpaceWorkers))
return genericList[v1.Worker](txn, SpaceWorkers)
}
-15
View File
@@ -1,15 +0,0 @@
package store
import v1 "github.com/cirruslabs/orchard/pkg/resource/v1"
type ListInput struct {
Filters []v1.Filter
}
type ListOption func(listInput *ListInput)
func WithListFilters(filters ...v1.Filter) ListOption {
return func(listInput *ListInput) {
listInput.Filters = filters
}
}
+1 -1
View File
@@ -29,7 +29,7 @@ type Transaction interface {
GetVM(name string) (result *v1.VM, err error)
SetVM(vm v1.VM) (err error)
DeleteVM(name string) (err error)
ListVMs(opts ...ListOption) (result []v1.VM, err error)
ListVMs() (result []v1.VM, err error)
GetWorker(name string) (result *v1.Worker, err error)
SetWorker(worker v1.Worker) (err error)