Skip to content

Commit 2b6f2d1

Browse files
committed
feat: rework inmem resource state implementation
This bring inmem closer to other state implementations: * `inmem.NewState()` is now namespaced inside, not an instance per namespace * one inmem state instance has a shared event buffer (stream) for all resource types and namespaces This should provide better memory usage for any inmem user, and also it builds the foundation to build a shared, consistent watch API for the controller runtime (not in this PR). Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
1 parent c7cf050 commit 2b6f2d1

49 files changed

Lines changed: 3224 additions & 1088 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
1+
# THIS FILE WAS AUTOMATICALLY GENERATED BY KRES, PLEASE DO NOT EDIT.
22
#
3-
# Generated on 2020-08-28T20:43:11Z by kres 292ed36-dirty.
3+
# Generated on 2026-08-04T10:58:40Z by kres 93d28ca.
44

55
_out
6+
*.local.md
7+
*.override.md

Makefile

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# THIS FILE WAS AUTOMATICALLY GENERATED BY KRES, PLEASE DO NOT EDIT.
22
#
3-
# Generated on 2026-07-15T06:26:20Z by kres d66531d.
3+
# Generated on 2026-08-04T10:58:40Z by kres 93d28ca.
44

55
# common variables
66

@@ -39,6 +39,7 @@ GOTOOLCHAIN ?= local
3939
GOEXPERIMENT ?=
4040
GO_BUILDFLAGS += -tags $(GO_BUILDTAGS)
4141
TESTPKGS ?= ./...
42+
IMAGE_SIGNER_IMAGE ?= ghcr.io/siderolabs/image-signer:v0.3.2
4243
KRES_IMAGE ?= ghcr.io/siderolabs/kres:latest
4344
CONFORMANCE_IMAGE ?= ghcr.io/siderolabs/conform:latest
4445

@@ -250,6 +251,19 @@ lint-fmt: lint-golangci-lint-fmt ## Run all linter formatters and fix up the so
250251
image-runtime: ## Builds image for runtime.
251252
@$(MAKE) registry-$@ IMAGE_NAME="runtime"
252253

254+
.PHONY: sign-image-runtime
255+
sign-image-runtime: ## Signs the image for runtime. Requires interactive Google authentication.
256+
@test -n "$$GITHUB_TOKEN" || { \
257+
echo 'GITHUB_TOKEN with write:packages scope must be set: gh auth refresh -s write:packages, then GITHUB_TOKEN=$$(gh auth token) make' $@; \
258+
exit 1; \
259+
}
260+
@TMP=$$(mktemp -d) && trap 'rm -rf "$$TMP"' EXIT && \
261+
printf '{"auths":{"$(REGISTRY)":{"username":"x","password":"%s"}}}' "$$GITHUB_TOKEN" > "$$TMP/config.json" && \
262+
docker run --rm -p 127.0.0.1:8585:8585 \
263+
-v "$$TMP:/dc:ro" -e DOCKER_CONFIG=/dc \
264+
$(IMAGE_SIGNER_IMAGE) sign --timeout=15m \
265+
$(REGISTRY)/$(USERNAME)/runtime:$(IMAGE_TAG)
266+
253267
.PHONY: rekres
254268
rekres:
255269
@docker pull $(KRES_IMAGE)

cmd/runtime/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
"github.com/cosi-project/runtime/pkg/logging"
3131
"github.com/cosi-project/runtime/pkg/state"
3232
"github.com/cosi-project/runtime/pkg/state/impl/inmem"
33-
"github.com/cosi-project/runtime/pkg/state/impl/namespaced"
3433
"github.com/cosi-project/runtime/pkg/state/protobuf/server"
3534
)
3635

@@ -77,7 +76,7 @@ func run() error {
7776
return fmt.Errorf("failed to listen on network address: %w", err)
7877
}
7978

80-
inmemState := state.WrapCore(namespaced.NewState(inmem.Build))
79+
inmemState := state.WrapCore(inmem.NewState())
8180

