Skip to content

Commit 04634bb

Browse files
committed
fix merge conflict
1 parent 76163c2 commit 04634bb

File tree

2 files changed

+1
-140
lines changed

2 files changed

+1
-140
lines changed

dbos/serialization.go

Lines changed: 0 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -81,142 +81,3 @@ func getNilOrZeroValue[T any]() T {
8181
// Otherwise return zero value
8282
return result
8383
}
84-
85-
// init registers the gobValue wrapper type with gob for gobSerializer
86-
func init() {
87-
// Register wrapper type - this is required for gob encoding/decoding to work
88-
safeGobRegister(gobValue{})
89-
}
90-
91-
type gobSerializer[T any] struct{}
92-
93-
func newGobSerializer[T any]() serializer[T] {
94-
return &gobSerializer[T]{}
95-
}
96-
97-
func (g *gobSerializer[T]) Encode(data T) (string, error) {
98-
if isNilValue(data) {
99-
// For nil values, encode an empty byte slice directly to base64
100-
return base64.StdEncoding.EncodeToString([]byte{}), nil
101-
}
102-
103-
// Register the type before encoding
104-
safeGobRegister(data)
105-
106-
var buf bytes.Buffer
107-
encoder := gob.NewEncoder(&buf)
108-
wrapper := gobValue{Value: data}
109-
if err := encoder.Encode(wrapper); err != nil {
110-
return "", fmt.Errorf("failed to encode data: %w", err)
111-
}
112-
return base64.StdEncoding.EncodeToString(buf.Bytes()), nil
113-
}
114-
115-
func (g *gobSerializer[T]) Decode(data *string) (T, error) {
116-
zero := *new(T)
117-
118-
if data == nil || *data == "" {
119-
return zero, nil
120-
}
121-
122-
dataBytes, err := base64.StdEncoding.DecodeString(*data)
123-
if err != nil {
124-
return zero, fmt.Errorf("failed to decode base64 data: %w", err)
125-
}
126-
127-
// If decoded data is empty, it represents a nil value
128-
if len(dataBytes) == 0 {
129-
return zero, nil
130-
}
131-
132-
// Resolve the type of T
133-
tType := reflect.TypeOf(zero)
134-
if tType == nil {
135-
// zero is nil, T is likely a pointer type or interface
136-
// Get the type from a pointer to T's zero value
137-
tType = reflect.TypeOf(&zero).Elem()
138-
}
139-
140-
// Register type T before decoding
141-
// This is required on the recovery path, where the process might not have been doing the encode/registering.
142-
// This will panic if T is an non-registered interface type (which is not supported)
143-
if tType != nil && tType.Kind() != reflect.Interface {
144-
safeGobRegister(zero)
145-
}
146-
147-
var wrapper gobValue
148-
decoder := gob.NewDecoder(bytes.NewReader(dataBytes))
149-
if err := decoder.Decode(&wrapper); err != nil {
150-
return zero, fmt.Errorf("failed to decode gob data: %w", err)
151-
}
152-
153-
decoded := wrapper.Value
154-
155-
// Gob stores pointed values directly, so we need to reconstruct the pointer type
156-
if tType != nil && tType.Kind() == reflect.Pointer {
157-
elemType := tType.Elem()
158-
decodedType := reflect.TypeOf(decoded)
159-
160-
// Check if decoded value matches the element type (not the pointer type)
161-
if decodedType != nil && decodedType == elemType {
162-
// Create a new pointer to the decoded value
163-
elemValue := reflect.New(elemType)
164-
elemValue.Elem().Set(reflect.ValueOf(decoded))
165-
return elemValue.Interface().(T), nil
166-
}
167-
// If decoded is already a pointer of the correct type, try direct assertion
168-
if decodedType != nil && decodedType == tType {
169-
typedResult, ok := decoded.(T)
170-
if ok {
171-
return typedResult, nil
172-
}
173-
}
174-
// If decoded is nil and T is a pointer type, return nil pointer
175-
if decoded == nil {
176-
return zero, nil
177-
}
178-
}
179-
180-
// Not a pointer -- direct type assertion
181-
typedResult, ok := decoded.(T)
182-
if !ok {
183-
return zero, fmt.Errorf("cannot convert decoded value of type %T to %T", decoded, zero)
184-
}
185-
return typedResult, nil
186-
}
187-
188-
// isNilValue checks if a value is nil (for pointer types, slice, map, etc.)
189-
func isNilValue(v any) bool {
190-
val := reflect.ValueOf(v)
191-
if !val.IsValid() {
192-
return true
193-
}
194-
switch val.Kind() {
195-
case reflect.Pointer, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func:
196-
return val.IsNil()
197-
}
198-
return false
199-
}
200-
201-
// IsNestedPointer checks if a type is a nested pointer (e.g., **int, ***int).
202-
// It returns false for non-pointer types and single-level pointers (*int).
203-
// It returns true for nested pointers with depth > 1.
204-
func IsNestedPointer(t reflect.Type) bool {
205-
if t == nil {
206-
return false
207-
}
208-
209-
depth := 0
210-
currentType := t
211-
212-
// Count pointer indirection levels, break early if depth > 1
213-
for currentType != nil && currentType.Kind() == reflect.Pointer {
214-
depth++
215-
if depth > 1 {
216-
return true
217-
}
218-
currentType = currentType.Elem()
219-
}
220-
221-
return false
222-
}

dbos/workflow.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ func (h *workflowHandle[R]) processOutcome(outcome workflowOutcome[R]) (R, error
227227
parentWorkflowID: workflowState.workflowID,
228228
childWorkflowID: h.workflowID,
229229
stepID: workflowState.nextStepID(),
230-
output: &encodedOutput,
230+
output: encodedOutput,
231231
err: outcome.err,
232232
}
233233
recordResultErr := retry(h.dbosContext, func() error {

0 commit comments

Comments
 (0)