Support sink schema sidecar#8
Conversation
freeznet
left a comment
There was a problem hiding this comment.
Review: Support sink schema sidecar
Thanks for this — the approach is clean and lines up with how Start already derives the working directory (filepath.Dir(os.Executable()) in pf/function.go), so the sidecar lands next to context.sock exactly where the generic runtime looks. Decoupling the public SinkSchema from the private sinkSchemaSidecarPayload wire struct is a good call, and pinning the always-emit-{} properties behavior with a test is nice.
A few change requests / suggestions (details inline):
- Missing Apache license header on both new files — every other file in
pf/(function.go,context.go,log.go) carries the ASF header. This is the main must-fix (license/RAT consistency). noneschema type isn't skipped — only""andbytesare. Pulsar'sSchemaType.NONEis also "no schema", so anonecaller would still get a sidecar written.- No normalization / exported constants for
schemaType— the value is written verbatim, so correctness depends entirely on the caller matching the runtime's expected vocabulary. - Stale sidecar isn't removed on the skip path (low severity if work dirs are always ephemeral).
- Test coverage — add the empty-string skip case and an uppercase
BYTEScase to lock in theEqualFoldboundary.
None of these are happy-path correctness bugs; #1 is the primary blocker.
freeznet
left a comment
There was a problem hiding this comment.
Re-review: commit 70f20aa "Address schema sidecar review feedback"
Thanks for the quick turnaround — all five items from the previous pass are addressed:
- ✅ Apache license header on both files
- ✅
nonetreated as no-schema (viaisNoSchemaType) - ✅ Stale sidecar removed on the skip path, with the correct
!os.IsNotExistguard - ✅ Exported
SchemaType*constants + doc onSinkSchema.SchemaType - ✅ Table-driven tests for empty / bytes / BYTES / none / NONE + stale removal + normalization
Two follow-ups from the new commit (details inline):
-
Casing of the emitted
schemaType(please confirm).normalizeSinkSchemaTypenow lowercases the value that is written to the sidecar, andTestWriteSinkSchemaSidecarToDirNormalizesSchemaTypelocks"JSON"→"json"in. Pulsar's canonicalSchemaTypeenum names are UPPERCASE andSchemaType.valueOf(...)is case-sensitive. If the generic runtime parses the string that way, lowercasing breaks every type — and it's also a regression vs. the first version, which wrote the value verbatim (a caller passing"JSON"used to work). If the runtime is case-insensitive / expects lowercase, all good — I just want it confirmed, since the blast radius is every schema. -
SchemaTypeBool = "bool"looks wrong. Pulsar's boolean type isSchemaType.BOOLEAN→"boolean", independent of the casing question above.
Everything else looks good.
Summary
This adds explicit sink schema sidecar support to the Go launcher SDK. Generic executable functions return raw bytes, so the runtime needs a sidecar schema definition to create schema-aware Pulsar or Kafka producers without asking the user function process to decode and re-encode records.
The new API exposes
pf.SinkSchema,pf.WriteSinkSchemaSidecar, andpf.StartWithSinkSchema.StartWithSinkSchemawritessink.schema.jsonnext to the executable before entering the normalStartloop, matching the generic runtime sidecar lookup path. The sidecar payload uses the shared fields consumed by the runtime:schemaType,name,schemaData, andproperties. Empty orbytesschema types are skipped because those do not require a producer schema.Validation
go test -count=1 ./...go vet ./...go test -count=1 ./...inexamplesgo vet ./...inexamples