Skip to content

Commit

Permalink
relpool-rid (#63)
Browse files Browse the repository at this point in the history
* cache inverted model on first use

* write message when inverted model is cached

* Use sync.Pool for Relation slices. (#60)

* up go.sum

* Memory pool for slices and messages

* Add memory pool for timestamppb.Timestamp

* Use vtproto mempool for Relation

* relpool change + RelationId refectoring (#62)

* convert azm to use RelationIdentifier

* update go-directory & grpc deps

* Fix: Checker.checkRelation wasn't setting the subject ID

As a result it was getting way more relations back.

* update deps

* Toggle between shared or per-call memory pool.

* Replace Cache RWMutex with an atomic pointer.

* Initialize SlicePool with given capacity

* upd [email protected]

---------

Co-authored-by: Ronen Hilewicz <[email protected]>

---------

Co-authored-by: Ronen Hilewicz <[email protected]>
Co-authored-by: Ronen Hilewicz <[email protected]>
  • Loading branch information
3 people authored Dec 11, 2024
1 parent ce48e0f commit 249565a
Show file tree
Hide file tree
Showing 18 changed files with 412 additions and 203 deletions.
51 changes: 18 additions & 33 deletions cache/cache.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package cache

import (
"sync"
"sync/atomic"

"github.com/aserto-dev/azm/mempool"
"github.com/aserto-dev/azm/model"
"github.com/aserto-dev/azm/model/diff"
stts "github.com/aserto-dev/azm/stats"
Expand All @@ -17,47 +18,39 @@ type (
)

type Cache struct {
model *model.Model
mtx sync.RWMutex
model atomic.Pointer[model.Model]
relsPool *mempool.RelationsPool
}

// New, create new model cache instance.
func New(m *model.Model) *Cache {
return &Cache{
model: m,
mtx: sync.RWMutex{},
cache := &Cache{
relsPool: mempool.NewRelationsPool(),
}

cache.model.Store(m)
return cache
}

// UpdateModel, swaps the cache model instance.
func (c *Cache) UpdateModel(m *model.Model) error {
c.mtx.Lock()
defer c.mtx.Unlock()
c.model = m
c.model.Store(m)
return nil
}

func (c *Cache) CanUpdate(other *model.Model, stats *stts.Stats) error {
c.mtx.Lock()
defer c.mtx.Unlock()
return diff.CanUpdateModel(c.model, other, stats)
return diff.CanUpdateModel(c.model.Load(), other, stats)
}

// ObjectExists, checks if given object type name exists in the model cache.
func (c *Cache) ObjectExists(on ObjectName) bool {
c.mtx.RLock()
defer c.mtx.RUnlock()

_, ok := c.model.Objects[on]
_, ok := c.model.Load().Objects[on]
return ok
}

// RelationExists, checks if given relation type, for the given object type, exists in the model cache.
func (c *Cache) RelationExists(on ObjectName, rn RelationName) bool {
c.mtx.RLock()
defer c.mtx.RUnlock()

if obj, ok := c.model.Objects[on]; ok {
if obj, ok := c.model.Load().Objects[on]; ok {
_, ok := obj.Relations[rn]
return ok
}
Expand All @@ -66,27 +59,19 @@ func (c *Cache) RelationExists(on ObjectName, rn RelationName) bool {

// PermissionExists, checks if given permission, for the given object type, exists in the model cache.
func (c *Cache) PermissionExists(on ObjectName, pn RelationName) bool {
c.mtx.RLock()
defer c.mtx.RUnlock()

if obj, ok := c.model.Objects[on]; ok {
if obj, ok := c.model.Load().Objects[on]; ok {
_, ok := obj.Permissions[pn]
return ok
}
return false
}

func (c *Cache) Metadata() *model.Metadata {
c.mtx.RLock()
defer c.mtx.RUnlock()
return c.model.Metadata
return c.model.Load().Metadata
}

func (c *Cache) ValidateRelation(relation *dsc.Relation) error {
c.mtx.RLock()
defer c.mtx.RUnlock()

return c.model.ValidateRelation(
func (c *Cache) ValidateRelation(relation *dsc.RelationIdentifier) error {
return c.model.Load().ValidateRelation(
ObjectName(relation.ObjectType),
model.ObjectID(relation.ObjectId),
RelationName(relation.Relation),
Expand Down Expand Up @@ -123,7 +108,7 @@ func (c *Cache) AssignableRelations(on, sn ObjectName, sr ...RelationName) ([]Re
}
}

matches := lo.PickBy(c.model.Objects[on].Relations, func(rn RelationName, r *model.Relation) bool {
matches := lo.PickBy(c.model.Load().Objects[on].Relations, func(rn RelationName, r *model.Relation) bool {
for _, ref := range r.Union {
if ref.Object != sn {
// type mismatch
Expand Down
19 changes: 16 additions & 3 deletions cache/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ package cache

import (
"github.com/aserto-dev/azm/graph"
"github.com/aserto-dev/azm/mempool"
dsr "github.com/aserto-dev/go-directory/aserto/directory/reader/v3"
"github.com/aserto-dev/go-directory/pkg/pb"
"github.com/aserto-dev/go-directory/pkg/prop"
"google.golang.org/protobuf/types/known/structpb"
)

// If true, use a shared memory pool for all requests.
// Othersise, each call gets its own pool.
const sharedPool = true

func (c *Cache) Check(req *dsr.CheckRequest, relReader graph.RelationReader) (*dsr.CheckResponse, error) {
checker := graph.NewCheck(c.model, req, relReader)
checker := graph.NewCheck(c.model.Load(), req, relReader, c.relationsPool())

ctx := pb.NewStruct()

Expand All @@ -32,9 +37,9 @@ func (c *Cache) GetGraph(req *dsr.GetGraphRequest, relReader graph.RelationReade
)

if req.ObjectId == "" {
search, err = graph.NewObjectSearch(c.model, req, relReader)
search, err = graph.NewObjectSearch(c.model.Load(), req, relReader, c.relationsPool())
} else {
search, err = graph.NewSubjectSearch(c.model, req, relReader)
search, err = graph.NewSubjectSearch(c.model.Load(), req, relReader, c.relationsPool())
}

if err != nil {
Expand All @@ -43,3 +48,11 @@ func (c *Cache) GetGraph(req *dsr.GetGraphRequest, relReader graph.RelationReade

return search.Search()
}

func (c *Cache) relationsPool() *mempool.RelationsPool {
if sharedPool {
return c.relsPool
}

return mempool.NewRelationsPool()
}
27 changes: 15 additions & 12 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,38 +1,41 @@
module github.com/aserto-dev/azm

go 1.22.9
go 1.22.10

toolchain go1.23.3
toolchain go1.23.4

// replace github.com/aserto-dev/go-directory => ../go-directory

require (
github.com/antlr4-go/antlr/v4 v4.13.1
github.com/aserto-dev/errors v0.0.11
github.com/aserto-dev/go-directory v0.33.1
github.com/deckarep/golang-set/v2 v2.6.0
github.com/aserto-dev/go-directory v0.33.2
github.com/deckarep/golang-set/v2 v2.7.0
github.com/hashicorp/go-multierror v1.1.1
github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.33.0
github.com/samber/lo v1.47.0
github.com/stretchr/testify v1.10.0
google.golang.org/grpc v1.68.0
google.golang.org/grpc v1.68.1
google.golang.org/protobuf v1.35.2
gopkg.in/yaml.v3 v3.0.1
)

require (
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.2-20240920164238-5a7b106cbb87.1 // indirect
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.2-20241127180247-a33202765966.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
golang.org/x/net v0.31.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.20.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect
golang.org/x/exp v0.0.0-20241210194714-1829a127f884 // indirect
golang.org/x/net v0.32.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
)
44 changes: 22 additions & 22 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.2-20240920164238-5a7b106cbb87.1 h1:7QIeAuTdLp173vC/9JojRMDFcpmqtoYrxPmvdHAOynw=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.2-20240920164238-5a7b106cbb87.1/go.mod h1:mnHCFccv4HwuIAOHNGdiIc5ZYbBCvbTWZcodLN5wITI=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.2-20241127180247-a33202765966.1 h1:jLd96rDDNJ+zIJxvV/L855VEtrjR0G4aePVDlCpf6kw=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.2-20241127180247-a33202765966.1/go.mod h1:mnHCFccv4HwuIAOHNGdiIc5ZYbBCvbTWZcodLN5wITI=
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
github.com/aserto-dev/errors v0.0.11 h1:CXo+Uwmh09doG2HvL1SC8Fnne8f9VPrGyEQPtogAfyY=
github.com/aserto-dev/errors v0.0.11/go.mod h1:T1YQOtcxpgBriPTn5HXJkD/QukYz5YojYOIzGMo0ybM=
github.com/aserto-dev/go-directory v0.33.1-0.20241125175915-5cffa131b985 h1:Pjpoa4n8Kx1KBaQ8GyW9Y9bVnbzTwWkx7gDhL5huhmI=
github.com/aserto-dev/go-directory v0.33.1-0.20241125175915-5cffa131b985/go.mod h1:eEvIFY+t6WclhJPHbu+Y17ghF4qRYc36UkJL5UNPVPY=
github.com/aserto-dev/go-directory v0.33.1 h1:jLyzMRu5Omw5KJ2cmqnGZZbrF091HFHnt9awhqZhSq8=
github.com/aserto-dev/go-directory v0.33.1/go.mod h1:0Ng9lPTahslSN/ONoWCceG6Q1ukpSfxYEu589eCReRM=
github.com/aserto-dev/go-directory v0.33.2 h1:QJwzSmfxJ7EG0RzWsgu7In5cAeGtZURZklSsHhMOFh8=
github.com/aserto-dev/go-directory v0.33.2/go.mod h1:gK239V0htJtp0/BwvbTrYv/XIphoK/AugP8sw3m8B0s=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM=
github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/deckarep/golang-set/v2 v2.7.0 h1:gIloKvD7yH2oip4VLhsv3JyLLFnC0Y2mlusgcvJYW5k=
github.com/deckarep/golang-set/v2 v2.7.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
Expand Down Expand Up @@ -41,6 +39,8 @@ github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1 h1:dOYG7LS/WK00RWZc8X
github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
Expand All @@ -52,23 +52,23 @@ github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU=
golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ=
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
Loading

0 comments on commit 249565a

Please sign in to comment.