Skip to content

Commit f4bbdf3

Browse files
authored
Merge pull request #1997 from authzed/dispatch-chunk-safeguards
additional dispatch chunk safeguards
2 parents 5d16bb1 + a657d62 commit f4bbdf3

File tree

10 files changed

+70
-13
lines changed

10 files changed

+70
-13
lines changed

internal/datastore/common/sql.go

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"go.opentelemetry.io/otel"
1212
"go.opentelemetry.io/otel/attribute"
1313

14+
log "github.com/authzed/spicedb/internal/logging"
1415
"github.com/authzed/spicedb/pkg/datastore"
1516
"github.com/authzed/spicedb/pkg/datastore/options"
1617
core "github.com/authzed/spicedb/pkg/proto/core/v1"
@@ -107,6 +108,11 @@ type SchemaQueryFilterer struct {
107108

108109
// NewSchemaQueryFilterer creates a new SchemaQueryFilterer object.
109110
func NewSchemaQueryFilterer(schema SchemaInformation, initialQuery sq.SelectBuilder, filterMaximumIDCount uint16) SchemaQueryFilterer {
111+
if filterMaximumIDCount == 0 {
112+
filterMaximumIDCount = 100
113+
log.Warn().Msg("SchemaQueryFilterer: filterMaximumIDCount not set, defaulting to 100")
114+
}
115+
110116
return SchemaQueryFilterer{
111117
schema: schema,
112118
queryBuilder: initialQuery,

internal/datastore/crdb/options.go

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
pgxcommon "github.com/authzed/spicedb/internal/datastore/postgres/common"
8+
log "github.com/authzed/spicedb/internal/logging"
89
)
910

1011
type crdbOptions struct {
@@ -85,6 +86,11 @@ func generateConfig(options []Option) (crdbOptions, error) {
8586
)
8687
}
8788

89+
if computed.filterMaximumIDCount == 0 {
90+
computed.filterMaximumIDCount = 100
91+
log.Warn().Msg("filterMaximumIDCount not set, defaulting to 100")
92+
}
93+
8894
return computed, nil
8995
}
9096

internal/datastore/mysql/options.go

+7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package mysql
33
import (
44
"fmt"
55
"time"
6+
7+
log "github.com/authzed/spicedb/internal/logging"
68
)
79

810
const (
@@ -82,6 +84,11 @@ func generateConfig(options []Option) (mysqlOptions, error) {
8284
)
8385
}
8486

87+
if computed.filterMaximumIDCount == 0 {
88+
computed.filterMaximumIDCount = 100
89+
log.Warn().Msg("filterMaximumIDCount not set, defaulting to 100")
90+
}
91+
8592
return computed, nil
8693
}
8794

internal/datastore/postgres/options.go

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
pgxcommon "github.com/authzed/spicedb/internal/datastore/postgres/common"
8+
log "github.com/authzed/spicedb/internal/logging"
89
)
910

1011
type postgresOptions struct {
@@ -106,6 +107,11 @@ func generateConfig(options []Option) (postgresOptions, error) {
106107
return computed, fmt.Errorf("unknown migration phase: %s", computed.migrationPhase)
107108
}
108109

110+
if computed.filterMaximumIDCount == 0 {
111+
computed.filterMaximumIDCount = 100
112+
log.Warn().Msg("filterMaximumIDCount not set, defaulting to 100")
113+
}
114+
109115
return computed, nil
110116
}
111117

internal/datastore/spanner/options.go

+7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"math"
66
"runtime"
77
"time"
8+
9+
log "github.com/authzed/spicedb/internal/logging"
810
)
911

1012
type spannerOptions struct {
@@ -88,6 +90,11 @@ func generateConfig(options []Option) (spannerOptions, error) {
8890
return computed, fmt.Errorf("unknown migration phase: %s", computed.migrationPhase)
8991
}
9092

93+
if computed.filterMaximumIDCount == 0 {
94+
computed.filterMaximumIDCount = 100
95+
log.Warn().Msg("filterMaximumIDCount not set, defaulting to 100")
96+
}
97+
9198
return computed, nil
9299
}
93100

