Skip to content

feat!(sdk): replace serve_service with a builder - #3

Closed
jonasz-lasut wants to merge 1 commit into
mainfrom
feat/serve-customized
Closed

jonasz-lasut wants to merge 1 commit into
mainfrom
feat/serve-customized

Conversation

@jonasz-lasut

Copy link
Copy Markdown
Collaborator

What

Replaces serve_service (#1, unreleased) with a builder, leaving two entry points:

  • serve(function, args) - the default function server, unchanged behavior.
  • serve_customized(args) - a ServerBuilder composing the server from the components you need, in the spirit of function-sdk-go's options:
    • .function(f) - the generated typed FunctionRunnerService server (honors --max-recv-message-size),
    • .service(s) - any tonic Service + NamedService: the function behind a custom codec (a transparent proxy that must forward request bytes verbatim, which prost's generated codec cannot do), an instrumented wrapper, or further services beside the function,
    • .file_descriptor_set(bytes) - reflection descriptors for added services, next to this crate's own,
    • .health_reporter() - hands the gRPC HealthReporter to the caller, who then owns every status (set NOT_SERVING before start-up work, flip to serving when ready); without it, every added service is reported serving when serving starts,
    • .serve() - listens and serves until SIGTERM/SIGINT.

The transport is identical to serve in every configuration: mTLS from --tls-certs-dir unless --insecure, v1+v1alpha reflection, the health service, graceful shutdown. HealthReporter is re-exported so callers need no tonic-health dependency.

Why

Supersedes #2: a pair of ever-more-specific free functions (serve_service, serve_service_with_health, ...) scales poorly as one-off combinations appear; a builder makes the combinations compositional - custom codec and caller-owned health and an extra service is one chain, not a fourth function. Since 0.3.0 has not shipped, serve_service is removed rather than deprecated.

The health handle exists because a function doing start-up work (warming caches, compiling wasm) should listen immediately and let probes read NOT_SERVING while it warms: a closed port reads as a crashed process and can restart-loop the pod. Requests are served regardless of health status - health is what probes read, not a gate.

Notes

  • The integration tests cover a hand-rolled service end to end (routing and health under its NAME - tonic routes by NamedService::NAME, so a stand-in for the FunctionRunnerService must keep the real name) and the caller-owned-health sequence: NOT_SERVING at start, RunFunction answered while not serving, SERVING after the flip.
  • With .health_reporter() taken, the SDK sets no initial status by itself (avoiding a race with a caller flipping early); callers set the initial NOT_SERVING - shown in the rustdoc example.

Slated for 0.3.0.

serve_customized(args) starts a ServerBuilder composing the server
from parts, in the spirit of function-sdk-go's options: function()
adds the generated typed server, service() any tonic service (a
custom codec, an instrumented wrapper, services beside the function),
file_descriptor_set() their reflection descriptors, and
health_reporter() hands readiness to the caller (services otherwise
report serving when serving starts). serve delegates to it; the
serve_service function from #1 is removed before any release ships
it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jonasz-lasut

Copy link
Copy Markdown
Collaborator Author

Closing: we are keeping the SDK surface to serve alone. A project needing a customized server builds it from public pieces (tonic, tonic-health, tonic-reflection, proto::FILE_DESCRIPTOR_SET) - function-wasm did exactly that before #1, and a copy stays honest where an abstraction with one caller cannot anticipate the next customization. #1 is being reverted for the same reason.

@jonasz-lasut
jonasz-lasut deleted the feat/serve-customized branch August 25, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant