@@ -3,7 +3,6 @@ package dbos
33import (
44 "context"
55 "crypto/sha256"
6- "encoding/gob"
76 "encoding/hex"
87 "errors"
98 "fmt"
@@ -121,12 +120,13 @@ type DBOSContext interface {
121120 GetStepID () (int , error ) // Get the current step ID (only available within workflows)
122121
123122 // Workflow management
124- RetrieveWorkflow (_ DBOSContext , workflowID string ) (WorkflowHandle [any ], error ) // Get a handle to an existing workflow
125- CancelWorkflow (_ DBOSContext , workflowID string ) error // Cancel a workflow by setting its status to CANCELLED
126- ResumeWorkflow (_ DBOSContext , workflowID string ) (WorkflowHandle [any ], error ) // Resume a cancelled workflow
127- ForkWorkflow (_ DBOSContext , input ForkWorkflowInput ) (WorkflowHandle [any ], error ) // Fork a workflow from a specific step
128- ListWorkflows (_ DBOSContext , opts ... ListWorkflowsOption ) ([]WorkflowStatus , error ) // List workflows based on filtering criteria
129- GetWorkflowSteps (_ DBOSContext , workflowID string ) ([]StepInfo , error ) // Get the execution steps of a workflow
123+ RetrieveWorkflow (_ DBOSContext , workflowID string ) (WorkflowHandle [any ], error ) // Get a handle to an existing workflow
124+ CancelWorkflow (_ DBOSContext , workflowID string ) error // Cancel a workflow by setting its status to CANCELLED
125+ ResumeWorkflow (_ DBOSContext , workflowID string ) (WorkflowHandle [any ], error ) // Resume a cancelled workflow
126+ ForkWorkflow (_ DBOSContext , input ForkWorkflowInput ) (WorkflowHandle [any ], error ) // Fork a workflow from a specific step
127+ ListWorkflows (_ DBOSContext , opts ... ListWorkflowsOption ) ([]WorkflowStatus , error ) // List workflows based on filtering criteria
128+ GetWorkflowSteps (_ DBOSContext , workflowID string ) ([]StepInfo , error ) // Get the execution steps of a workflow
129+ ListRegisteredWorkflows (_ DBOSContext , opts ... ListRegisteredWorkflowsOption ) ([]WorkflowRegistryEntry , error ) // List registered workflows with filtering options
130130
131131 // Accessors
132132 GetApplicationVersion () string // Get the application version for this context
@@ -159,7 +159,7 @@ type dbosContext struct {
159159 workflowsWg * sync.WaitGroup
160160
161161 // Workflow registry - read-mostly sync.Map since registration happens only before launch
162- workflowRegistry * sync.Map // map[string]workflowRegistryEntry
162+ workflowRegistry * sync.Map // map[string]WorkflowRegistryEntry
163163 workflowCustomNametoFQN * sync.Map // Maps fully qualified workflow names to custom names. Usefor when client enqueues a workflow by name because registry is indexed by FQN.
164164
165165 // Workflow scheduler
@@ -194,7 +194,8 @@ func WithValue(ctx DBOSContext, key, val any) DBOSContext {
194194 }
195195 // Will do nothing if the concrete type is not dbosContext
196196 if dbosCtx , ok := ctx .(* dbosContext ); ok {
197- return & dbosContext {
197+ launched := dbosCtx .launched .Load ()
198+ childCtx := & dbosContext {
198199 ctx : context .WithValue (dbosCtx .ctx , key , val ), // Spawn a new child context with the value set
199200 logger : dbosCtx .logger ,
200201 systemDB : dbosCtx .systemDB ,
@@ -205,6 +206,8 @@ func WithValue(ctx DBOSContext, key, val any) DBOSContext {
205206 executorID : dbosCtx .executorID ,
206207 applicationID : dbosCtx .applicationID ,
207208 }
209+ childCtx .launched .Store (launched )
210+ return childCtx
208211 }
209212 return nil
210213}
@@ -217,7 +220,10 @@ func WithoutCancel(ctx DBOSContext) DBOSContext {
217220 return nil
218221 }
219222 if dbosCtx , ok := ctx .(* dbosContext ); ok {
220- return & dbosContext {
223+ launched := dbosCtx .launched .Load ()
224+ // Create a new context that is not canceled when the parent is canceled
225+ // but retains all other values
226+ childCtx := & dbosContext {
221227 ctx : context .WithoutCancel (dbosCtx .ctx ),
222228 logger : dbosCtx .logger ,
223229 systemDB : dbosCtx .systemDB ,
@@ -228,6 +234,8 @@ func WithoutCancel(ctx DBOSContext) DBOSContext {
228234 executorID : dbosCtx .executorID ,
229235 applicationID : dbosCtx .applicationID ,
230236 }
237+ childCtx .launched .Store (launched )
238+ return childCtx
231239 }
232240 return nil
233241}
@@ -240,8 +248,9 @@ func WithTimeout(ctx DBOSContext, timeout time.Duration) (DBOSContext, context.C
240248 return nil , func () {}
241249 }
242250 if dbosCtx , ok := ctx .(* dbosContext ); ok {
251+ launched := dbosCtx .launched .Load ()
243252 newCtx , cancelFunc := context .WithTimeoutCause (dbosCtx .ctx , timeout , errors .New ("DBOS context timeout" ))
244- return & dbosContext {
253+ childCtx := & dbosContext {
245254 ctx : newCtx ,
246255 logger : dbosCtx .logger ,
247256 systemDB : dbosCtx .systemDB ,
@@ -251,7 +260,9 @@ func WithTimeout(ctx DBOSContext, timeout time.Duration) (DBOSContext, context.C
251260 applicationVersion : dbosCtx .applicationVersion ,
252261 executorID : dbosCtx .executorID ,
253262 applicationID : dbosCtx .applicationID ,
254- }, cancelFunc
263+ }
264+ childCtx .launched .Store (launched )
265+ return childCtx , cancelFunc
255266 }
256267 return nil , func () {}
257268}
@@ -275,6 +286,34 @@ func (c *dbosContext) GetApplicationID() string {
275286 return c .applicationID
276287}
277288
289+ // ListRegisteredWorkflows returns information about registered workflows with their registration parameters.
290+ // Supports filtering using functional options.
291+ func (c * dbosContext ) ListRegisteredWorkflows (_ DBOSContext , opts ... ListRegisteredWorkflowsOption ) ([]WorkflowRegistryEntry , error ) {
292+ // Initialize parameters with defaults
293+ params := & listRegisteredWorkflowsOptions {}
294+
295+ // Apply all provided options
296+ for _ , opt := range opts {
297+ opt (params )
298+ }
299+
300+ // Get all registered workflows and apply filters
301+ var filteredWorkflows []WorkflowRegistryEntry
302+ c .workflowRegistry .Range (func (key , value interface {}) bool {
303+ workflow := value .(WorkflowRegistryEntry )
304+
305+ // Filter by scheduled only
306+ if params .scheduledOnly && workflow .CronSchedule == "" {
307+ return true
308+ }
309+
310+ filteredWorkflows = append (filteredWorkflows , workflow )
311+ return true
312+ })
313+
314+ return filteredWorkflows , nil
315+ }
316+
278317// NewDBOSContext creates a new DBOS context with the provided configuration.
279318// The context must be launched with Launch() for workflow execution and should be shut down with Shutdown().
280319// This function initializes the DBOS system database, sets up the queue sub-system, and prepares the workflow registry.
@@ -317,15 +356,14 @@ func NewDBOSContext(ctx context.Context, inputConfig Config) (DBOSContext, error
317356
318357 // Register types we serialize with gob
319358 var t time.Time
320- gob . Register ( t )
359+ safeGobRegister ( t , initExecutor . logger )
321360 var ws []WorkflowStatus
322- gob . Register (ws )
361+ safeGobRegister (ws , initExecutor . logger )
323362 var si []StepInfo
324- gob .Register (si )
325363 var h workflowHandle [any ]
326- gob . Register ( h )
364+ safeGobRegister ( h , initExecutor . logger )
327365 var ph workflowPollingHandle [any ]
328- gob . Register (ph )
366+ safeGobRegister (ph , initExecutor . logger )
329367
330368 // Initialize global variables from processed config (already handles env vars and defaults)
331369 initExecutor .applicationVersion = config .ApplicationVersion
0 commit comments