Documentation
¶
Index ¶
- type Authorizer
- type ConsumerConnection
- type DequeueParams
- type DequeueResult
- type Handler
- type LeaseBatchResult
- type OpError
- type Queue
- type Server
- func (s *Server) AckBatch(q Queue, leaseIDs []string) (LeaseBatchResult, *OpError)
- func (s *Server) AckSingle(q Queue, leaseID string) *OpError
- func (s *Server) Consumers() []ConsumerConnection
- func (s *Server) Dequeue(ctx context.Context, q Queue, params DequeueParams) (DequeueResult, *OpError)
- func (s *Server) Extend(q Queue, leaseID string, extendBy time.Duration) *OpError
- func (s *Server) NackBatch(q Queue, leaseIDs []string, dead bool, reason string, delay time.Duration) (LeaseBatchResult, *OpError)
- func (s *Server) NackSingle(q Queue, leaseID string, dead bool, reason string, delay time.Duration) *OpError
- func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
- type TokenIdentifier
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Authorizer ¶
func BearerTokenAuthorizer ¶
func BearerTokenAuthorizer(tokens [][]byte) Authorizer
type ConsumerConnection ¶ added in v2.13.0
type ConsumerConnection struct {
ID string
Route string
ConsumerGroup string
Endpoint string
RemoteAddr string
UserAgent string
TokenRef string
ConnectedAt time.Time
MessagesSent int64
LastMessageAt time.Time
}
ConsumerConnection describes one pull consumer that currently holds an open SSE stream.
The connection gauge (`hookaido_pull_sse_connection_active`) answers how many consumers are attached; this answers which. That distinction matters because an unexpected second consumer on a route is not a visible failure: the queue is competing-consumer, so the two split the traffic and each of them observes a fluctuating fraction of the events arriving, which is indistinguishable from delivery loss from the inside. The count says there is a problem; the identity is what turns it into a fix.
TokenRef names the configured secret reference the request authenticated with (`env.PULL_TOKEN`, `file./run/secrets/pull`), never the token value. It is empty when the Pull API runs without tokens, and it is deliberately the reference rather than a hash: an operator can map it back to a Hookaidofile line, which is what they need in order to decide whose credential is in use.
type DequeueParams ¶
type DequeueParams struct {
Batch int
MaxWait time.Duration
HasMaxWait bool
LeaseTTL time.Duration
HasLeaseTTL bool
}
DequeueParams captures normalized dequeue input for route-bound operations.
type DequeueResult ¶
DequeueResult is the route-bound dequeue output.
type LeaseBatchResult ¶
type LeaseBatchResult struct {
Succeeded int
Conflicts []queue.LeaseBatchConflict
}
LeaseBatchResult captures aggregate lease mutation output.
type Queue ¶ added in v2.13.0
Queue is the queue one pull endpoint reads from.
A pull endpoint used to be identified by its route alone, because a route had exactly one queue and every envelope in it carried the literal target `pull`. Consumer groups break that: a route with groups fans out to one independent queue per group, so the route no longer says which messages an endpoint is entitled to — the target does.
ConsumerGroup is empty for an ungrouped route and carries the group name otherwise. It exists next to Target rather than being parsed back out of it so that metrics and the consumer registry can label by group without re-deriving it from a string prefix.
type Server ¶
type Server struct {
Store queue.Store
// Target is the queue target used when ResolveQueue is not wired. The
// runtime always wires it; this keeps a bare Server usable.
Target string
// ResolveQueue maps a pull endpoint path to the queue it reads from. It
// replaces a plain endpoint-to-route lookup because a route with consumer
// groups serves several endpoints, one per independent queue.
ResolveQueue func(endpoint string) (Queue, bool)
Authorize Authorizer
ObserveDequeue func(q Queue, statusCode int, items []queue.Envelope)
ObserveAck func(q Queue, statusCode int, leaseID string, leaseExpired bool)
ObserveNack func(q Queue, statusCode int, leaseID string, leaseExpired bool)
ObserveExtend func(q Queue, statusCode int, leaseID string, extendBy time.Duration, leaseExpired bool)
DefaultLeaseTTL time.Duration
MaxBatch int
MaxLeaseBatch int
MaxLeaseTTL time.Duration
DefaultMaxWait time.Duration
MaxWait time.Duration
SSEKeepalive time.Duration
SSEMaxConnection time.Duration
ObserveSSEConnect func(q Queue)
ObserveSSEDisconnect func(q Queue, statusCode int, messagesSent int, duration time.Duration)
// IdentifyToken names the configured secret reference a request
// authenticated with, for the consumer registry below. It never returns the
// token value. Optional: without it consumers are listed without a
// credential.
IdentifyToken TokenIdentifier
// ObserveConsumerConnect and ObserveConsumerDisconnect report SSE stream
// lifecycle so the runtime can log it. They exist next to the SSE metric
// observers because a counter and an identity answer different questions:
// the gauge says two consumers are attached, these say which two, and the
// disconnect is the half that a plain `http_request` access-log line for
// the establishing GET can never provide.
ObserveConsumerConnect func(c ConsumerConnection)
ObserveConsumerDisconnect func(c ConsumerConnection, statusCode int, duration time.Duration)
// LeaseRouteScoped reports whether the running config uses per-route pull
// credentials. When it does, lease operations are checked against the route
// they were issued for; when it does not, every client is authorized for
// every route anyway and the check is skipped. See lease_scope.go.
LeaseRouteScoped func() bool
RecentLeaseOpTTL time.Duration
RecentLeaseOpCap int
// contains filtered or unexported fields
}
func (*Server) AckBatch ¶
func (s *Server) AckBatch(q Queue, leaseIDs []string) (LeaseBatchResult, *OpError)
func (*Server) Consumers ¶ added in v2.13.0
func (s *Server) Consumers() []ConsumerConnection
Consumers returns the pull consumers with an open SSE stream right now, ordered by route and then by how long they have been connected.
Only SSE streams appear here. A consumer that polls `POST .../dequeue` holds no connection between calls, so there is nothing to list and nothing the connection gauge counts either.
func (*Server) Dequeue ¶
func (s *Server) Dequeue(ctx context.Context, q Queue, params DequeueParams) (DequeueResult, *OpError)
Dequeue takes ctx so a long poll ends when the caller does. Without it a worker that timed out left the handler blocked inside the store for the rest of max_wait, and items arriving meanwhile were leased into a connection that no longer existed -- invisible for the whole lease TTL, until the expiry sweep reclaimed them.
func (*Server) NackSingle ¶
type TokenIdentifier ¶ added in v2.13.0
TokenIdentifier names the configured token reference a request authenticated with — never the token value. See BearerTokenIdentifier.
func BearerTokenIdentifier ¶ added in v2.13.0
func BearerTokenIdentifier(refs []string, tokens [][]byte) TokenIdentifier
BearerTokenIdentifier names which configured token reference a request authenticated with, for the consumer registry.
refs and tokens are index-aligned as the config resolves them; a ref without a token, or a token past the end of refs, is skipped rather than reported under the wrong name. The return value is the reference (`env.PULL_TOKEN`), never the secret — an operator needs to map an unexpected consumer back to a Hookaidofile line, and a token value in an Admin API response or a log line would be a credential leak by way of a diagnostic.
It returns "" when nothing matches, including when the Pull API runs without tokens at all. That is not an authorization decision: the authorizer above has already made it by the time this is consulted.