Skip to content

Support sink schema sidecar#8

Merged
jiangpengcheng merged 3 commits into
mainfrom
supports_sidecar_schema
Jul 8, 2026
Merged

Support sink schema sidecar#8
jiangpengcheng merged 3 commits into
mainfrom
supports_sidecar_schema

Conversation

@jiangpengcheng

Copy link
Copy Markdown
Member

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, and pf.StartWithSinkSchema. StartWithSinkSchema writes sink.schema.json next to the executable before entering the normal Start loop, matching the generic runtime sidecar lookup path. The sidecar payload uses the shared fields consumed by the runtime: schemaType, name, schemaData, and properties. Empty or bytes schema types are skipped because those do not require a producer schema.

Validation

  • go test -count=1 ./...
  • go vet ./...
  • go test -count=1 ./... in examples
  • go vet ./... in examples

@jiangpengcheng jiangpengcheng marked this pull request as ready for review July 7, 2026 09:57
@jiangpengcheng jiangpengcheng requested a review from a team as a code owner July 7, 2026 09:57

@freeznet freeznet left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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):

  1. 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).
  2. none schema type isn't skipped — only "" and bytes are. Pulsar's SchemaType.NONE is also "no schema", so a none caller would still get a sidecar written.
  3. No normalization / exported constants for schemaType — the value is written verbatim, so correctness depends entirely on the caller matching the runtime's expected vocabulary.
  4. Stale sidecar isn't removed on the skip path (low severity if work dirs are always ephemeral).
  5. Test coverage — add the empty-string skip case and an uppercase BYTES case to lock in the EqualFold boundary.

None of these are happy-path correctness bugs; #1 is the primary blocker.

Comment thread pf/schema_sidecar.go
Comment thread pf/schema_sidecar.go Outdated
Comment thread pf/schema_sidecar.go
Comment thread pf/schema_sidecar_test.go Outdated

@freeznet freeznet left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
  • none treated as no-schema (via isNoSchemaType)
  • ✅ Stale sidecar removed on the skip path, with the correct !os.IsNotExist guard
  • ✅ Exported SchemaType* constants + doc on SinkSchema.SchemaType
  • ✅ Table-driven tests for empty / bytes / BYTES / none / NONE + stale removal + normalization

Two follow-ups from the new commit (details inline):

  1. Casing of the emitted schemaType (please confirm). normalizeSinkSchemaType now lowercases the value that is written to the sidecar, and TestWriteSinkSchemaSidecarToDirNormalizesSchemaType locks "JSON""json" in. Pulsar's canonical SchemaType enum names are UPPERCASE and SchemaType.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.

  2. SchemaTypeBool = "bool" looks wrong. Pulsar's boolean type is SchemaType.BOOLEAN"boolean", independent of the casing question above.

Everything else looks good.

Comment thread pf/schema_sidecar.go
Comment thread pf/schema_sidecar.go Outdated
freeznet
freeznet previously approved these changes Jul 7, 2026
@jiangpengcheng jiangpengcheng merged commit 3c0c22b into main Jul 8, 2026
1 check passed
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.

2 participants