8281
logger := logging.DefaultLogger()
8382

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0
1010
github.com/hashicorp/go-multierror v1.1.1
1111
github.com/klauspost/compress v1.19.2
12-
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10
12+
github.com/planetscale/vtprotobuf v0.6.1-0.20260702190614-8ae5a48058df
1313
github.com/siderolabs/gen v0.8.7
1414
github.com/siderolabs/go-pointer v1.0.1
1515
github.com/siderolabs/go-retry v0.3.3

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
3737
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
3838
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
3939
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
40-
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
41-
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
40+
github.com/planetscale/vtprotobuf v0.6.1-0.20260702190614-8ae5a48058df h1:x2ymdov8jnZLDPfI+VVcf/ZvzuZ2u36ieXTuQASMkWI=
41+
github.com/planetscale/vtprotobuf v0.6.1-0.20260702190614-8ae5a48058df/go.mod h1:araspv2uYKozbi5lrKaqpv1/Uei7eQSml8JCw2A3IRg=
4242
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4343
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
4444
github.com/siderolabs/gen v0.8.7 h1:Nu31kL0ln/facRHBfNX7zcB7w9VZ9tifXKsP4lUtWHw=

pkg/controller/generic/cleanup/cleanup_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,12 @@ import (
2222
"github.com/cosi-project/runtime/pkg/resource/rtestutils"
2323
"github.com/cosi-project/runtime/pkg/state"
2424
"github.com/cosi-project/runtime/pkg/state/impl/inmem"
25-
"github.com/cosi-project/runtime/pkg/state/impl/namespaced"
2625
)
2726

2827
func runTest(t *testing.T, f func(ctx context.Context, t *testing.T, st state.State, rt *runtime.Runtime)) {
2928
defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
3029

31-
st := state.WrapCore(namespaced.NewState(inmem.Build))
30+
st := state.WrapCore(inmem.NewState())
3231

3332
logger := logging.DefaultLogger()
3433

pkg/controller/generic/destroy/destroy_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"github.com/cosi-project/runtime/pkg/resource/typed"
2727
"github.com/cosi-project/runtime/pkg/state"
2828
"github.com/cosi-project/runtime/pkg/state/impl/inmem"
29-
"github.com/cosi-project/runtime/pkg/state/impl/namespaced"
3029
)
3130

