Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DrainSignal ¶
type DrainSignal struct {
// contains filtered or unexported fields
}
drain.go — framework-side gRPC drain signal (GAP-1 PR-10 [#1153]).
DrainSignal is a one-shot, idempotent shutdown signal shared between the adapters/grpc.Server (producer: Trigger at GracefulStop start) and the gRPC stream interceptor chain (consumer: StreamDrain binds each in-flight stream's context to Context()). grpc-go's GracefulStop only *waits* for in-flight streams — it never cancels their handler contexts — so a long-lived server-stream that ignores shutdown blocks until the hard-stop deadline. The DrainSignal closes that gap: Trigger cancels Context(), every active stream's ctx.Done() fires, handlers that select on it return promptly, and GracefulStop completes within budget.
The composition root constructs ONE DrainSignal inside interceptor.Deps; the adapter derives both the stream chain and graceful-stop trigger from that same deps object. This follows the same Option-3 instance-sharing discipline as the shared ServiceRegistrar (#1152): a missing signal is a composition bug and fails closed at startup.
func NewDrainSignal ¶
func NewDrainSignal() *DrainSignal
NewDrainSignal returns a fresh, un-triggered DrainSignal. This is the ONLY way to obtain a usable value: the type is exported (it is a Config/Deps field), so a zero-value new(DrainSignal) / DrainSignal{} IS constructable outside this package, but its fields are nil — Trigger/Context would panic. Validate (called by adapters/grpc Config.validate and NewStreamChain) rejects such a value at startup.
func (*DrainSignal) Context ¶
func (d *DrainSignal) Context() context.Context
Context returns a context canceled (with context.Canceled) the first time Trigger is called. StreamDrain derives each stream's handler context from it so drain propagates as ordinary ctx cancellation. It is never nil for a value built by NewDrainSignal (a zero-value is rejected by Validate before use).
func (*DrainSignal) Trigger ¶
func (d *DrainSignal) Trigger()
Trigger cancels Context(). It is idempotent and safe for concurrent use: the adapter calls it once at GracefulStop start, and any further call is a harmless no-op (context.CancelFunc is itself idempotent).
func (*DrainSignal) Validate ¶
func (d *DrainSignal) Validate() error
Validate reports whether d is a usable signal built by NewDrainSignal. It is nil-receiver safe. A nil pointer or a zero-value (new(DrainSignal)) has a nil cancel/ctx and would panic at Trigger()/Context(); adapters/grpc Config.validate and NewStreamChain call Validate so a non-constructed signal fails fast at startup rather than at GracefulStop. The sealed-construction Hard upgrade (forbidding a zero-value at compile time) is tracked with #1752.
type ServerInterceptors ¶
type ServerInterceptors struct {
// contains filtered or unexported fields
}
ServerInterceptors is the adapter-consumable gRPC interceptor bundle.
It deliberately lives in runtime/grpc, not adapters/grpc, so adapters/grpc does not import runtime/grpc/interceptor (GRPC-ADAPTER-LAYER-01). The normal constructor is interceptor.NewServerInterceptors(deps), which fixes the bundle to the unary + stream chains built from one deps value.
func NewServerInterceptorsBundle ¶
func NewServerInterceptorsBundle( options []grpc.ServerOption, registrar *ServiceRegistrar, drain *DrainSignal, ) ServerInterceptors
NewServerInterceptorsBundle packages pre-built server options with the shared registrar and drain signal. It is intentionally low-level: composition roots should call interceptor.NewServerInterceptors(deps), which supplies the full unary + stream chain pair from one deps object.
func (ServerInterceptors) Drain ¶
func (b ServerInterceptors) Drain() *DrainSignal
Drain returns the shared graceful-stop drain signal.
func (ServerInterceptors) Registrar ¶
func (b ServerInterceptors) Registrar() *ServiceRegistrar
Registrar returns the shared method attribution registrar.
func (ServerInterceptors) ServerOptions ¶
func (b ServerInterceptors) ServerOptions() []grpc.ServerOption
ServerOptions returns a defensive copy of the bundled grpc.ServerOptions.
func (ServerInterceptors) Validate ¶
func (b ServerInterceptors) Validate() error
Validate reports whether b has enough state for adapters/grpc.New to build a server without silently dropping attribution, auth, or stream drain.
type ServiceRegistrar ¶
type ServiceRegistrar struct {
// contains filtered or unexported fields
}
ServiceRegistrar is the cell-facing gRPC service registration seam. It is constructed by adapters/grpc.Server.Registrar() and handed to bootstrap which calls Register(spec) for each GRPCServiceSpec drained from the cell snapshot. The grpc.ServiceRegistrar interface is NOT exported — the only entry point is Register(spec), which routes through the attribution-aware cellScopedRegistrar interceptor.
All public methods are safe for concurrent use after construction.
func NewServiceRegistrar ¶
func NewServiceRegistrar() *ServiceRegistrar
NewServiceRegistrar builds a ServiceRegistrar with an empty attribution map and no delegation target (two-phase, Option 3 #1152). The composition root creates it FIRST so reg.CellIDForMethod can be handed to the unary interceptor chain — which is composed BEFORE the gRPC server exists — and binds the delegation target via BindServer once grpc.NewServer has been constructed with that chain. CellIDForMethod is callable immediately (the map exists from construction); it returns matches once Register has populated it during the bootstrap drain.
func (*ServiceRegistrar) BindServer ¶
func (r *ServiceRegistrar) BindServer(inner grpc.ServiceRegistrar)
BindServer sets the delegation target (typically *grpc.Server) that Register forwards RegisterService calls to. It must be called exactly once, during adapter construction, before any Register call (the bootstrap drain runs in phase7b, after New returns). inner must not be nil and BindServer must not be called twice — both are B-class programmer errors raised via panicregister.Approved.
func (*ServiceRegistrar) CellIDForMethod ¶
func (r *ServiceRegistrar) CellIDForMethod(fullMethod string) (string, bool)
CellIDForMethod returns the cellID attributed to fullMethod (e.g. "/grpc.health.v1.Health/Check"). The second return value is false when the method has not been registered via Register. Safe for concurrent use.
func (*ServiceRegistrar) Register ¶
func (r *ServiceRegistrar) Register(spec cell.GRPCServiceSpec) error
Register invokes the spec.Register callback via an attribution-aware, single-use cellScopedRegistrar interceptor, then records every method/stream exposed by the registered service under spec.CellID.
This implementation always returns nil; every contract violation panics via panicregister.Approved (B-class programmer / config error, fail-fast at startup — the drain runs in phase7b before any RPC is served):
- spec.Register is not a func(grpc.ServiceRegistrar): panicregister.Approved("grpc-registrar-bad-register-fn", …).
- spec.Register is a typed-nil callback (a nil func(grpc.ServiceRegistrar) boxed in any — passes kernel's bare-nil Validate but is uninvokable): panicregister.Approved("grpc-registrar-nil-register-fn", …).
- the callback does not register exactly one service (zero = silently unserved spec; >1 = a single spec smuggling multiple services): panicregister.Approved("grpc-registrar-service-count", …).
- the callback registers a ServiceName already owned by another spec (cross-cell collision): panicregister.Approved("grpc-registrar-dup-service", …) before grpc-go's own fatal — with first/current owner context.
- the cellScopedRegistrar is retained and used after the callback returns (escaped scope — would let registration leak past Serve): panicregister.Approved("grpc-registrar-escaped-scope", …).
Register must be called before grpcServer.Serve (enforced by the drain ordering: bootstrap calls Register in phase7b before grpcServeAll). The scope is closed once the callback returns so a retained registrar cannot register after Serve.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package interceptor provides the gRPC unary and streaming server interceptor chains that align the gRPC transport with the existing HTTP middleware stack (runtime/http/middleware): RequestID, CellAttribution, Tracing, AccessLog, Metrics, Auth, and Recovery.
|
Package interceptor provides the gRPC unary and streaming server interceptor chains that align the gRPC transport with the existing HTTP middleware stack (runtime/http/middleware): RequestID, CellAttribution, Tracing, AccessLog, Metrics, Auth, and Recovery. |