github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/dispatch/cluster/cluster.go (about) 1 package cluster 2 3 import ( 4 "time" 5 6 "github.com/authzed/spicedb/internal/dispatch" 7 "github.com/authzed/spicedb/internal/dispatch/caching" 8 "github.com/authzed/spicedb/internal/dispatch/graph" 9 "github.com/authzed/spicedb/internal/dispatch/keys" 10 "github.com/authzed/spicedb/pkg/cache" 11 ) 12 13 // Option is a function-style option for configuring a combined Dispatcher. 14 type Option func(*optionState) 15 16 type optionState struct { 17 metricsEnabled bool 18 prometheusSubsystem string 19 cache cache.Cache 20 concurrencyLimits graph.ConcurrencyLimits 21 remoteDispatchTimeout time.Duration 22 } 23 24 // MetricsEnabled enables issuing prometheus metrics 25 func MetricsEnabled(enabled bool) Option { 26 return func(state *optionState) { 27 state.metricsEnabled = enabled 28 } 29 } 30 31 // PrometheusSubsystem sets the subsystem name for the prometheus metrics 32 func PrometheusSubsystem(name string) Option { 33 return func(state *optionState) { 34 state.prometheusSubsystem = name 35 } 36 } 37 38 // Cache sets the cache for the remote dispatcher. 39 func Cache(c cache.Cache) Option { 40 return func(state *optionState) { 41 state.cache = c 42 } 43 } 44 45 // ConcurrencyLimits sets the max number of goroutines per operation 46 func ConcurrencyLimits(limits graph.ConcurrencyLimits) Option { 47 return func(state *optionState) { 48 state.concurrencyLimits = limits 49 } 50 } 51 52 // RemoteDispatchTimeout sets the maximum timeout for a remote dispatch. 53 // Defaults to 60s (as defined in the remote dispatcher). 54 func RemoteDispatchTimeout(remoteDispatchTimeout time.Duration) Option { 55 return func(state *optionState) { 56 state.remoteDispatchTimeout = remoteDispatchTimeout 57 } 58 } 59 60 // NewClusterDispatcher takes a dispatcher (such as one created by 61 // combined.NewDispatcher) and returns a cluster dispatcher suitable for use as 62 // the dispatcher for the dispatch grpc server. 63 func NewClusterDispatcher(dispatch dispatch.Dispatcher, options ...Option) (dispatch.Dispatcher, error) { 64 var opts optionState 65 for _, fn := range options { 66 fn(&opts) 67 } 68 69 clusterDispatch := graph.NewDispatcher(dispatch, opts.concurrencyLimits) 70 71 if opts.prometheusSubsystem == "" { 72 opts.prometheusSubsystem = "dispatch" 73 } 74 75 cachingClusterDispatch, err := caching.NewCachingDispatcher(opts.cache, opts.metricsEnabled, opts.prometheusSubsystem, &keys.CanonicalKeyHandler{}) 76 if err != nil { 77 return nil, err 78 } 79 cachingClusterDispatch.SetDelegate(clusterDispatch) 80 return cachingClusterDispatch, nil 81 }