3231
// ANamespaceName is the namespace of A resource.
@@ -68,7 +67,7 @@ func (a ASpec) DeepCopy() ASpec {
6867
func runTest(t *testing.T, f func(ctx context.Context, t *testing.T, st state.State, rt *runtime.Runtime)) {
6968
defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
7069

71-
st := state.WrapCore(namespaced.NewState(inmem.Build))
70+
st := state.WrapCore(inmem.NewState())
7271

7372
logger := logging.DefaultLogger()
7473

pkg/controller/generic/qtransform/qtransform_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import (
3434
"github.com/cosi-project/runtime/pkg/safe"
3535
"github.com/cosi-project/runtime/pkg/state"
3636
"github.com/cosi-project/runtime/pkg/state/impl/inmem"
37-
"github.com/cosi-project/runtime/pkg/state/impl/namespaced"
3837
)
3938

4039
type ABController = qtransform.QController[*A, *B]
@@ -891,7 +890,7 @@ func TestMappedByLabelInput(t *testing.T) {
891890
func setup(t *testing.T, f func(ctx context.Context, st state.State, rt *runtime.Runtime), opts ...options.Option) {
892891
defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
893892

894-
st := state.WrapCore(namespaced.NewState(inmem.Build))
893+
st := state.WrapCore(inmem.NewState())
895894

896895
logger := logging.DefaultLogger()
897896

pkg/controller/generic/transform/transform_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
"github.com/cosi-project/runtime/pkg/safe"
3131
"github.com/cosi-project/runtime/pkg/state"
3232
"github.com/cosi-project/runtime/pkg/state/impl/inmem"
33-
"github.com/cosi-project/runtime/pkg/state/impl/namespaced"
3433
)
3534

3635
type ABController = transform.Controller[*A, *B]
@@ -639,7 +638,7 @@ func TestHooks(t *testing.T) {
639638
func setup(t *testing.T, f func(ctx context.Context, st state.State, rt *runtime.Runtime)) {
640639
defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
641640

642-
st := state.WrapCore(namespaced.NewState(inmem.Build))
641+
st := state.WrapCore(inmem.NewState())
643642

644643
logger := logging.DefaultLogger()
645644

pkg/controller/runtime/runtime_test.go

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import (
3232
"github.com/cosi-project/runtime/pkg/state"
3333
stateconformance "github.com/cosi-project/runtime/pkg/state/conformance"
3434
"github.com/cosi-project/runtime/pkg/state/impl/inmem"
35-
"github.com/cosi-project/runtime/pkg/state/impl/namespaced"
3635
"github.com/cosi-project/runtime/pkg/state/protobuf/client"
3736
"github.com/cosi-project/runtime/pkg/state/protobuf/server"
3837
)
@@ -97,7 +96,7 @@ func TestRuntimeConformance(t *testing.T) {
9796
suiterunner.Run(t, &conformance.RuntimeSuite{
9897
MetricsReadCacheEnabled: tt.metricsReadCacheEnabled,
9998
SetupRuntime: func(rs *conformance.RuntimeSuite) {
100-
rs.State = state.WrapCore(namespaced.NewState(inmem.Build))
99+
rs.State = state.WrapCore(inmem.NewState())
101100
logger := zaptest.NewLogger(rs.T())
102101
rs.Runtime = must.Value(runtime.NewRuntime(rs.State, logger, tt.opts...))(rs.T())
103102
},
@@ -119,7 +118,7 @@ func TestRuntimeConformance(t *testing.T) {
119118
l := must.Value((&net.ListenConfig{}).Listen(t.Context(), "tcp", listenOn))(rs.T())
120119

121120
grpcServer := grpc.NewServer()
122-
inmemState := state.WrapCore(namespaced.NewState(inmem.Build))
121+
inmemState := state.WrapCore(inmem.NewState())
123122
v1alpha1.RegisterStateServer(grpcServer, server.NewState(inmemState))
124123

125124
go func() { assert.NoError(rs.T(), grpcServer.Serve(l)) }()
@@ -153,12 +152,11 @@ func TestRuntimeWatchError(t *testing.T) {
153152
defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
154153

155154
// create a state with tiny capacity
156-
st := state.WrapCore(namespaced.NewState(func(ns string) state.CoreState {
157-
return inmem.NewStateWithOptions(
158-
inmem.WithHistoryMaxCapacity(10),
159-
inmem.WithHistoryGap(5),
160-
)(ns)
161-
}))
155+
st := state.WrapCore(inmem.NewStateWithOptions(
156+
inmem.WithHistoryInitialCapacity(10),
157+
inmem.WithHistoryMaxCapacity(10),
158+
inmem.WithHistoryGap(5),
159+
))
162160

163161
logger := zaptest.NewLogger(t)
164162
rt, err := runtime.NewRuntime(st, logger)
@@ -192,7 +190,7 @@ func TestRuntimeWatchOverrun(t *testing.T) {
192190

193191
defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
194192

195-
st := state.WrapCore(namespaced.NewState(inmem.Build))
193+
st := state.WrapCore(inmem.NewState())
196194

197195
logger := zaptest.NewLogger(t)
198196
rt, err := runtime.NewRuntime(st, logger)
@@ -245,7 +243,7 @@ func TestRuntimeWatchOverrun(t *testing.T) {
245243
func TestRuntimeCachedState(t *testing.T) {
246244
defer goleak.VerifyNone(t, goleak.IgnoreCurrent())
247245

248-
st := state.WrapCore(namespaced.NewState(inmem.Build))
246+
st := state.WrapCore(inmem.NewState())
249247

250248
logger := zaptest.NewLogger(t)
251249
rt, err := runtime.NewRuntime(st, logger, options.WithCachedResource("cached", conformance.IntResourceType))

0 commit comments

Comments
 (0)