Documentation
¶
Overview ¶
Package rpc serves the grant protocol (api/grant/v1) over gRPC on top of a core.Core, and optionally exposes a thin JSON gateway. It owns the mapping from core.StatusCode to gRPC codes and Miss details; the core stays transport-agnostic.
Index ¶
- Constants
- func AdmissionInterceptor() grpc.UnaryServerInterceptor
- func AdmissionStreamInterceptor() grpc.StreamServerInterceptor
- func CallerFrom(ctx context.Context) (tlsconf.Caller, bool)
- func CallerInterceptor() grpc.UnaryServerInterceptor
- func CallerStreamInterceptor() grpc.StreamServerInterceptor
- func ConnContext(ctx context.Context, _ net.Conn) context.Context
- func FenceFromProto(f *grantv1.Fence) core.Fence
- func HealthFunc(epoch func() uint64, health *core.SourceHealth, tier core.Tier, ...) func() map[string]any
- func IsMiss(err error) bool
- func IsNoWorkspace(err error) bool
- func MissFromError(err error) (*grantv1.Miss, bool)
- func NewGRPCServer(s *Server, opts ...grpc.ServerOption) *grpc.Server
- func RejectUnknown(m protoreflect.Message) error
- func ServerCreds(cfg *tls.Config) credentials.TransportCredentials
- func StatusToProto(st core.Status) *grantv1.Status
- func WithCaller(ctx context.Context, c tlsconf.Caller) context.Context
- func WithDraining(health func() map[string]any, draining func() bool) func() map[string]any
- func WriteHealth(w http.ResponseWriter, body map[string]any)
- type Gateway
- type Server
- func (s *Server) Clone(ctx context.Context, req *grantv1.CloneRequest) (*grantv1.CloneResponse, error)
- func (s *Server) Discard(ctx context.Context, req *grantv1.DiscardRequest) (*emptypb.Empty, error)
- func (s *Server) Download(req *grantv1.DownloadRequest, stream grantv1.Fibers_DownloadServer) error
- func (s *Server) ListFiles(ctx context.Context, req *grantv1.ListFilesRequest) (*grantv1.ListFilesResponse, error)
- func (s *Server) Park(ctx context.Context, req *grantv1.ParkRequest) (*emptypb.Empty, error)
- func (s *Server) Release(ctx context.Context, req *grantv1.ReleaseRequest) (*emptypb.Empty, error)
- func (s *Server) ToError(code core.StatusCode, err error) error
- func (s *Server) Upload(stream grantv1.Fibers_UploadServer) error
- func (s *Server) Watch(_ *emptypb.Empty, stream grantv1.Fibers_WatchServer) error
Constants ¶
const DefaultRetryAfter = time.Second
DefaultRetryAfter is what SHED tells the caller to wait.
const MaxChunk = 1 << 20
MaxChunk is the most data one Upload or Download message carries, well under gRPC's 4 MiB message limit.
Variables ¶
This section is empty.
Functions ¶
func AdmissionInterceptor ¶
func AdmissionInterceptor() grpc.UnaryServerInterceptor
AdmissionInterceptor enforces admission completeness on the wire: a request carrying any field the schema does not define is rejected with InvalidArgument. Protobuf keeps unknown fields on decode instead of dropping them, so "the request struct has no field to bind it to" is a checkable property, not a silent one.
func AdmissionStreamInterceptor ¶
func AdmissionStreamInterceptor() grpc.StreamServerInterceptor
AdmissionStreamInterceptor is AdmissionInterceptor for streaming calls. It checks every message the client sends, not only the first, so a later Upload chunk cannot carry an undefined field either.
func CallerFrom ¶
CallerFrom is the verified caller of the request. ok is false on a plaintext listener, where there is no caller identity.
func CallerInterceptor ¶
func CallerInterceptor() grpc.UnaryServerInterceptor
CallerInterceptor puts the TLS peer's identity on every unary call's context. A peer whose certificate cannot name it is Unauthenticated.
func CallerStreamInterceptor ¶
func CallerStreamInterceptor() grpc.StreamServerInterceptor
CallerStreamInterceptor is CallerInterceptor for streaming calls.
func ConnContext ¶
ConnContext is the http.Server.ConnContext hook of a server that serves a Gateway. With it the gateway names a connection's peer once. A handler served without it names the peer on every request.
func FenceFromProto ¶
FenceFromProto is the inverse of the fence mapping, for clients.
func HealthFunc ¶
func HealthFunc(epoch func() uint64, health *core.SourceHealth, tier core.Tier, audit func() error) func() map[string]any
HealthFunc builds the standard /healthz body. It holds the epoch, the advertised tier, whether the issuer is reachable and the audit spool's state. An idle issuer is not down, only a stale one is. audit is "ok" or "poisoned". The fsync error is logged when it happens and never put in the body, which the gateway serves without authentication, since it names the spool's path. A nil health or audit omits its key.
func IsNoWorkspace ¶
IsNoWorkspace reports whether err is the refusal of a file call on a fiber whose grant has no workspace.
func MissFromError ¶
MissFromError extracts the Miss detail from a gRPC error, for clients and the conformance suite.
func NewGRPCServer ¶
func NewGRPCServer(s *Server, opts ...grpc.ServerOption) *grpc.Server
NewGRPCServer builds a grpc.Server with the caller and admission interceptors and the Fibers service registered. Pass grpc.Creds(rpc.ServerCreds(cfg)) for mutual TLS, so each connection's caller is named once at its handshake.
func RejectUnknown ¶
func RejectUnknown(m protoreflect.Message) error
RejectUnknown walks the message and every nested message and fails on the first unknown field found.
func ServerCreds ¶
func ServerCreds(cfg *tls.Config) credentials.TransportCredentials
ServerCreds are the TLS credentials of a server that names its callers. A connection's peer is named once, at its handshake, and the caller interceptors read that name on every call. The auth info of such a connection embeds credentials.TLSInfo and is not that type, so code that asserts credentials.TLSInfo does not match it.
func StatusToProto ¶
StatusToProto converts a ledger status to the wire message.
func WithCaller ¶
WithCaller records the verified caller on ctx.
func WithDraining ¶
WithDraining adds "draining": true to what health returns while draining reports true, for a readiness check. WriteHealth answers that body with 503, so a readiness probe takes the home out of its endpoints while it parks its sessions before it stops. A liveness check keeps health unwrapped, since a 503 there means restart fiberd.
func WriteHealth ¶
func WriteHealth(w http.ResponseWriter, body map[string]any)
WriteHealth writes a /healthz body. The status is 503 when the audit spool is poisoned, because every Sync operation fails until fiberd restarts. A probe that sees it restarts the home or drains it. A readiness body from WithDraining is 503 too while fiberd drains before it stops. An unreachable issuer stays 200, since fiberd fences it and recovers on its own.
Types ¶
type Gateway ¶
type Gateway struct {
Server *Server
// Health is served at GET /healthz for readiness polling, with the
// status WriteHealth picks.
Health func() map[string]any
}
Gateway is the thin JSON-over-HTTP face of the same service, mounted only when fiberd is started with -http. Requests are protobuf JSON (protojson) of the same messages; unknown fields are rejected exactly as on gRPC. Errors are the google.rpc.Status JSON with the Miss detail embedded, and the HTTP code follows the gRPC code.
type Server ¶
type Server struct {
grantv1.UnimplementedFibersServer
Core *core.Core
// Issuer is reported in every Miss so a DEFERRED caller knows which
// control plane to fall back through.
Issuer string
RetryAfter time.Duration
}
Server implements grantv1.FibersServer.
func (*Server) Clone ¶
func (s *Server) Clone(ctx context.Context, req *grantv1.CloneRequest) (*grantv1.CloneResponse, error)
func (*Server) Discard ¶
Discard deletes a parked session by name. Like Clone it carries the grant, so the caller is checked against the grant's binding from the TLS peer, not through owns. Another tenant's session is not filed under this grant's tenant, so it answers NotFound.
func (*Server) Download ¶
func (s *Server) Download(req *grantv1.DownloadRequest, stream grantv1.Fibers_DownloadServer) error
Download reads one regular file from a fiber's workspace. The first chunk carries the file's info, and every chunk at most MaxChunk bytes.
func (*Server) ListFiles ¶
func (s *Server) ListFiles(ctx context.Context, req *grantv1.ListFilesRequest) (*grantv1.ListFilesResponse, error)
ListFiles lists one directory of a fiber's workspace. An empty dir is the workspace itself.
func (*Server) Park ¶
Park and Release answer NotFound, never PermissionDenied, for another caller's fiber, so a fiber ID reveals nothing about who holds it.
func (*Server) ToError ¶
func (s *Server) ToError(code core.StatusCode, err error) error
Miss policy: every miss carries a grantv1.Miss detail. Never a bare code.
core.Shed -> ResourceExhausted + Miss{SHED, retry_after_s}
core.DeferredFallback -> Unavailable + Miss{DEFERRED_FALLBACK, issuer}
core.NeedsTier -> FailedPrecondition
core.Invalid -> InvalidArgument (ErrAnonymousPark, ErrSessionRunning)
core.Unauthenticated -> Unauthenticated
core.NotFound -> NotFound (ErrFiberUnknown, ErrSessionUnknown)
core.NoWorkspace -> FailedPrecondition + NoWorkspace
core.OverBudget -> ResourceExhausted, no Miss
core.Internal -> Internal
func (*Server) Upload ¶
func (s *Server) Upload(stream grantv1.Fibers_UploadServer) error
Upload writes one file into a fiber's workspace. The first message is the header, which declares the size, so an oversize file is refused before any data is read. Every later message is a chunk of at most MaxChunk bytes, and the chunks add up to the declared size. The file appears only once every byte and the optional sha256 checked out.