Skip to content

Commit cd85f49

Browse files
committed
fix: use unstable payload option for protojson codec
1 parent 1df111e commit cd85f49

File tree

18 files changed

+1112
-526
lines changed

18 files changed

+1112
-526
lines changed

encoding/encoding.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,25 @@ type PayloadCodec interface {
122122
Codec
123123
}
124124

125+
// UnstableSerializer is an interface that codecs can implement to indicate
126+
// they may produce non-deterministic output for the same input.
127+
type UnstableSerializer interface {
128+
IsUnstable() bool
129+
}
130+
131+
// IsUnstableSerialization returns true if the codec may produce non-deterministic output.
132+
// This is true for ProtoJSONCodec (protojson does not guarantee deterministic output)
133+
// and any codec implementing UnstableSerializer that returns true from IsUnstable().
134+
func IsUnstableSerialization(codec Codec) bool {
135+
if _, ok := codec.(protoJSONCodec); ok {
136+
return true
137+
}
138+
if unstable, ok := codec.(UnstableSerializer); ok {
139+
return unstable.IsUnstable()
140+
}
141+
return false
142+
}
143+
125144
// InputPayload is provided to Restate upon handler discovery, to teach the ingress how to validate incoming
126145
// request bodies.
127146
type InputPayload struct {
@@ -264,7 +283,10 @@ func (j protoJSONCodec) Unmarshal(data []byte, input any) (err error) {
264283
func (j protoJSONCodec) Marshal(output any) ([]byte, error) {
265284
switch output := output.(type) {
266285
case proto.Message:
267-
return protojson.Marshal(output)
286+
return protojson.MarshalOptions{
287+
Indent: "",
288+
Multiline: false,
289+
}.Marshal(output)
268290
default:
269291
return nil, fmt.Errorf("ProtoJSONCodec.Marshal called with a type that is not a proto.Message")
270292
}

encoding/encoding_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,23 @@ func TestGenerateJsonSchema(t *testing.T) {
9595
})
9696
}
9797
}
98+
99+
func TestIsUnstableSerialization(t *testing.T) {
100+
tests := []struct {
101+
name string
102+
codec Codec
103+
expected bool
104+
}{
105+
{"JSONCodec", JSONCodec, false},
106+
{"ProtoCodec", ProtoCodec, false},
107+
{"ProtoJSONCodec", ProtoJSONCodec, true},
108+
{"BinaryCodec", BinaryCodec, false},
109+
}
110+
111+
for _, tt := range tests {
112+
t.Run(tt.name, func(t *testing.T) {
113+
result := IsUnstableSerialization(tt.codec)
114+
require.Equal(t, tt.expected, result, "IsUnstableSerialization(%s) = %v, want %v", tt.name, result, tt.expected)
115+
})
116+
}
117+
}

0 commit comments

Comments
 (0)