Documentation
¶
Index ¶
- Constants
- Variables
- func CanonicalRequest(method, path, timestamp, eventID string, body []byte) string
- func Install(ctx ValueStore, service *Service) error
- func Retryable(err error) bool
- func Sign(secret, method, path, timestamp, eventID string, body []byte) string
- func Verify(secret, signature, method, path, timestamp, eventID string, body []byte) bool
- type DecisionRequest
- type DecisionResult
- type DeliveryError
- type Dispatcher
- type DispatcherConfig
- type Disposition
- type Event
- type Finalizer
- type FinalizerFunc
- type FinalizerKey
- type FinalizerRegistry
- type HTTPDeliverer
- type Lease
- type Metrics
- type NackOutcome
- type NotifyCapability
- type QueueConfig
- type QueueDepths
- type RedisQueue
- func (q *RedisQueue) Ack(eventID int64, token string) (bool, error)
- func (q *RedisQueue) Claim(now time.Time, leaseDuration time.Duration) (*Lease, error)
- func (q *RedisQueue) Defer(eventID int64, token string, due time.Time) (bool, error)
- func (q *RedisQueue) Depths() (QueueDepths, error)
- func (q *RedisQueue) Enqueue(event Event, due time.Time) error
- func (q *RedisQueue) Nack(lease Lease, now time.Time, delay time.Duration, maxAttempts int, ...) (NackOutcome, error)
- func (q *RedisQueue) ReclaimExpired(now time.Time, limit int) (int, error)
- func (q *RedisQueue) Renew(eventID int64, token string, now time.Time, leaseDuration time.Duration) (bool, error)
- func (q *RedisQueue) ReplayDLQ(eventID int64, due time.Time) (bool, error)
- type Registry
- func (r *Registry) CanNotify(capability NotifyCapability, actionType string) bool
- func (r *Registry) NotifyProducers() []NotifyCapability
- func (r *Registry) Resolve(senderUID, owner, actionType string) Resolution
- func (r *Registry) ResolveNotifyToken(token string) (NotifyCapability, bool)
- func (r *Registry) Route(senderUID, owner, actionType string) (*Route, bool)
- func (r *Registry) ValidateNotifyTokenExclusions(tokens ...string) error
- type Resolution
- type ResolutionKind
- type Route
- type RouteSpec
- type Service
- func (s *Service) CanNotify(capability NotifyCapability, actionType string) bool
- func (s *Service) Enqueue(event Event) (int64, error)
- func (s *Service) NotifyProducers() []NotifyCapability
- func (s *Service) Resolve(senderUID, owner, actionType string) Resolution
- func (s *Service) ResolveNotifyToken(token string) (NotifyCapability, bool)
- type State
- type ValueStore
Constants ¶
const ( HeaderSignature = "X-Octo-Signature" HeaderTimestamp = "X-Octo-Timestamp" HeaderEventID = "X-Octo-Event-ID" )
const MaxDecisionResponseBytes = 64 << 10
Variables ¶
var ErrServiceAlreadyInstalled = errors.New("cardactiondispatch: service already installed")
Functions ¶
func CanonicalRequest ¶
func Install ¶
func Install(ctx ValueStore, service *Service) error
Types ¶
type DecisionRequest ¶
type DecisionRequest struct {
EventID int64 `json:"event_id,string"`
ActionID string `json:"action_id"`
Decision string `json:"decision"`
OperatorUID string `json:"operator_uid"`
DocID string `json:"doc_id,omitempty"`
RequestID string `json:"request_id,omitempty"`
Inputs map[string]interface{} `json:"inputs"`
Data map[string]interface{} `json:"data,omitempty"`
MessageID string `json:"message_id"`
ChannelID string `json:"channel_id"`
ChannelType uint8 `json:"channel_type"`
SpaceID string `json:"space_id,omitempty"`
ActedAt int64 `json:"acted_at"`
}
func DecisionRequestFromEvent ¶
func DecisionRequestFromEvent(event Event) DecisionRequest
type DecisionResult ¶
type DecisionResult struct {
Disposition Disposition `json:"disposition"`
State State `json:"state"`
RequesterUID string `json:"requester_uid,omitempty"`
Display map[string]string `json:"display,omitempty"`
}
func DecodeDecisionResult ¶
func DecodeDecisionResult(reader io.Reader) (DecisionResult, error)
type DeliveryError ¶
func (*DeliveryError) Error ¶
func (e *DeliveryError) Error() string
func (*DeliveryError) Unwrap ¶
func (e *DeliveryError) Unwrap() error
type Dispatcher ¶
type Dispatcher struct {
// contains filtered or unexported fields
}
func NewDispatcher ¶
func NewDispatcher(queue dispatchQueue, registry *Registry, deliverer callbackDeliverer, finalizer Finalizer, cfg DispatcherConfig) (*Dispatcher, error)
func (*Dispatcher) ProcessOne ¶
ProcessOne claims and completely handles at most one due event. Callback and finalization failures are converted into a durable retry/DLQ transition; an error is returned only when the queue state itself could not be made safe.
func (*Dispatcher) Stop ¶
func (d *Dispatcher) Stop()
func (*Dispatcher) String ¶
func (d *Dispatcher) String() string
type DispatcherConfig ¶
type Disposition ¶
type Disposition string
const ( DispositionApplied Disposition = "applied" DispositionReplayed Disposition = "replayed" DispositionForbidden Disposition = "forbidden" DispositionConflict Disposition = "conflict" DispositionNotFound Disposition = "not_found" )
type Event ¶
type Event struct {
EventID int64 `json:"event_id"`
SenderUID string `json:"sender_uid"`
Owner string `json:"owner"`
ActionType string `json:"action_type"`
MessageID string `json:"message_id"`
ChannelID string `json:"channel_id"`
ChannelType uint8 `json:"channel_type"`
SpaceID string `json:"space_id,omitempty"`
ActionID string `json:"action_id"`
OperatorUID string `json:"operator_uid"`
ClientToken string `json:"client_token,omitempty"`
ActedAt int64 `json:"acted_at"`
Inputs map[string]interface{} `json:"inputs"`
Data map[string]interface{} `json:"data,omitempty"`
}
type Finalizer ¶
type Finalizer interface {
Finalize(ctx context.Context, event Event, result DecisionResult) error
}
type FinalizerFunc ¶
type FinalizerFunc func(context.Context, Event, DecisionResult) error
func (FinalizerFunc) Finalize ¶
func (f FinalizerFunc) Finalize(ctx context.Context, event Event, result DecisionResult) error
type FinalizerKey ¶
FinalizerKey binds a route to an optional specialized terminal renderer. Routes without a binding use the standard approval fallback.
type FinalizerRegistry ¶
type FinalizerRegistry struct {
// contains filtered or unexported fields
}
FinalizerRegistry keeps custom terminal visuals explicit while preserving config-only onboarding for standard approval consumers.
func NewFinalizerRegistry ¶
func NewFinalizerRegistry(fallback Finalizer, bindings map[FinalizerKey]Finalizer) (*FinalizerRegistry, error)
func (*FinalizerRegistry) Finalize ¶
func (r *FinalizerRegistry) Finalize(ctx context.Context, event Event, result DecisionResult) error
type HTTPDeliverer ¶
type HTTPDeliverer struct {
// contains filtered or unexported fields
}
func NewHTTPDeliverer ¶
func NewHTTPDeliverer(transport http.RoundTripper, clock func() time.Time) *HTTPDeliverer
func (*HTTPDeliverer) Deliver ¶
func (d *HTTPDeliverer) Deliver(ctx context.Context, route *Route, request DecisionRequest) (DecisionResult, error)
type Metrics ¶
type Metrics struct {
// contains filtered or unexported fields
}
func NewMetrics ¶
func NewMetrics(reg prometheus.Registerer) *Metrics
type NackOutcome ¶
type NackOutcome string
const ( NackRequeued NackOutcome = "requeued" NackDeadLettered NackOutcome = "dead_lettered" NackTokenMismatch NackOutcome = "token_mismatch" )
type NotifyCapability ¶
NotifyCapability is the server-authoritative identity granted to one first-party notification caller. The bearer token never supplies owner or sender metadata; it resolves to this value at the ingress boundary.
type QueueConfig ¶
type QueueDepths ¶
type RedisQueue ¶
type RedisQueue struct {
// contains filtered or unexported fields
}
func NewRedisQueue ¶
func NewRedisQueue(client *rd.Client, cfg QueueConfig) (*RedisQueue, error)
func (*RedisQueue) Defer ¶
Defer returns a capacity-blocked lease to ready without consuming a delivery attempt. The lease token and leased-set membership are checked atomically, so a stale worker cannot move a lease owned by another replica.
func (*RedisQueue) Depths ¶
func (q *RedisQueue) Depths() (QueueDepths, error)
func (*RedisQueue) Nack ¶
func (q *RedisQueue) Nack(lease Lease, now time.Time, delay time.Duration, maxAttempts int, reason string) (NackOutcome, error)
func (*RedisQueue) ReclaimExpired ¶
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
func NewRegistry ¶
func (*Registry) CanNotify ¶
func (r *Registry) CanNotify(capability NotifyCapability, actionType string) bool
CanNotify keeps a capability scoped to only the action types that explicitly declare its notify_token_env. A token for one owner cannot mint another owner's card or access a callback-only route.
func (*Registry) NotifyProducers ¶
func (r *Registry) NotifyProducers() []NotifyCapability
func (*Registry) Resolve ¶
func (r *Registry) Resolve(senderUID, owner, actionType string) Resolution
func (*Registry) ResolveNotifyToken ¶
func (r *Registry) ResolveNotifyToken(token string) (NotifyCapability, bool)
ResolveNotifyToken performs a constant-time comparison against every configured first-party notification capability. Tokens are unique across capabilities, so at most one result can match.
func (*Registry) ValidateNotifyTokenExclusions ¶
ValidateNotifyTokenExclusions prevents a route-scoped approval token from accidentally inheriting a broader legacy/docs notify capability.
type Resolution ¶
type Resolution struct {
Kind ResolutionKind
Route *Route
}
type ResolutionKind ¶
type ResolutionKind string
const ( ResolutionCallback ResolutionKind = "callback" ResolutionBotPull ResolutionKind = "bot_pull" ResolutionReject ResolutionKind = "reject" )
type RouteSpec ¶
type RouteSpec struct {
SenderUID string
Owner string
ActionType string
URL string
SecretEnv string
NotifyTokenEnv string
Timeout time.Duration
MaxAttempts int
BaseBackoff time.Duration
MaxBackoff time.Duration
MaxInFlight int
}
func LoadRouteSpecs ¶
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func FromContext ¶
func FromContext(ctx ValueStore) (*Service, bool)
func NewService ¶
func (*Service) CanNotify ¶
func (s *Service) CanNotify(capability NotifyCapability, actionType string) bool
func (*Service) NotifyProducers ¶
func (s *Service) NotifyProducers() []NotifyCapability
func (*Service) Resolve ¶
func (s *Service) Resolve(senderUID, owner, actionType string) Resolution
func (*Service) ResolveNotifyToken ¶
func (s *Service) ResolveNotifyToken(token string) (NotifyCapability, bool)