github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/dispatch/dispatch.go (about) 1 package dispatch 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/rs/zerolog" 8 9 log "github.com/authzed/spicedb/internal/logging" 10 v1 "github.com/authzed/spicedb/pkg/proto/dispatch/v1" 11 ) 12 13 // ReadyState represents the ready state of the dispatcher. 14 type ReadyState struct { 15 // Message is a human-readable status message for the current state. 16 Message string 17 18 // IsReady indicates whether the datastore is ready. 19 IsReady bool 20 } 21 22 // Dispatcher interface describes a method for passing subchecks off to additional machines. 23 type Dispatcher interface { 24 Check 25 Expand 26 ReachableResources 27 LookupResources 28 LookupSubjects 29 30 // Close closes the dispatcher. 31 Close() error 32 33 // ReadyState returns true when dispatcher is able to respond to requests 34 ReadyState() ReadyState 35 } 36 37 // Check interface describes just the methods required to dispatch check requests. 38 type Check interface { 39 // DispatchCheck submits a single check request and returns its result. 40 DispatchCheck(ctx context.Context, req *v1.DispatchCheckRequest) (*v1.DispatchCheckResponse, error) 41 } 42 43 // Expand interface describes just the methods required to dispatch expand requests. 44 type Expand interface { 45 // DispatchExpand submits a single expand request and returns its result. 46 DispatchExpand(ctx context.Context, req *v1.DispatchExpandRequest) (*v1.DispatchExpandResponse, error) 47 } 48 49 // ReachableResourcesStream is an alias for the stream to which reachable resources will be written. 50 type ReachableResourcesStream = Stream[*v1.DispatchReachableResourcesResponse] 51 52 // ReachableResources interface describes just the methods required to dispatch reachable resources requests. 53 type ReachableResources interface { 54 // DispatchReachableResources submits a single reachable resources request, writing its results to the specified stream. 55 DispatchReachableResources( 56 req *v1.DispatchReachableResourcesRequest, 57 stream ReachableResourcesStream, 58 ) error 59 } 60 61 // LookupResourcesStream is an alias for the stream to which found resources will be written. 62 type LookupResourcesStream = Stream[*v1.DispatchLookupResourcesResponse] 63 64 // LookupResources interface describes just the methods required to dispatch LookupResources requests. 65 type LookupResources interface { 66 // DispatchLookupResources submits a single lookup request and returns its result. 67 DispatchLookupResources( 68 req *v1.DispatchLookupResourcesRequest, 69 stream LookupResourcesStream, 70 ) error 71 } 72 73 // LookupSubjectsStream is an alias for the stream to which found subjects will be written. 74 type LookupSubjectsStream = Stream[*v1.DispatchLookupSubjectsResponse] 75 76 // LookupSubjects interface describes just the methods required to dispatch lookup subjects requests. 77 type LookupSubjects interface { 78 // DispatchLookupSubjects submits a single lookup subjects request, writing its results to the specified stream. 79 DispatchLookupSubjects( 80 req *v1.DispatchLookupSubjectsRequest, 81 stream LookupSubjectsStream, 82 ) error 83 } 84 85 // DispatchableRequest is an interface for requests. 86 type DispatchableRequest interface { 87 zerolog.LogObjectMarshaler 88 89 GetMetadata() *v1.ResolverMeta 90 } 91 92 // CheckDepth returns ErrMaxDepth if there is insufficient depth remaining to dispatch. 93 func CheckDepth(ctx context.Context, req DispatchableRequest) error { 94 metadata := req.GetMetadata() 95 if metadata == nil { 96 log.Ctx(ctx).Warn().Object("request", req).Msg("request missing metadata") 97 return fmt.Errorf("request missing metadata") 98 } 99 100 if metadata.DepthRemaining == 0 { 101 return NewMaxDepthExceededError(req) 102 } 103 104 return nil 105 } 106 107 // AddResponseMetadata adds the metadata found in the incoming metadata to the existing 108 // metadata, *modifying it in place*. 109 func AddResponseMetadata(existing *v1.ResponseMeta, incoming *v1.ResponseMeta) { 110 existing.DispatchCount += incoming.DispatchCount 111 existing.CachedDispatchCount += incoming.CachedDispatchCount 112 existing.DepthRequired = max(existing.DepthRequired, incoming.DepthRequired) 113 }