internal/dispatch/cluster/cluster.go

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/authzed/spicedb/internal/dispatch/caching"
88
"github.com/authzed/spicedb/internal/dispatch/graph"
99
"github.com/authzed/spicedb/internal/dispatch/keys"
10+
log "github.com/authzed/spicedb/internal/logging"
1011
"github.com/authzed/spicedb/pkg/cache"
1112
)
1213

@@ -74,6 +75,11 @@ func NewClusterDispatcher(dispatch dispatch.Dispatcher, options ...Option) (disp
7475
fn(&opts)
7576
}
7677

78+
chunkSize := opts.dispatchChunkSize
79+
if chunkSize == 0 {
80+
chunkSize = 100
81+
log.Warn().Msgf("ClusterDispatcher: dispatchChunkSize not set, defaulting to %d", chunkSize)
82+
}
7783
clusterDispatch := graph.NewDispatcher(dispatch, opts.concurrencyLimits, opts.dispatchChunkSize)
7884

7985
if opts.prometheusSubsystem == "" {

internal/dispatch/combined/combined.go

+1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ func NewDispatcher(options ...Option) (dispatch.Dispatcher, error) {
153153
chunkSize := opts.dispatchChunkSize
154154
if chunkSize == 0 {
155155
chunkSize = 100
156+
log.Warn().Msgf("CombinedDispatcher: dispatchChunkSize not set, defaulting to %d", chunkSize)
156157
}
157158
redispatch := graph.NewDispatcher(cachingRedispatch, opts.concurrencyLimits, chunkSize)
158159
redispatch = singleflight.New(redispatch, &keys.CanonicalKeyHandler{})

internal/dispatch/graph/graph.go

+20-10
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,18 @@ func NewLocalOnlyDispatcherWithLimits(concurrencyLimits ConcurrencyLimits, dispa
8888
d := &localDispatcher{}
8989

9090
concurrencyLimits = limitsOrDefaults(concurrencyLimits, defaultConcurrencyLimit)
91+
chunkSize := dispatchChunkSize
92+
if chunkSize == 0 {
93+
chunkSize = 100
94+
log.Warn().Msgf("LocalOnlyDispatcher: dispatchChunkSize not set, defaulting to %d", chunkSize)
95+
}
9196

92-
d.checker = graph.NewConcurrentChecker(d, concurrencyLimits.Check, dispatchChunkSize)
97+
d.checker = graph.NewConcurrentChecker(d, concurrencyLimits.Check, chunkSize)
9398
d.expander = graph.NewConcurrentExpander(d)
94-
d.reachableResourcesHandler = graph.NewCursoredReachableResources(d, concurrencyLimits.ReachableResources, dispatchChunkSize)
95-
d.lookupResourcesHandler = graph.NewCursoredLookupResources(d, d, concurrencyLimits.LookupResources, dispatchChunkSize)
96-
d.lookupSubjectsHandler = graph.NewConcurrentLookupSubjects(d, concurrencyLimits.LookupSubjects, dispatchChunkSize)
97-
d.lookupResourcesHandler2 = graph.NewCursoredLookupResources2(d, d, concurrencyLimits.LookupResources, dispatchChunkSize)
99+
d.reachableResourcesHandler = graph.NewCursoredReachableResources(d, concurrencyLimits.ReachableResources, chunkSize)
100+
d.lookupResourcesHandler = graph.NewCursoredLookupResources(d, d, concurrencyLimits.LookupResources, chunkSize)
101+
d.lookupSubjectsHandler = graph.NewConcurrentLookupSubjects(d, concurrencyLimits.LookupSubjects, chunkSize)
102+
d.lookupResourcesHandler2 = graph.NewCursoredLookupResources2(d, d, concurrencyLimits.LookupResources, chunkSize)
98103

99104
return d
100105
}
@@ -103,13 +108,18 @@ func NewLocalOnlyDispatcherWithLimits(concurrencyLimits ConcurrencyLimits, dispa
103108
// the provided redispatcher.
104109
func NewDispatcher(redispatcher dispatch.Dispatcher, concurrencyLimits ConcurrencyLimits, dispatchChunkSize uint16) dispatch.Dispatcher {
105110
concurrencyLimits = limitsOrDefaults(concurrencyLimits, defaultConcurrencyLimit)
111+
chunkSize := dispatchChunkSize
112+
if chunkSize == 0 {
113+
chunkSize = 100
114+
log.Warn().Msgf("Dispatcher: dispatchChunkSize not set, defaulting to %d", chunkSize)
115+
}
106116

107-
checker := graph.NewConcurrentChecker(redispatcher, concurrencyLimits.Check, dispatchChunkSize)
117+
checker := graph.NewConcurrentChecker(redispatcher, concurrencyLimits.Check, chunkSize)
108118
expander := graph.NewConcurrentExpander(redispatcher)
109-
reachableResourcesHandler := graph.NewCursoredReachableResources(redispatcher, concurrencyLimits.ReachableResources, dispatchChunkSize)
110-
lookupResourcesHandler := graph.NewCursoredLookupResources(redispatcher, redispatcher, concurrencyLimits.LookupResources, dispatchChunkSize)
111-
lookupSubjectsHandler := graph.NewConcurrentLookupSubjects(redispatcher, concurrencyLimits.LookupSubjects, dispatchChunkSize)
112-
lookupResourcesHandler2 := graph.NewCursoredLookupResources2(redispatcher, redispatcher, concurrencyLimits.LookupResources, dispatchChunkSize)
119+
reachableResourcesHandler := graph.NewCursoredReachableResources(redispatcher, concurrencyLimits.ReachableResources, chunkSize)
120+
lookupResourcesHandler := graph.NewCursoredLookupResources(redispatcher, redispatcher, concurrencyLimits.LookupResources, chunkSize)
121+
lookupSubjectsHandler := graph.NewConcurrentLookupSubjects(redispatcher, concurrencyLimits.LookupSubjects, chunkSize)
122+
lookupResourcesHandler2 := graph.NewCursoredLookupResources2(redispatcher, redispatcher, concurrencyLimits.LookupResources, chunkSize)
113123

114124
return &localDispatcher{
115125
checker: checker,

internal/services/v1/experimental.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ func NewExperimentalServer(dispatch dispatch.Dispatcher, permServerConfig Permis
7777
config.StreamReadTimeout = streamReadTimeoutFallbackSeconds * time.Second
7878
}
7979

80+
chunkSize := permServerConfig.DispatchChunkSize
81+
if chunkSize == 0 {
82+
log.
83+
Warn().
84+
Msg("experimental server config specified invalid DispatchChunkSize, defaulting to 100")
85+
chunkSize = 100
86+
}
87+
8088
return &experimentalServer{
8189
WithServiceSpecificInterceptors: shared.WithServiceSpecificInterceptors{
8290
Unary: middleware.ChainUnaryServer(
@@ -98,7 +106,7 @@ func NewExperimentalServer(dispatch dispatch.Dispatcher, permServerConfig Permis
98106
maxCaveatContextSize: permServerConfig.MaxCaveatContextSize,
99107
maxConcurrency: config.BulkCheckMaxConcurrency,
100108
dispatch: dispatch,
101-
dispatchChunkSize: permServerConfig.DispatchChunkSize,
109+
dispatchChunkSize: chunkSize,
102110
},
103111
}
104112
}

pkg/genutil/slicez/chunking.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ func ForEachChunk[T any](data []T, chunkSize uint16, handler func(items []T)) {
1414

1515
func ForEachChunkUntil[T any](data []T, chunkSize uint16, handler func(items []T) (bool, error)) (bool, error) {
1616
if chunkSize == 0 {
17-
logging.Warn().Int("invalid-chunk-size", int(chunkSize)).Msg("ForEachChunk got an invalid chunk size; defaulting to 1")
18-
chunkSize = 1
17+
logging.Warn().Int("invalid-chunk-size", int(chunkSize)).Msg("ForEachChunk got an invalid chunk size; defaulting to 100")
18+
chunkSize = 100
1919
}
2020

2121
dataLength := uint64(len(data))

0 commit comments

Comments
 (0)