Skip to content

Commit 2330e34

Browse files
committed
change the changeset to generic
1 parent ec99b34 commit 2330e34

20 files changed

+315
-418
lines changed

apps/workspace-engine/pkg/changeset/changeset.go

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,59 +8,36 @@ import (
88
type ChangeType string
99

1010
const (
11-
ChangeTypeInsert ChangeType = "insert"
11+
ChangeTypeCreate ChangeType = "create"
1212
ChangeTypeUpdate ChangeType = "update"
1313
ChangeTypeDelete ChangeType = "delete"
14+
ChangeTypeTaint ChangeType = "taint"
1415
)
1516

16-
type EntityType string
17-
18-
const (
19-
EntityTypeResource EntityType = "resource"
20-
EntityTypeDeployment EntityType = "deployment"
21-
EntityTypeEnvironment EntityType = "environment"
22-
EntityTypeReleaseTarget EntityType = "releaseTarget"
23-
EntityTypeJob EntityType = "job"
24-
EntityTypeJobAgent EntityType = "jobAgent"
25-
EntityTypeRelease EntityType = "release"
26-
EntityTypeDeploymentVariable EntityType = "deploymentVariable"
27-
EntityTypeDeploymentVersion EntityType = "deploymentVersion"
28-
EntityTypeVariableSet EntityType = "variableSet"
29-
EntityTypeSystem EntityType = "system"
30-
EntityTypeResourceProvider EntityType = "resourceProvider"
31-
EntityTypeResourceMetadataGroup EntityType = "resourceMetadataGroup"
32-
EntityTypeResourceRelationshipRule EntityType = "resourceRelationshipRule"
33-
EntityTypePolicy EntityType = "policy"
34-
)
35-
36-
type Change struct {
37-
EntityType EntityType
17+
type Change[T any] struct {
3818
Type ChangeType
39-
ID string
40-
Entity any
19+
Entity T
4120
Timestamp time.Time
4221
}
4322

44-
type ChangeSet struct {
23+
type ChangeSet[T any] struct {
4524
IsInitialLoad bool
46-
Changes []Change
25+
Changes []Change[T]
4726
Mutex sync.Mutex
4827
}
4928

50-
func NewChangeSet() *ChangeSet {
51-
return &ChangeSet{
52-
Changes: make([]Change, 0),
29+
func NewChangeSet[T any]() *ChangeSet[T] {
30+
return &ChangeSet[T]{
31+
Changes: make([]Change[T], 0),
5332
}
5433
}
5534

56-
func (cs *ChangeSet) Record(entityType EntityType, changeType ChangeType, id string, entity any) {
35+
func (cs *ChangeSet[T]) Record(changeType ChangeType, entity T) {
5736
cs.Mutex.Lock()
5837
defer cs.Mutex.Unlock()
5938

60-
cs.Changes = append(cs.Changes, Change{
61-
EntityType: entityType,
39+
cs.Changes = append(cs.Changes, Change[T]{
6240
Type: changeType,
63-
ID: id,
6441
Entity: entity,
6542
Timestamp: time.Now(),
6643
})

apps/workspace-engine/pkg/changeset/changeset_consumer.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ import (
44
"context"
55
)
66

7-
type ChangesetConsumer interface {
8-
FlushChangeset(ctx context.Context, changeset *ChangeSet) error
7+
type ChangesetConsumer[T any] interface {
8+
FlushChangeset(ctx context.Context, changeset *ChangeSet[T]) error
99
}
1010

1111
type NoopChangesetConsumer struct{}
1212

13-
var _ ChangesetConsumer = (*NoopChangesetConsumer)(nil)
13+
var _ ChangesetConsumer[any] = (*NoopChangesetConsumer)(nil)
1414

1515
func NewNoopChangesetConsumer() *NoopChangesetConsumer {
1616
return &NoopChangesetConsumer{}
1717
}
1818

19-
func (n *NoopChangesetConsumer) FlushChangeset(ctx context.Context, changeset *ChangeSet) error {
19+
func (n *NoopChangesetConsumer) FlushChangeset(ctx context.Context, changeset *ChangeSet[any]) error {
2020
return nil
2121
}

apps/workspace-engine/pkg/changeset/changeset_test.go

Lines changed: 31 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,20 @@ import (
88

99
// Test that recording changes works correctly
1010
func TestChangeSet_Record(t *testing.T) {
11-
cs := NewChangeSet()
11+
cs := NewChangeSet[any]()
1212

1313
// Record a change
1414
testEntity := map[string]string{"name": "test-resource"}
15-
cs.Record(EntityTypeResource, ChangeTypeInsert, "resource-1", testEntity)
15+
cs.Record(ChangeTypeCreate, testEntity)
1616

1717
// Verify the change was recorded
1818
if len(cs.Changes) != 1 {
1919
t.Fatalf("expected 1 change, got %d", len(cs.Changes))
2020
}
2121

2222
change := cs.Changes[0]
23-
if change.EntityType != EntityTypeResource {
24-
t.Errorf("expected EntityType %v, got %v", EntityTypeResource, change.EntityType)
25-
}
26-
if change.Type != ChangeTypeInsert {
27-
t.Errorf("expected ChangeType %v, got %v", ChangeTypeInsert, change.Type)
28-
}
29-
if change.ID != "resource-1" {
30-
t.Errorf("expected ID %s, got %s", "resource-1", change.ID)
23+
if change.Type != ChangeTypeCreate {
24+
t.Errorf("expected ChangeType %v, got %v", ChangeTypeCreate, change.Type)
3125
}
3226
if change.Entity == nil {
3327
t.Error("expected Entity to be set, got nil")
@@ -39,46 +33,36 @@ func TestChangeSet_Record(t *testing.T) {
3933

4034
// Test that recording multiple changes works correctly
4135
func TestChangeSet_RecordMultiple(t *testing.T) {
42-
cs := NewChangeSet()
36+
cs := NewChangeSet[any]()
4337

4438
// Record multiple changes
45-
cs.Record(EntityTypeResource, ChangeTypeInsert, "resource-1", nil)
46-
cs.Record(EntityTypeDeployment, ChangeTypeUpdate, "deployment-1", nil)
47-
cs.Record(EntityTypeEnvironment, ChangeTypeDelete, "env-1", nil)
39+
cs.Record(ChangeTypeCreate, "resource-1")
40+
cs.Record(ChangeTypeUpdate, "deployment-1")
41+
cs.Record(ChangeTypeDelete, "env-1")
4842

4943
// Verify all changes were recorded
5044
if len(cs.Changes) != 3 {
5145
t.Fatalf("expected 3 changes, got %d", len(cs.Changes))
5246
}
5347

5448
// Verify each change
55-
expectedChanges := []struct {
56-
entityType EntityType
57-
changeType ChangeType
58-
id string
59-
}{
60-
{EntityTypeResource, ChangeTypeInsert, "resource-1"},
61-
{EntityTypeDeployment, ChangeTypeUpdate, "deployment-1"},
62-
{EntityTypeEnvironment, ChangeTypeDelete, "env-1"},
49+
expectedChanges := []ChangeType{
50+
ChangeTypeCreate,
51+
ChangeTypeUpdate,
52+
ChangeTypeDelete,
6353
}
6454

6555
for i, expected := range expectedChanges {
6656
change := cs.Changes[i]
67-
if change.EntityType != expected.entityType {
68-
t.Errorf("change %d: expected EntityType %v, got %v", i, expected.entityType, change.EntityType)
69-
}
70-
if change.Type != expected.changeType {
71-
t.Errorf("change %d: expected ChangeType %v, got %v", i, expected.changeType, change.Type)
72-
}
73-
if change.ID != expected.id {
74-
t.Errorf("change %d: expected ID %s, got %s", i, expected.id, change.ID)
57+
if change.Type != expected {
58+
t.Errorf("change %d: expected ChangeType %v, got %v", i, expected, change.Type)
7559
}
7660
}
7761
}
7862

7963
// Test thread safety of concurrent Record() calls
8064
func TestChangeSet_ConcurrentRecord(t *testing.T) {
81-
cs := NewChangeSet()
65+
cs := NewChangeSet[any]()
8266

8367
numGoroutines := 100
8468
changesPerGoroutine := 10
@@ -91,12 +75,8 @@ func TestChangeSet_ConcurrentRecord(t *testing.T) {
9175
go func(goroutineID int) {
9276
defer wg.Done()
9377
for j := 0; j < changesPerGoroutine; j++ {
94-
cs.Record(
95-
EntityTypeResource,
96-
ChangeTypeInsert,
97-
"resource-"+string(rune(goroutineID))+"-"+string(rune(j)),
98-
nil,
99-
)
78+
entity := map[string]int{"goroutine": goroutineID, "iteration": j}
79+
cs.Record(ChangeTypeCreate, entity)
10080
}
10181
}(i)
10282
}
@@ -111,14 +91,11 @@ func TestChangeSet_ConcurrentRecord(t *testing.T) {
11191

11292
// Verify no changes were lost or corrupted
11393
for i, change := range cs.Changes {
114-
if change.EntityType != EntityTypeResource {
115-
t.Errorf("change %d: expected EntityType %v, got %v", i, EntityTypeResource, change.EntityType)
94+
if change.Type != ChangeTypeCreate {
95+
t.Errorf("change %d: expected ChangeType %v, got %v", i, ChangeTypeCreate, change.Type)
11696
}
117-
if change.Type != ChangeTypeInsert {
118-
t.Errorf("change %d: expected ChangeType %v, got %v", i, ChangeTypeInsert, change.Type)
119-
}
120-
if change.ID == "" {
121-
t.Errorf("change %d: expected non-empty ID", i)
97+
if change.Entity == nil {
98+
t.Errorf("change %d: expected non-nil Entity", i)
12299
}
123100
if change.Timestamp.IsZero() {
124101
t.Errorf("change %d: expected non-zero Timestamp", i)
@@ -128,23 +105,22 @@ func TestChangeSet_ConcurrentRecord(t *testing.T) {
128105

129106
// Test that change ordering is preserved
130107
func TestChangeSet_OrderingPreserved(t *testing.T) {
131-
cs := NewChangeSet()
108+
cs := NewChangeSet[string]()
132109

133110
// Record changes with a small delay to ensure distinct timestamps
134111
changes := []struct {
135-
entityType EntityType
136112
changeType ChangeType
137-
id string
113+
entity string
138114
}{
139-
{EntityTypeResource, ChangeTypeInsert, "first"},
140-
{EntityTypeDeployment, ChangeTypeUpdate, "second"},
141-
{EntityTypeEnvironment, ChangeTypeDelete, "third"},
142-
{EntityTypeJob, ChangeTypeInsert, "fourth"},
143-
{EntityTypeRelease, ChangeTypeUpdate, "fifth"},
115+
{ChangeTypeCreate, "first"},
116+
{ChangeTypeUpdate, "second"},
117+
{ChangeTypeDelete, "third"},
118+
{ChangeTypeCreate, "fourth"},
119+
{ChangeTypeUpdate, "fifth"},
144120
}
145121

146122
for _, c := range changes {
147-
cs.Record(c.entityType, c.changeType, c.id, nil)
123+
cs.Record(c.changeType, c.entity)
148124
time.Sleep(1 * time.Millisecond) // Small delay to ensure distinct timestamps
149125
}
150126

@@ -155,11 +131,8 @@ func TestChangeSet_OrderingPreserved(t *testing.T) {
155131

156132
for i, expected := range changes {
157133
change := cs.Changes[i]
158-
if change.ID != expected.id {
159-
t.Errorf("position %d: expected ID %s, got %s (ordering not preserved)", i, expected.id, change.ID)
160-
}
161-
if change.EntityType != expected.entityType {
162-
t.Errorf("position %d: expected EntityType %v, got %v", i, expected.entityType, change.EntityType)
134+
if change.Entity != expected.entity {
135+
t.Errorf("position %d: expected Entity %s, got %s (ordering not preserved)", i, expected.entity, change.Entity)
163136
}
164137
if change.Type != expected.changeType {
165138
t.Errorf("position %d: expected ChangeType %v, got %v", i, expected.changeType, change.Type)

apps/workspace-engine/pkg/changeset/context.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ import (
55
)
66

77
// contextKey is an unexported type for keys defined in this package.
8-
type contextKey struct{}
8+
type contextKey[T any] struct{}
99

10-
var changesetKey = &contextKey{}
10+
var changesetKey = &contextKey[any]{}
1111

1212
// WithChangeSet returns a new context with the provided ChangeSet attached.
13-
func WithChangeSet(ctx context.Context, cs *ChangeSet) context.Context {
13+
func WithChangeSet[T any](ctx context.Context, cs *ChangeSet[T]) context.Context {
1414
return context.WithValue(ctx, changesetKey, cs)
1515
}
1616

1717
// FromContext retrieves the ChangeSet from the context, if it exists.
1818
// The returned boolean is true if a ChangeSet was found in the context.
19-
func FromContext(ctx context.Context) (*ChangeSet, bool) {
20-
cs, ok := ctx.Value(changesetKey).(*ChangeSet)
19+
func FromContext[T any](ctx context.Context) (*ChangeSet[T], bool) {
20+
cs, ok := ctx.Value(changesetKey).(*ChangeSet[T])
2121
return cs, ok
2222
}

0 commit comments

Comments
 (0)