add doc.go

This commit is contained in:
Ryan McKinley 2024-07-03 14:45:14 -07:00
parent 22d3f163df
commit 9fa906ab80
4 changed files with 43 additions and 75 deletions

View File

@ -28,7 +28,7 @@ func ProvideResourceServer(db db.DB, cfg *setting.Cfg, features featuremgmt.Feat
Tracer: tracer, Tracer: tracer,
} }
useEntitySQL := true useEntitySQL := false
if useEntitySQL { if useEntitySQL {
eDB, err := dbimpl.ProvideEntityDB(db, cfg, features, tracer) eDB, err := dbimpl.ProvideEntityDB(db, cfg, features, tracer)
if err != nil { if err != nil {

View File

@ -69,8 +69,9 @@ type cdkBackend struct {
nextRV NextResourceVersion nextRV NextResourceVersion
mutex sync.Mutex mutex sync.Mutex
// Typically one... the server wrapper // Simple watch stream -- NOTE, this only works for single tenant!
subscribers []chan *WrittenEvent broadcaster Broadcaster[*WrittenEvent]
stream chan<- *WrittenEvent
} }
func (s *cdkBackend) getPath(key *ResourceKey, rv int64) string { func (s *cdkBackend) getPath(key *ResourceKey, rv int64) string {
@ -123,24 +124,19 @@ func (s *cdkBackend) WriteEvent(ctx context.Context, event WriteEvent) (rv int64
} }
// Async notify all subscribers // Async notify all subscribers
if s.subscribers != nil { if s.stream != nil {
go func() { go func() {
write := &WrittenEvent{ write := &WrittenEvent{
WriteEvent: event, WriteEvent: event,
Timestamp: time.Now().UnixMilli(), Timestamp: time.Now().UnixMilli(),
ResourceVersion: rv, ResourceVersion: rv,
} }
for _, sub := range s.subscribers { s.stream <- write
sub <- write
}
}() }()
} }
return rv, err return rv, err
} }
// Read implements ResourceStoreServer.
func (s *cdkBackend) Read(ctx context.Context, req *ReadRequest) (*ReadResponse, error) { func (s *cdkBackend) Read(ctx context.Context, req *ReadRequest) (*ReadResponse, error) {
rv := req.ResourceVersion rv := req.ResourceVersion
@ -191,7 +187,6 @@ func isDeletedMarker(raw []byte) bool {
return false return false
} }
// List implements AppendingStore.
func (s *cdkBackend) PrepareList(ctx context.Context, req *ListRequest) (*ListResponse, error) { func (s *cdkBackend) PrepareList(ctx context.Context, req *ListRequest) (*ListResponse, error) {
resources, err := buildTree(ctx, s, req.Options.Key) resources, err := buildTree(ctx, s, req.Options.Key)
if err != nil { if err != nil {
@ -215,36 +210,21 @@ func (s *cdkBackend) PrepareList(ctx context.Context, req *ListRequest) (*ListRe
return rsp, nil return rsp, nil
} }
// Watch implements AppendingStore.
func (s *cdkBackend) WatchWriteEvents(ctx context.Context) (<-chan *WrittenEvent, error) { func (s *cdkBackend) WatchWriteEvents(ctx context.Context) (<-chan *WrittenEvent, error) {
stream := make(chan *WrittenEvent, 10) s.mutex.Lock()
{ defer s.mutex.Unlock()
s.mutex.Lock()
defer s.mutex.Unlock()
// Add the event stream if s.broadcaster == nil {
s.subscribers = append(s.subscribers, stream) var err error
} s.broadcaster, err = NewBroadcaster(context.Background(), func(c chan<- *WrittenEvent) error {
s.stream = c
// Wait for context done return nil
go func() { })
// Wait till the context is done if err != nil {
<-ctx.Done() return nil, err
// Then remove the subscription
s.mutex.Lock()
defer s.mutex.Unlock()
// Copy all streams without our listener
subs := []chan *WrittenEvent{}
for _, sub := range s.subscribers {
if sub != stream {
subs = append(subs, sub)
}
} }
s.subscribers = subs }
}() return s.broadcaster.Subscribe(ctx)
return stream, nil
} }
// group > resource > namespace > name > versions // group > resource > namespace > name > versions

View File

@ -2,7 +2,6 @@ package resource
import ( import (
"context" "context"
"embed"
"encoding/json" "encoding/json"
"fmt" "fmt"
"os" "os"
@ -39,7 +38,6 @@ func TestSimpleServer(t *testing.T) {
Metadata: fileblob.MetadataDontWrite, // skip Metadata: fileblob.MetadataDontWrite, // skip
}) })
require.NoError(t, err) require.NoError(t, err)
fmt.Printf("ROOT: %s\n\n", tmp) fmt.Printf("ROOT: %s\n\n", tmp)
} }
store, err := NewCDKBackend(ctx, CDKBackendOptions{ store, err := NewCDKBackend(ctx, CDKBackendOptions{
@ -53,7 +51,30 @@ func TestSimpleServer(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
t.Run("playlist happy CRUD paths", func(t *testing.T) { t.Run("playlist happy CRUD paths", func(t *testing.T) {
raw := testdata(t, "01_create_playlist.json") raw := []byte(`{
"apiVersion": "playlist.grafana.app/v0alpha1",
"kind": "Playlist",
"metadata": {
"name": "fdgsv37qslr0ga",
"namespace": "default",
"annotations": {
"grafana.app/originName": "elsewhere",
"grafana.app/originPath": "path/to/item",
"grafana.app/originTimestamp": "2024-02-02T00:00:00Z"
}
},
"spec": {
"title": "hello",
"interval": "5m",
"items": [
{
"type": "dashboard_by_uid",
"value": "vmie2cmWz"
}
]
}
}`)
key := &ResourceKey{ key := &ResourceKey{
Group: "playlist.grafana.app", Group: "playlist.grafana.app",
Resource: "rrrr", // can be anything :( Resource: "rrrr", // can be anything :(
@ -144,13 +165,3 @@ func TestSimpleServer(t *testing.T) {
require.Len(t, all.Items, 0) // empty require.Len(t, all.Items, 0) // empty
}) })
} }
//go:embed testdata/*
var testdataFS embed.FS
func testdata(t *testing.T, filename string) []byte {
t.Helper()
b, err := testdataFS.ReadFile(`testdata/` + filename)
require.NoError(t, err)
return b
}

View File

@ -1,23 +0,0 @@
{
"apiVersion": "playlist.grafana.app/v0alpha1",
"kind": "Playlist",
"metadata": {
"name": "fdgsv37qslr0ga",
"namespace": "default",
"annotations": {
"grafana.app/originName": "elsewhere",
"grafana.app/originPath": "path/to/item",
"grafana.app/originTimestamp": "2024-02-02T00:00:00Z"
}
},
"spec": {
"title": "hello",
"interval": "5m",
"items": [
{
"type": "dashboard_by_uid",
"value": "vmie2cmWz"
}
]
}
}