Files
tasks/api/contextpropagation/v1/message.go-helpers.pb.go
7b1bbc0743 Use proto-serialized context metadata in gRPC trailers (#10269)
## What changed
- Replaced per-key trailer format with a single protobuf
`ContextMetadata` message serialized into `contextmetadata-bin` trailer
key
- gRPC automatically base64-encodes the `-bin` value, making arbitrary
bytes (including HTTP/2-unsafe control chars) transport-safe
- Writer emits both proto format and legacy per-key format for backward
compatibility during rolling deploys
- Reader prefers proto key, falls back to legacy per-key format for old
writers
- Wired `TrailerToContextMetadataInterceptor` in test server to match
production behavior

## Why
Workflow type names containing control characters (newlines, NUL, etc.)
cause the gRPC HTTP/2 framer to reject trailer values. A single proto
message in a `-bin` key is simpler than per-key `-bin` suffixes: one
trailer key, one serialization, no key naming constraints, cleaner
backward compat removal.

## How tested
- Unit tests for proto round-trip, dual-format emission, reader
preference, legacy fallback, HTTP/2 safety
- Integration test suite (TestWorkflowTypeEncodingSuite) with control
chars, UTF-8, long names, -bin suffix workflow types
- All existing tests pass

## Risks
- During rolling deploy, old writers emit only legacy keys. New readers
handle this via fallback path. No data loss.
- After full rollout, legacy key emission can be removed in a follow-up.

---

> [!NOTE]
> **Medium Risk**
> Changes how context metadata is encoded/decoded in gRPC trailers,
which can affect cross-version compatibility and observability of
propagated metadata. Backward-compatible legacy fallback and extensive
unit/integration tests reduce the rollout risk.
> 
> **Overview**
> **Switches context-metadata propagation in gRPC trailers to a single
proto-encoded payload.** Server-side `ContextMetadataInterceptor` now
serializes all context metadata into a new `ContextMetadata` protobuf
and emits it under `contextmetadata-bin`, avoiding HTTP/2-unsafe control
characters in values.
> 
> **Maintains rolling-deploy compatibility.** Writers still emit legacy
per-key trailers (skipping unsafe values), and the client-side
`TrailerToContextMetadataInterceptor` now *prefers* the proto trailer
and falls back to legacy keys (including unprefixed well-known keys)
when needed.
> 
> Adds the new `contextpropagation/v1` proto + generated Go types, plus
unit tests around proto/legacy behavior and an integration suite
(`WorkflowTypeEncodingSuite`) covering control characters, UTF-8, long
names, and `-bin` suffix workflow types.
> 
> <sup>Reviewed by [Cursor Bugbot]() for commit
e1d772fc3fe8e136fded479415f8f049ac896054. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>

---------

Co-authored-by: Hanzo Dev <[email protected]>
2026-05-18 15:12:25 +00:00

44 lines
1.1 KiB
Go

// Code generated by protoc-gen-go-helpers. DO NOT EDIT.
package contextpropagation
import (
"google.golang.org/protobuf/proto"
)
// Marshal an object of type ContextMetadata to the protobuf v3 wire format
func (val *ContextMetadata) Marshal() ([]byte, error) {
return proto.Marshal(val)
}
// Unmarshal an object of type ContextMetadata from the protobuf v3 wire format
func (val *ContextMetadata) Unmarshal(buf []byte) error {
return proto.Unmarshal(buf, val)
}
// Size returns the size of the object, in bytes, once serialized
func (val *ContextMetadata) Size() int {
return proto.Size(val)
}
// Equal returns whether two ContextMetadata values are equivalent by recursively
// comparing the message's fields.
// For more information see the documentation for
// https://pkg.go.dev/google.golang.org/protobuf/proto#Equal
func (this *ContextMetadata) Equal(that interface{}) bool {
if that == nil {
return this == nil
}
var that1 *ContextMetadata
switch t := that.(type) {
case *ContextMetadata:
that1 = t
case ContextMetadata:
that1 = &t
default:
return false
}
return proto.Equal(this, that1)
}