Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change from using protos to structs for relationships, ONRs and RRs #2081

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
efd028c
Reorganize tuple package and add relationship structs
josephschorr Sep 16, 2024
cdf5273
Start on datastore conversion with MemDB
josephschorr Sep 16, 2024
6ef4b3a
Update tests and get memdb passing for struct and iterator changes
josephschorr Sep 16, 2024
3af7ea2
Small tuple package improvements
josephschorr Sep 16, 2024
846ff04
Tuple -> Relationship renames
josephschorr Sep 17, 2024
17c8bf2
Start addressing RelationTuple in all other packages
josephschorr Sep 25, 2024
130ca0a
Update postgres driver for relationship changes
josephschorr Sep 28, 2024
bb3ea58
Update MySQL driver for relationship changes
josephschorr Sep 29, 2024
58e11c7
Update CRDB and Spanner and a few other locations for relationship ch…
josephschorr Sep 29, 2024
4b0671b
Address lint errors
josephschorr Sep 30, 2024
f729ef8
Move the remaining go files to 1.23.1
josephschorr Sep 30, 2024
0186a0d
Fix CRDB tests for relationship changes
josephschorr Sep 30, 2024
17ffcc5
Fix Postgres tests for relationship changes
josephschorr Sep 30, 2024
3d7bf84
Fix MySQL tests for relationship changes
josephschorr Sep 30, 2024
bc71c13
Fix Spanner tests for relationship changes
josephschorr Sep 30, 2024
458ecdd
Fix benchmark test
josephschorr Sep 30, 2024
1e420ff
Fix WASM test for relationships changes
josephschorr Sep 30, 2024
f1b4cb7
Integration test fixes for changed relationships
josephschorr Sep 30, 2024
270d7a6
Integration test fixes for changed relationships
josephschorr Sep 30, 2024
2819054
Disable close-after-usage check for rel iterator, as it handles it in…
josephschorr Sep 30, 2024
6534e2f
Update read-only mode test for PG
josephschorr Sep 30, 2024
2626edb
Fix dev test error
josephschorr Sep 30, 2024
1ec152f
Fixes for new relationship structs after rebase
josephschorr Oct 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/spicedb/servetesting_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ func TestTestServer(t *testing.T) {
// Try writing a simple relationship against readonly and ensure it fails.
_, err = rov1client.WriteRelationships(context.Background(), &v1.WriteRelationshipsRequest{
Updates: []*v1.RelationshipUpdate{
tuple.UpdateToRelationshipUpdate(tuple.Create(relationship)),
tuple.MustUpdateToV1RelationshipUpdate(tuple.Create(relationship)),
},
})
require.Equal("rpc error: code = Unavailable desc = service read-only", err.Error())

// Write a simple relationship.
_, err = v1client.WriteRelationships(context.Background(), &v1.WriteRelationshipsRequest{
Updates: []*v1.RelationshipUpdate{
tuple.UpdateToRelationshipUpdate(tuple.Create(relationship)),
tuple.MustUpdateToV1RelationshipUpdate(tuple.Create(relationship)),
},
})
require.NoError(err)
Expand Down
2 changes: 1 addition & 1 deletion e2e/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/authzed/spicedb/e2e

go 1.22.7
go 1.23.1

require (
github.com/authzed/authzed-go v0.15.1-0.20240916185322-dad4080470f3
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/authzed/spicedb

go 1.22.7
go 1.23.1

require (
buf.build/gen/go/prometheus/prometheus/protocolbuffers/go v1.34.2-20240802094132-5b212ab78fb7.2
Expand Down
10 changes: 5 additions & 5 deletions internal/datasets/subjectsetbyresourceid.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package datasets
import (
"fmt"

core "github.com/authzed/spicedb/pkg/proto/core/v1"
v1 "github.com/authzed/spicedb/pkg/proto/dispatch/v1"
"github.com/authzed/spicedb/pkg/tuple"
)

// NewSubjectSetByResourceID creates and returns a map of subject sets, indexed by resource ID.
Expand Down Expand Up @@ -34,10 +34,10 @@ func (ssr SubjectSetByResourceID) add(resourceID string, subject *v1.FoundSubjec

// AddFromRelationship adds the subject found in the given relationship to this map, indexed at
// the resource ID specified in the relationship.
func (ssr SubjectSetByResourceID) AddFromRelationship(relationship *core.RelationTuple) error {
return ssr.add(relationship.ResourceAndRelation.ObjectId, &v1.FoundSubject{
SubjectId: relationship.Subject.ObjectId,
CaveatExpression: wrapCaveat(relationship.Caveat),
func (ssr SubjectSetByResourceID) AddFromRelationship(relationship tuple.Relationship) error {
return ssr.add(relationship.Resource.ObjectID, &v1.FoundSubject{
SubjectId: relationship.Subject.ObjectID,
CaveatExpression: wrapCaveat(relationship.OptionalCaveat),
})
}

Expand Down
12 changes: 6 additions & 6 deletions internal/datasets/subjectsetbytype.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,24 @@ func NewSubjectByTypeSet() *SubjectByTypeSet {
}

// AddSubjectOf adds the subject found in the given relationship, along with its caveat.
func (s *SubjectByTypeSet) AddSubjectOf(relationship *core.RelationTuple) error {
return s.AddSubject(relationship.Subject, relationship.Caveat)
func (s *SubjectByTypeSet) AddSubjectOf(relationship tuple.Relationship) error {
return s.AddSubject(relationship.Subject, relationship.OptionalCaveat)
}

// AddConcreteSubject adds a non-caveated subject to the set.
func (s *SubjectByTypeSet) AddConcreteSubject(subject *core.ObjectAndRelation) error {
func (s *SubjectByTypeSet) AddConcreteSubject(subject tuple.ObjectAndRelation) error {
return s.AddSubject(subject, nil)
}

// AddSubject adds the specified subject to the set.
func (s *SubjectByTypeSet) AddSubject(subject *core.ObjectAndRelation, caveat *core.ContextualizedCaveat) error {
key := tuple.JoinRelRef(subject.Namespace, subject.Relation)
func (s *SubjectByTypeSet) AddSubject(subject tuple.ObjectAndRelation, caveat *core.ContextualizedCaveat) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious - why did this go from being a pointer to not being a pointer?

key := tuple.JoinRelRef(subject.ObjectType, subject.Relation)
if _, ok := s.byType[key]; !ok {
s.byType[key] = NewSubjectSet()
}

return s.byType[key].Add(&v1.FoundSubject{
SubjectId: subject.ObjectId,
SubjectId: subject.ObjectID,
CaveatExpression: wrapCaveat(caveat),
})
}
Expand Down
10 changes: 5 additions & 5 deletions internal/datasets/subjectsetbytype_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,19 @@ func TestSubjectByTypeSet(t *testing.T) {
require.True(t, set.IsEmpty())

// Add some concrete subjects.
err := set.AddConcreteSubject(tuple.ParseONR("document:foo#viewer"))
err := set.AddConcreteSubject(tuple.MustParseONR("document:foo#viewer"))
require.NoError(t, err)

err = set.AddConcreteSubject(tuple.ParseONR("document:bar#viewer"))
err = set.AddConcreteSubject(tuple.MustParseONR("document:bar#viewer"))
require.NoError(t, err)

err = set.AddConcreteSubject(tuple.ParseONR("team:something#member"))
err = set.AddConcreteSubject(tuple.MustParseONR("team:something#member"))
require.NoError(t, err)

err = set.AddConcreteSubject(tuple.ParseONR("team:other#member"))
err = set.AddConcreteSubject(tuple.MustParseONR("team:other#member"))
require.NoError(t, err)

err = set.AddConcreteSubject(tuple.ParseONR("team:other#manager"))
err = set.AddConcreteSubject(tuple.MustParseONR("team:other#manager"))
require.NoError(t, err)
Comment on lines +44 to 57
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easier to maintain over time if you write these with a loop:

for _, rel := range []string{
    "document:foo#viewer",
    "document:bar#viewer",
    "team:something#member",
    "team:other#member",
    "team:other#manager",
} {
    require.NoError(t, set.AddConcreteSubject(tuple.MustParseONR(rel)))
}


// Add a caveated subject.
Expand Down
92 changes: 49 additions & 43 deletions internal/datastore/benchmark/driver_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
dsconfig "github.com/authzed/spicedb/pkg/cmd/datastore"
"github.com/authzed/spicedb/pkg/datastore"
"github.com/authzed/spicedb/pkg/datastore/options"
core "github.com/authzed/spicedb/pkg/proto/core/v1"
"github.com/authzed/spicedb/pkg/tuple"
)

Expand Down Expand Up @@ -80,12 +79,9 @@ func BenchmarkDatastoreDriver(b *testing.B) {
// Write a fair amount of data, much more than a functional test
for docNum := 0; docNum < numDocuments; docNum++ {
_, err := ds.ReadWriteTx(ctx, func(ctx context.Context, rwt datastore.ReadWriteTransaction) error {
var updates []*core.RelationTupleUpdate
var updates []tuple.RelationshipUpdate
for userNum := 0; userNum < usersPerDoc; userNum++ {
updates = append(updates, &core.RelationTupleUpdate{
Operation: core.RelationTupleUpdate_CREATE,
Tuple: docViewer(strconv.Itoa(docNum), strconv.Itoa(userNum)),
})
updates = append(updates, tuple.Create(docViewer(strconv.Itoa(docNum), strconv.Itoa(userNum))))
}

return rwt.WriteRelationships(ctx, updates)
Expand All @@ -110,14 +106,26 @@ func BenchmarkDatastoreDriver(b *testing.B) {
})
require.NoError(b, err)
var count int
for rel := iter.Next(); rel != nil; rel = iter.Next() {
for _, err := range iter {
require.NoError(b, err)
count++
}
require.NoError(b, iter.Err())
iter.Close()
require.Equal(b, usersPerDoc, count)
}
})
b.Run("SnapshotReadOnlyNamespace", func(b *testing.B) {
for n := 0; n < b.N; n++ {
iter, err := ds.SnapshotReader(headRev).QueryRelationships(ctx, datastore.RelationshipsFilter{
OptionalResourceType: testfixtures.DocumentNS.Name,
})
require.NoError(b, err)
var count int
for _, err := range iter {
require.NoError(b, err)
count++
}
}
})
b.Run("SortedSnapshotReadOnlyNamespace", func(b *testing.B) {
for orderName, order := range sortOrders {
order := order
Expand All @@ -128,11 +136,10 @@ func BenchmarkDatastoreDriver(b *testing.B) {
}, options.WithSort(order))
require.NoError(b, err)
var count int
for rel := iter.Next(); rel != nil; rel = iter.Next() {
for _, err := range iter {
require.NoError(b, err)
count++
}
require.NoError(b, iter.Err())
iter.Close()
}
})
}
Expand All @@ -148,11 +155,10 @@ func BenchmarkDatastoreDriver(b *testing.B) {
}, options.WithSort(order))
require.NoError(b, err)
var count int
for rel := iter.Next(); rel != nil; rel = iter.Next() {
for _, err := range iter {
require.NoError(b, err)
count++
}
require.NoError(b, iter.Err())
iter.Close()
}
})
}
Expand All @@ -170,11 +176,10 @@ func BenchmarkDatastoreDriver(b *testing.B) {
}, options.WithSort(order))
require.NoError(b, err)
var count int
for rel := iter.Next(); rel != nil; rel = iter.Next() {
for _, err := range iter {
require.NoError(b, err)
count++
}
require.NoError(b, iter.Err())
iter.Close()
}
})
}
Expand All @@ -186,32 +191,31 @@ func BenchmarkDatastoreDriver(b *testing.B) {
}, options.WithSortForReverse(options.ByResource))
require.NoError(b, err)
var count int
for rel := iter.Next(); rel != nil; rel = iter.Next() {
for _, err := range iter {
require.NoError(b, err)
count++
}
require.NoError(b, iter.Err())
iter.Close()
}
})
b.Run("Touch", buildTupleTest(ctx, ds, core.RelationTupleUpdate_TOUCH))
b.Run("Create", buildTupleTest(ctx, ds, core.RelationTupleUpdate_CREATE))
b.Run("Touch", buildRelTest(ctx, ds, tuple.UpdateOperationTouch))
b.Run("Create", buildRelTest(ctx, ds, tuple.UpdateOperationCreate))
b.Run("CreateAndTouch", func(b *testing.B) {
const totalRelationships = 1000
for _, portionCreate := range []float64{0, 0.10, 0.25, 0.50, 1} {
portionCreate := portionCreate
b.Run(fmt.Sprintf("%v_", portionCreate), func(b *testing.B) {
for n := 0; n < b.N; n++ {
portionCreateIndex := int(math.Floor(portionCreate * totalRelationships))
mutations := make([]*core.RelationTupleUpdate, 0, totalRelationships)
mutations := make([]tuple.RelationshipUpdate, 0, totalRelationships)
for index := 0; index < totalRelationships; index++ {
if index >= portionCreateIndex {
stableID := fmt.Sprintf("id-%d", index)
tpl := docViewer(stableID, stableID)
mutations = append(mutations, tuple.Touch(tpl))
rel := docViewer(stableID, stableID)
mutations = append(mutations, tuple.Touch(rel))
} else {
randomID := testfixtures.RandomObjectID(32)
tpl := docViewer(randomID, randomID)
mutations = append(mutations, tuple.Create(tpl))
rel := docViewer(randomID, randomID)
mutations = append(mutations, tuple.Create(rel))
}
}

Expand Down Expand Up @@ -244,15 +248,15 @@ func TestAllDriversBenchmarkedOrSkipped(t *testing.T) {
require.Empty(t, notBenchmarked)
}

func buildTupleTest(ctx context.Context, ds datastore.Datastore, op core.RelationTupleUpdate_Operation) func(b *testing.B) {
func buildRelTest(ctx context.Context, ds datastore.Datastore, op tuple.UpdateOperation) func(b *testing.B) {
return func(b *testing.B) {
for n := 0; n < b.N; n++ {
_, err := ds.ReadWriteTx(ctx, func(ctx context.Context, rwt datastore.ReadWriteTransaction) error {
randomID := testfixtures.RandomObjectID(32)
return rwt.WriteRelationships(ctx, []*core.RelationTupleUpdate{
return rwt.WriteRelationships(ctx, []tuple.RelationshipUpdate{
{
Operation: op,
Tuple: docViewer(randomID, randomID),
Operation: op,
Relationship: docViewer(randomID, randomID),
},
})
})
Expand All @@ -261,17 +265,19 @@ func buildTupleTest(ctx context.Context, ds datastore.Datastore, op core.Relatio
}
}

func docViewer(documentID, userID string) *core.RelationTuple {
return &core.RelationTuple{
ResourceAndRelation: &core.ObjectAndRelation{
Namespace: testfixtures.DocumentNS.Name,
ObjectId: documentID,
Relation: "viewer",
},
Subject: &core.ObjectAndRelation{
Namespace: testfixtures.UserNS.Name,
ObjectId: userID,
Relation: datastore.Ellipsis,
func docViewer(documentID, userID string) tuple.Relationship {
return tuple.Relationship{
RelationshipReference: tuple.RelationshipReference{
Resource: tuple.ObjectAndRelation{
ObjectType: testfixtures.DocumentNS.Name,
ObjectID: documentID,
Relation: "viewer",
},
Subject: tuple.ObjectAndRelation{
ObjectType: testfixtures.UserNS.Name,
ObjectID: userID,
Relation: datastore.Ellipsis,
},
},
}
}
Loading
Loading