Skip to content

Commit 80744b9

Browse files
committed
move toward lazy registration
1 parent f632d4e commit 80744b9

File tree

5 files changed

+6
-87
lines changed

5 files changed

+6
-87
lines changed

dbos/client.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -240,18 +240,6 @@ func Enqueue[P any, R any](c Client, queueName, workflowName string, input P, op
240240
return nil, errors.New("client cannot be nil")
241241
}
242242

243-
// Register the input and outputs for gob encoding
244-
var logger *slog.Logger
245-
if cl, ok := c.(*client); ok {
246-
if ctx, ok := cl.dbosCtx.(*dbosContext); ok {
247-
logger = ctx.logger
248-
}
249-
}
250-
var typedInput P
251-
safeGobRegister(typedInput, logger)
252-
var typedOutput R
253-
safeGobRegister(typedOutput, logger)
254-
255243
// Call the interface method with the same signature
256244
handle, err := c.Enqueue(queueName, workflowName, input, opts...)
257245
if err != nil {

dbos/dbos.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -354,14 +354,6 @@ func NewDBOSContext(ctx context.Context, inputConfig Config) (DBOSContext, error
354354
initExecutor.logger = config.Logger
355355
initExecutor.logger.Info("Initializing DBOS context", "app_name", config.AppName, "dbos_version", getDBOSVersion())
356356

357-
// Register types we serialize with gob
358-
var t time.Time
359-
safeGobRegister(t, initExecutor.logger)
360-
var ws []WorkflowStatus
361-
safeGobRegister(ws, initExecutor.logger)
362-
var si []StepInfo
363-
safeGobRegister(si, initExecutor.logger)
364-
365357
// Initialize global variables from processed config (already handles env vars and defaults)
366358
initExecutor.applicationVersion = config.ApplicationVersion
367359
initExecutor.executorID = config.ExecutorID

dbos/serialization.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ func serialize(data any) (string, error) {
3333
return "", nil
3434
}
3535

36+
// Lazy registration of the type for gob encoding
37+
safeGobRegister(data, nil)
38+
3639
var buf bytes.Buffer
3740
enc := gob.NewEncoder(&buf)
3841
if err := enc.Encode(&data); err != nil {
@@ -66,14 +69,6 @@ func deserialize(data *string) (any, error) {
6669
// These specific conflicts don't affect encoding/decoding correctness, so they're safe to ignore.
6770
// Other panics (like register `any`) are real errors and will propagate.
6871
func safeGobRegister(value any, logger *slog.Logger) {
69-
if isNilValue(value) {
70-
// Don't attempt to register nil values, as gob.Register(nil) panics
71-
if logger != nil {
72-
logger.Debug("Skipping gob registration for nil value", "type", fmt.Sprintf("%T", value))
73-
}
74-
return
75-
}
76-
7772
defer func() {
7873
if r := recover(); r != nil {
7974
if errStr, ok := r.(string); ok {

dbos/serialization_test.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package dbos
22

33
import (
44
"context"
5-
"encoding/gob"
65
"errors"
76
"fmt"
87
"strings"
@@ -304,11 +303,8 @@ func TestWorkflowEncoding(t *testing.T) {
304303
}
305304
})
306305

307-
t.Run("ManualInterfaceRegistration", func(t *testing.T) {
308-
// Manually register the concrete type for interface testing
309-
gob.Register(ConcreteResponse{})
310-
311-
// Test a workflow that returns an interface with manually registered concrete type
306+
t.Run("LazyInterfaceRegistration", func(t *testing.T) {
307+
// Test a workflow that returns an interface with lazily registered concrete type
312308
directHandle, err := RunWorkflow(executor, encodingWorkflowInterface, "test-interface")
313309
require.NoError(t, err)
314310

dbos/workflow.go

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"errors"
66
"fmt"
7-
"log/slog"
87
"math"
98
"reflect"
109
"runtime"
@@ -449,16 +448,6 @@ func RegisterWorkflow[P any, R any](ctx DBOSContext, fn Workflow[P, R], opts ...
449448

450449
fqn := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
451450

452-
// Registry the input/output types for gob encoding
453-
var logger *slog.Logger
454-
if c, ok := ctx.(*dbosContext); ok {
455-
logger = c.logger
456-
}
457-
var p P
458-
var r R
459-
safeGobRegister(p, logger)
460-
safeGobRegister(r, logger)
461-
462451
// Register a type-erased version of the durable workflow for recovery
463452
typedErasedWorkflow := WorkflowFunc(func(ctx DBOSContext, input any) (any, error) {
464453
typedInput, ok := input.(P)
@@ -480,6 +469,7 @@ func RegisterWorkflow[P any, R any](ctx DBOSContext, fn Workflow[P, R], opts ...
480469

481470
// If this is a scheduled workflow, register a cron job
482471
if registrationParams.cronSchedule != "" {
472+
var p P
483473
if reflect.TypeOf(p) != reflect.TypeOf(time.Time{}) {
484474
panic(fmt.Sprintf("scheduled workflow function must accept a time.Time as input, got %T", p))
485475
}
@@ -1055,14 +1045,6 @@ func RunAsStep[R any](ctx DBOSContext, fn Step[R], opts ...StepOption) (R, error
10551045
return *new(R), newStepExecutionError("", "", "step function cannot be nil")
10561046
}
10571047

1058-
// Register the output type for gob encoding
1059-
var logger *slog.Logger
1060-
if c, ok := ctx.(*dbosContext); ok {
1061-
logger = c.logger
1062-
}
1063-
var r R
1064-
safeGobRegister(r, logger)
1065-
10661048
// Append WithStepName option to ensure the step name is set. This will not erase a user-provided step name
10671049
stepName := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
10681050
opts = append(opts, WithStepName(stepName))
@@ -1224,11 +1206,6 @@ func Send[P any](ctx DBOSContext, destinationID string, message P, topic string)
12241206
if ctx == nil {
12251207
return errors.New("ctx cannot be nil")
12261208
}
1227-
var logger *slog.Logger
1228-
if c, ok := ctx.(*dbosContext); ok {
1229-
logger = c.logger
1230-
}
1231-
safeGobRegister(message, logger)
12321209
return ctx.Send(ctx, destinationID, message, topic)
12331210
}
12341211

@@ -1304,11 +1281,6 @@ func SetEvent[P any](ctx DBOSContext, key string, message P) error {
13041281
if ctx == nil {
13051282
return errors.New("ctx cannot be nil")
13061283
}
1307-
var logger *slog.Logger
1308-
if c, ok := ctx.(*dbosContext); ok {
1309-
logger = c.logger
1310-
}
1311-
safeGobRegister(message, logger)
13121284
return ctx.SetEvent(ctx, key, message)
13131285
}
13141286

@@ -1500,14 +1472,6 @@ func RetrieveWorkflow[R any](ctx DBOSContext, workflowID string) (WorkflowHandle
15001472
return nil, errors.New("dbosCtx cannot be nil")
15011473
}
15021474

1503-
// Register the output for gob encoding
1504-
var logger *slog.Logger
1505-
if c, ok := ctx.(*dbosContext); ok {
1506-
logger = c.logger
1507-
}
1508-
var r R
1509-
safeGobRegister(r, logger)
1510-
15111475
// Call the interface method
15121476
handle, err := ctx.RetrieveWorkflow(ctx, workflowID)
15131477
if err != nil {
@@ -1598,14 +1562,6 @@ func ResumeWorkflow[R any](ctx DBOSContext, workflowID string) (WorkflowHandle[R
15981562
return nil, errors.New("ctx cannot be nil")
15991563
}
16001564

1601-
// Register the output for gob encoding
1602-
var logger *slog.Logger
1603-
if c, ok := ctx.(*dbosContext); ok {
1604-
logger = c.logger
1605-
}
1606-
var r R
1607-
safeGobRegister(r, logger)
1608-
16091565
_, err := ctx.ResumeWorkflow(ctx, workflowID)
16101566
if err != nil {
16111567
return nil, err
@@ -1694,14 +1650,6 @@ func ForkWorkflow[R any](ctx DBOSContext, input ForkWorkflowInput) (WorkflowHand
16941650
return nil, errors.New("ctx cannot be nil")
16951651
}
16961652

1697-
// Register the output for gob encoding
1698-
var logger *slog.Logger
1699-
if c, ok := ctx.(*dbosContext); ok {
1700-
logger = c.logger
1701-
}
1702-
var r R
1703-
safeGobRegister(r, logger)
1704-
17051653
handle, err := ctx.ForkWorkflow(ctx, input)
17061654
if err != nil {
17071655
return nil, err

0 commit comments

Comments
 (0)